All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/18] e500v2.inc: add recipe
@ 2017-12-28 10:04 Chunrong Guo
  2017-12-28 10:04 ` [PATCH 02/18] qoriq-ppc.inc: add recipes Chunrong Guo
                   ` (17 more replies)
  0 siblings, 18 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 conf/machine/include/e500v2.inc | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 conf/machine/include/e500v2.inc

diff --git a/conf/machine/include/e500v2.inc b/conf/machine/include/e500v2.inc
new file mode 100644
index 0000000..420f034
--- /dev/null
+++ b/conf/machine/include/e500v2.inc
@@ -0,0 +1,4 @@
+require conf/machine/include/tune-ppce500v2.inc
+
+MACHINEOVERRIDES =. "e500v2:"
+require conf/machine/include/qoriq-ppc.inc
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 02/18] qoriq-ppc.inc: add recipes
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2018-01-12 16:39   ` Otavio Salvador
  2017-12-28 10:04 ` [PATCH 03/18] e5500.inc: " Chunrong Guo
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 conf/machine/include/qoriq-ppc.inc | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 conf/machine/include/qoriq-ppc.inc

diff --git a/conf/machine/include/qoriq-ppc.inc b/conf/machine/include/qoriq-ppc.inc
new file mode 100644
index 0000000..d2e4782
--- /dev/null
+++ b/conf/machine/include/qoriq-ppc.inc
@@ -0,0 +1,15 @@
+# Provides the common settings for QorIQ PPC
+
+KERNEL_IMAGETYPE ?= "uImage"
+
+SERIAL_CONSOLES ?= "115200;ttyS0 115200;ttyS1 115200;ttyEHV0"
+SERIAL_CONSOLES_CHECK ?= "${SERIAL_CONSOLES}"
+
+MACHINEOVERRIDES =. "qoriq-ppc:"
+
+require conf/machine/include/qoriq-base.inc
+
+GCCVERSION_qoriq-ppc = "4.9.2"
+BINUVERSION_qoriq-ppc = "2.25"
+GLIBCVERSION_qoriq-ppc = "2.20"
+PREFERRED_VERSION_virtual/nativesdk-libiconv = "2.20"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 03/18] e5500.inc: add recipes
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
  2017-12-28 10:04 ` [PATCH 02/18] qoriq-ppc.inc: add recipes Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 04/18] e5500-64b.inc: " Chunrong Guo
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>>
---
 conf/machine/include/e5500.inc | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 conf/machine/include/e5500.inc

diff --git a/conf/machine/include/e5500.inc b/conf/machine/include/e5500.inc
new file mode 100644
index 0000000..364ffac
--- /dev/null
+++ b/conf/machine/include/e5500.inc
@@ -0,0 +1,6 @@
+TARGET_FPU = "hard"
+
+require conf/machine/include/tune-ppce5500.inc
+require conf/machine/include/qoriq-ppc.inc
+
+MACHINEOVERRIDES =. "e5500:"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 04/18] e5500-64b.inc: add recipes
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
  2017-12-28 10:04 ` [PATCH 02/18] qoriq-ppc.inc: add recipes Chunrong Guo
  2017-12-28 10:04 ` [PATCH 03/18] e5500.inc: " Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 05/18] mpc8548cds: add machine conf Chunrong Guo
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 conf/machine/include/e5500-64b.inc | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 conf/machine/include/e5500-64b.inc

diff --git a/conf/machine/include/e5500-64b.inc b/conf/machine/include/e5500-64b.inc
new file mode 100644
index 0000000..72b958c
--- /dev/null
+++ b/conf/machine/include/e5500-64b.inc
@@ -0,0 +1,11 @@
+TARGET_FPU = "hard"
+DEFAULTTUNE ?= "ppc64e5500"
+
+require conf/machine/include/tune-ppce5500.inc
+require conf/machine/include/qoriq-ppc.inc
+
+MACHINEOVERRIDES =. "e5500-64b:"
+
+require conf/multilib.conf
+MULTILIBS ?= "multilib:lib32"
+DEFAULTTUNE_virtclass-multilib-lib32 ?= "ppce5500"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 05/18] mpc8548cds: add machine conf
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (2 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 04/18] e5500-64b.inc: " Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 06/18] p2020rdb: " Chunrong Guo
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 conf/machine/mpc8548cds.conf | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 conf/machine/mpc8548cds.conf

diff --git a/conf/machine/mpc8548cds.conf b/conf/machine/mpc8548cds.conf
new file mode 100644
index 0000000..7319440
--- /dev/null
+++ b/conf/machine/mpc8548cds.conf
@@ -0,0 +1,14 @@
+#@TYPE: Machine
+#@Name: NXP MPC8548CDS
+#@DESCRIPTION: Machine configuration for the NXP MPC8548CDS
+#@MAINTAINER: Chunrong Guo <chunrong.guo@nxp.com>
+
+require conf/machine/include/e500v2.inc
+
+UBOOT_CONFIG ??= "nor"
+UBOOT_CONFIG[nor] = "MPC8548CDS_defconfig,,u-boot.bin"
+
+KERNEL_DEVICETREE = "mpc8548cds_32b.dtb"
+KERNEL_DEFCONFIG = "mpc85xx_defconfig"
+
+USE_VT ?= "0"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 06/18] p2020rdb: add machine conf
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (3 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 05/18] mpc8548cds: add machine conf Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 07/18] t1042d4rdb-64b: add machine config Chunrong Guo
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 conf/machine/p2020rdb.conf | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 conf/machine/p2020rdb.conf

diff --git a/conf/machine/p2020rdb.conf b/conf/machine/p2020rdb.conf
new file mode 100644
index 0000000..3fdcde0
--- /dev/null
+++ b/conf/machine/p2020rdb.conf
@@ -0,0 +1,29 @@
+#@TYPE: Machine
+#@Name: NXP P2020RDB
+#@SOC: p2020
+#@DESCRIPTION: Machine configuration for NXP QorIQ P2020 Reference
+#              Design Board with ppce500v2 core
+#@MAINTAINER: Chunrong Guo <chunrong.guo@nxp.com>
+
+require conf/machine/include/e500v2.inc
+
+MACHINEOVERRIDES =. "p2020:"
+BOOTFORMAT_CONFIG = "config_sram_p1022ds.dat"
+
+UBOOT_CONFIG ??= "nor nand sdcard spi 36bit-nor 36bit-spi 36bit-nand 36bit-sdcard"
+UBOOT_CONFIG[nor] = "P2020RDB-PC_config,,u-boot.bin"
+UBOOT_CONFIG[nand] = "P2020RDB-PC_NAND_config,,u-boot.bin"
+UBOOT_CONFIG[sdcard] = "P2020RDB-PC_SDCARD_config,,u-boot.bin"
+UBOOT_CONFIG[spi] = "P2020RDB-PC_SPIFLASH_config,,u-boot.bin"
+UBOOT_CONFIG[36bit-nor] = "P2020RDB-PC_36BIT_config,,u-boot.bin"
+UBOOT_CONFIG[36bit-spi] = "P2020RDB-PC_36BIT_SPIFLASH_config,,u-boot.bin"
+UBOOT_CONFIG[36bit-nand] = "P2020RDB-PC_36BIT_NAND_config,,u-boot.bin"
+UBOOT_CONFIG[36bit-sdcard] = "P2020RDB-PC_36BIT_SDCARD_config,,u-boot.bin"
+
+KERNEL_DEVICETREE ?= "p2020rdb-pc_32b.dtb"
+KERNEL_DEFCONFIG ?= "mpc85xx_smp_defconfig"
+KBUILD_DEFCONFIG ?= "mpc85xx_smp_defconfig"
+
+JFFS2_ERASEBLOCK = "0x20000"
+
+USE_VT ?= "0"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 07/18] t1042d4rdb-64b: add machine config
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (4 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 06/18] p2020rdb: " Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 08/18] t1042d4rdb: " Chunrong Guo
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 conf/machine/t1042d4rdb-64b.conf | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 conf/machine/t1042d4rdb-64b.conf

diff --git a/conf/machine/t1042d4rdb-64b.conf b/conf/machine/t1042d4rdb-64b.conf
new file mode 100644
index 0000000..4bb6f0b
--- /dev/null
+++ b/conf/machine/t1042d4rdb-64b.conf
@@ -0,0 +1,30 @@
+#@TYPE: Machine
+#@NAME: NXP T1042D4RDB
+#@SOC: t1042
+#@DESCRIPTION: Machine configuration for NXP QorIQ T1042D4 Reference
+#              Design Board with ppce5500 core in 64b mode
+#@MAINTAINER: Chunrong Guo <chunrong.guo@nxp.com>
+
+require conf/machine/include/e5500-64b.inc
+
+MACHINEOVERRIDES =. "t1:t1042:"
+
+UBOOT_CONFIG ??= "nand sdcard spi secure-boot nor"
+UBOOT_CONFIG[nor] = "T1042D4RDB_config,,u-boot.bin"
+UBOOT_CONFIG[nand] = "T1042D4RDB_NAND_config,,u-boot-with-spl-pbl.bin"
+UBOOT_CONFIG[sdcard] = "T1042D4RDB_SDCARD_config,,u-boot-with-spl-pbl.bin"
+UBOOT_CONFIG[spi] = "T1042D4RDB_SPIFLASH_config,,u-boot-with-spl-pbl.bin"
+UBOOT_CONFIG[secure-boot] = "T1042D4RDB_SECURE_BOOT_config,,u-boot.bin"
+
+HV_CFG_M = "t1040rdb"
+
+KERNEL_DEVICETREE ?= "t1042d4rdb.dtb"
+KERNEL_DEFCONFIG ?= "corenet64_smp_defconfig"
+
+JFFS2_ERASEBLOCK = "0x10000"
+
+QE_UCODE = "iram_Type_A_T1040_r1.0.bin"
+
+EXTRA_IMAGEDEPENDS += "fm-ucode rcw hypervisor hv-cfg qe-ucode"
+
+USE_VT ?= "0"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 08/18] t1042d4rdb: add machine config
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (5 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 07/18] t1042d4rdb-64b: add machine config Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 12/18] cloog: add recipes Chunrong Guo
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 conf/machine/t1042d4rdb.conf | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 conf/machine/t1042d4rdb.conf

diff --git a/conf/machine/t1042d4rdb.conf b/conf/machine/t1042d4rdb.conf
new file mode 100644
index 0000000..685b7cb
--- /dev/null
+++ b/conf/machine/t1042d4rdb.conf
@@ -0,0 +1,30 @@
+#@TYPE: Machine
+#@NAME: NXP T1042D4RDB
+#@SOC: t1042
+#@DESCRIPTION: Machine configuration for NXP QorIQ T1042D4 Reference
+#              Design Board with ppce5500 core in 32b mode
+#@MAINTAINER: Chunrong Guo <chunrong.guo@nxp.com>
+
+require conf/machine/include/e5500.inc
+
+MACHINEOVERRIDES =. "t1:t1042:"
+
+UBOOT_CONFIG ??= "nand sdcard spi secure-boot nor"
+UBOOT_CONFIG[nor] = "T1042D4RDB_config,,u-boot.bin"
+UBOOT_CONFIG[nand] = "T1042D4RDB_NAND_config,,u-boot-with-spl-pbl.bin"
+UBOOT_CONFIG[sdcard] = "T1042D4RDB_SDCARD_config,,u-boot-with-spl-pbl.bin"
+UBOOT_CONFIG[spi] = "T1042D4RDB_SPIFLASH_config,,u-boot-with-spl-pbl.bin"
+UBOOT_CONFIG[secure-boot] = "T1042D4RDB_SECURE_BOOT_config,,u-boot.bin"
+
+HV_CFG_M = "t1040rdb"
+
+KERNEL_DEVICETREE ?= "t1042d4rdb.dtb"
+KERNEL_DEFCONFIG ?= "corenet32_smp_defconfig"
+
+JFFS2_ERASEBLOCK = "0x10000"
+
+QE_UCODE = "iram_Type_A_T1040_r1.0.bin"
+
+EXTRA_IMAGEDEPENDS += "fm-ucode rcw qe-ucode"
+
+USE_VT ?= "0"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 12/18] cloog: add recipes
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (6 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 08/18] t1042d4rdb: " Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 13/18] isl:add recipes Chunrong Guo
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

*gcc 4.9 depends cloog

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-devtools/cloog/cloog.inc                   |  8 +++
 recipes-devtools/cloog/cloog_0.18.0.bb             | 22 +++++++++
 .../cloog/files/fix-automake1.13+-error.patch      | 57 ++++++++++++++++++++++
 .../files/fix-libcloog-isl-include-directory.patch | 25 ++++++++++
 4 files changed, 112 insertions(+)
 create mode 100644 recipes-devtools/cloog/cloog.inc
 create mode 100644 recipes-devtools/cloog/cloog_0.18.0.bb
 create mode 100644 recipes-devtools/cloog/files/fix-automake1.13+-error.patch
 create mode 100644 recipes-devtools/cloog/files/fix-libcloog-isl-include-directory.patch

diff --git a/recipes-devtools/cloog/cloog.inc b/recipes-devtools/cloog/cloog.inc
new file mode 100644
index 0000000..9062b97
--- /dev/null
+++ b/recipes-devtools/cloog/cloog.inc
@@ -0,0 +1,8 @@
+DESCRIPTION = "CLooG is a free software and library to generate code for scanning Z-polyhedra."
+HOMEPAGE = "http://www.cloog.org/"
+LICENSE = "LGPL-2.1"
+SECTION = "libs"
+
+BBCLASSEXTEND = "native nativesdk"
+
+inherit autotools
diff --git a/recipes-devtools/cloog/cloog_0.18.0.bb b/recipes-devtools/cloog/cloog_0.18.0.bb
new file mode 100644
index 0000000..63c59a6
--- /dev/null
+++ b/recipes-devtools/cloog/cloog_0.18.0.bb
@@ -0,0 +1,22 @@
+require cloog.inc
+
+DEPENDS = "gmp isl"
+
+LIC_FILES_CHKSUM = "file://LICENSE;md5=11398e4927d7ca5001fd4c768e147d83"
+
+SRC_URI = "ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-${PV}.tar.gz \
+           file://fix-automake1.13+-error.patch \
+           file://fix-libcloog-isl-include-directory.patch "
+
+SRC_URI[md5sum] = "be78a47bd82523250eb3e91646db5b3d"
+SRC_URI[sha256sum] = "1c4aa8dde7886be9cbe0f9069c334843b21028f61d344a2d685f88cb1dcf2228"
+
+S = "${WORKDIR}/cloog-${PV}"
+
+EXTRA_OECONF = "--with-bits=gmp --with-gmp-prefix=${STAGING_DIR_HOST}${prefix_native}"
+EXTRA_OECONF_class-native = "--with-bits=gmp --with-gmp-prefix=${STAGING_DIR_NATIVE}${prefix_native}"
+EXTRA_OECONF_class-nativesdk = " --with-bits=gmp --with-gmp-prefix=${STAGING_DIR_HOST}${exec_prefix}"
+
+EXTRA_OECONF += "--with-isl=no"
+EXTRA_OECONF_class-native += "--with-isl=system --with-isl-prefix=${STAGING_DIR_NATIVE}${prefix_native}"
+EXTRA_OECONF_class-nativesdk += "--with-isl=system --with-isl-prefix=${STAGING_DIR_HOST}${exec_prefix}"
diff --git a/recipes-devtools/cloog/files/fix-automake1.13+-error.patch b/recipes-devtools/cloog/files/fix-automake1.13+-error.patch
new file mode 100644
index 0000000..706a352
--- /dev/null
+++ b/recipes-devtools/cloog/files/fix-automake1.13+-error.patch
@@ -0,0 +1,57 @@
+From 61259c7d2f4a81ddc3efc2ce333f7499c632f44b Mon Sep 17 00:00:00 2001
+From: Lnc <hnc@singularity.fr>
+Date: Mon, 19 Aug 2013 15:28:09 +0200
+Subject: [PATCH] Fix error with automake 1.13+
+
+---
+ Makefile.am      |    3 +--
+ test/Makefile.am |   12 ++++++------
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 1749c95..5ac1b75 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -87,8 +87,7 @@ SOURCES_CORE = \
+ 	source/union_domain.c \
+ 	source/version.c
+ 
+-DEFAULT_INCLUDES = -I.
+-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
++AM_CPPFLAGS = -I. -I$(top_builddir)/include -I$(top_srcdir)/include
+ AM_CFLAGS = $(CFLAGS_WARN)
+ libcloog_isl_la_CPPFLAGS = @ISL_CPPFLAGS@ @OSL_CPPFLAGS@
+ libcloog_isl_la_LDFLAGS = -version-info @versioninfo@ \
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 65a8e5a..c97678b 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -43,7 +43,7 @@ else
+ GENERATE_TEST = generate_test
+ endif
+ noinst_PROGRAMS = $(GENERATE_TEST)
+-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
++AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
+ LDADD = ../libcloog-isl.la
+ generate_test_SOURCES = generate_test.c
+ 
+@@ -319,11 +319,11 @@ test_run: generate_test$(EXEEXT)
+ 	$(srcdir)/check_run.sh
+ 
+ check_SCRIPTS = \
+-	$(srcdir)/check_c.sh \
+-	$(srcdir)/check_fortran.sh \
+-	$(srcdir)/check_strided.sh \
+-	$(srcdir)/check_openscop.sh \
+-	$(srcdir)/check_special.sh
++	check_c.sh \
++	check_fortran.sh \
++	check_strided.sh \
++	check_openscop.sh \
++	check_special.sh
+ 
+ TESTS = $(check_SCRIPTS)
+ 
+-- 
+1.7.0.9.GIT
+
diff --git a/recipes-devtools/cloog/files/fix-libcloog-isl-include-directory.patch b/recipes-devtools/cloog/files/fix-libcloog-isl-include-directory.patch
new file mode 100644
index 0000000..b2d6246
--- /dev/null
+++ b/recipes-devtools/cloog/files/fix-libcloog-isl-include-directory.patch
@@ -0,0 +1,25 @@
+From 2b5bef22e2d2891b568ca9ba6b8f0df88609cc7d Mon Sep 17 00:00:00 2001
+From: Cedric Bastoul <cedric.bastoul@unistra.fr>
+Date: Fri, 4 Oct 2013 00:13:56 +0200
+Subject: [PATCH] Fix include directory for libcloog-isl
+
+---
+ Makefile.am |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index fd0f5c3..0425400 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -89,7 +89,7 @@ SOURCES_CORE = \
+ 
+ AM_CPPFLAGS = -I. -I$(top_builddir)/include -I$(top_srcdir)/include
+ AM_CFLAGS = $(CFLAGS_WARN)
+-libcloog_isl_la_CPPFLAGS = @ISL_CPPFLAGS@ @OSL_CPPFLAGS@
++libcloog_isl_la_CPPFLAGS = -I. -I$(top_builddir)/include -I$(top_srcdir)/include @ISL_CPPFLAGS@ @OSL_CPPFLAGS@
+ libcloog_isl_la_LDFLAGS = -version-info @versioninfo@ \
+ 	-rpath $(libdir) @ISL_LDFLAGS@ @OSL_LDFLAGS@
+ libcloog_isl_la_LIBADD = @ISL_LIBS@ @OSL_LIBS@ $(ISL_LA) $(OSL_LA)
+-- 
+1.7.0.9.GIT
+
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 13/18] isl:add recipes
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (7 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 12/18] cloog: add recipes Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 14/18] testfloat: update recipes Chunrong Guo
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

*gcc 4.9 depends isl

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-devtools/isl/isl.inc       |  8 ++++++++
 recipes-devtools/isl/isl_0.11.1.bb | 12 ++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 recipes-devtools/isl/isl.inc
 create mode 100644 recipes-devtools/isl/isl_0.11.1.bb

diff --git a/recipes-devtools/isl/isl.inc b/recipes-devtools/isl/isl.inc
new file mode 100644
index 0000000..6b9d6e4
--- /dev/null
+++ b/recipes-devtools/isl/isl.inc
@@ -0,0 +1,8 @@
+DESCRIPTION = "isl is a library for manipulating sets and relations of integer points bounded by linear constraints."
+HOMEPAGE = "http://freecode.com/projects/isl"
+LICENSE = "MIT"
+SECTION = "libs"
+
+BBCLASSEXTEND = "native nativesdk"
+
+inherit autotools
diff --git a/recipes-devtools/isl/isl_0.11.1.bb b/recipes-devtools/isl/isl_0.11.1.bb
new file mode 100644
index 0000000..71fad92
--- /dev/null
+++ b/recipes-devtools/isl/isl_0.11.1.bb
@@ -0,0 +1,12 @@
+require isl.inc
+
+DEPENDS = "gmp"
+
+LIC_FILES_CHKSUM = "file://LICENSE;md5=0c7c9ea0d2ff040ba4a25afa0089624b"
+
+SRC_URI = "http://isl.gforge.inria.fr/isl-${PV}.tar.gz"
+
+SRC_URI[md5sum] = "d7d27ebedc21a00b292cb7b50f4864f6"
+SRC_URI[sha256sum] = "55f6c36a119d5fbd90ebc1f7ab07144b41c6f7f038acd18ab58c4c11beefdfc8"
+
+S = "${WORKDIR}/isl-${PV}"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 14/18] testfloat: update recipes
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (8 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 13/18] isl:add recipes Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 15/18] sysklogd: update e500v2 patch Chunrong Guo
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

*depends on dos2unix-native

*add  do_prepare_recipe_sysroot task

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-extended/testfloat/testfloat_2a.bb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/recipes-extended/testfloat/testfloat_2a.bb b/recipes-extended/testfloat/testfloat_2a.bb
index 800cef3..b345064 100644
--- a/recipes-extended/testfloat/testfloat_2a.bb
+++ b/recipes-extended/testfloat/testfloat_2a.bb
@@ -3,6 +3,8 @@ LICENSE = "TestFloat"
 
 LIC_FILES_CHKSUM = "file://testfloat/testfloat.txt;beginline=87;endline=95;md5=bdb2e8111838a48015c29bd97f5b6145"
 
+DEPENDS += "dos2unix-native"
+
 SRC_URI = " http://www.jhauser.us/arithmetic/TestFloat-2a.tar.Z;name=TestFloat \
             http://www.jhauser.us/arithmetic/SoftFloat-2b.tar.Z;name=SoftFloat \
           "
@@ -28,7 +30,7 @@ do_unpack2(){
         echo -e "\nERROR: command dos2unix or fromdos not found\n" && return 1
     fi
 }
-addtask do_unpack2 after do_unpack before do_patch
+addtask do_unpack2 after do_prepare_recipe_sysroot do_unpack before do_patch
 
 do_compile(){
     oe_runmake -C testfloat/powerpc-linux-gcc/ CC="${CC}" EXTRA_CFLAGS="-DTEST_KERNEL_EMU"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 15/18] sysklogd: update e500v2 patch
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (9 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 14/18] testfloat: update recipes Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 16/18] diffutils: remove improper patch for qoriq-ppc Chunrong Guo
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-extended/sysklogd/files/no-vectorization.patch | 18 ++++++++++++++++++
 recipes-extended/sysklogd/sysklogd_%.bbappend          |  1 +
 2 files changed, 19 insertions(+)
 create mode 100644 recipes-extended/sysklogd/files/no-vectorization.patch
 create mode 100644 recipes-extended/sysklogd/sysklogd_%.bbappend

diff --git a/recipes-extended/sysklogd/files/no-vectorization.patch b/recipes-extended/sysklogd/files/no-vectorization.patch
new file mode 100644
index 0000000..cf1687e
--- /dev/null
+++ b/recipes-extended/sysklogd/files/no-vectorization.patch
@@ -0,0 +1,18 @@
+Upstream-Status: Inappropriate
+
+The compiler should not be generating vectorized instructions on this target.
+This is a work around until I can determine why this is occuring on this
+particular recipe
+
+Index: sysklogd-1.5/Makefile
+===================================================================
+--- sysklogd-1.5.orig/Makefile
++++ sysklogd-1.5/Makefile
+@@ -20,7 +20,7 @@
+ #SKFLAGS= -g -DSYSV -Wall
+ #LDFLAGS= -g
+-SKFLAGS = $(CFLAGS) $(CPPFLAGS) -DSYSV -Wall -fno-strength-reduce
++SKFLAGS = $(CFLAGS) $(CPPFLAGS) -DSYSV -Wall -fno-strength-reduce -fno-tree-vectorize
+ # -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+ # -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
+ # $(shell getconf LFS_SKFLAGS)
diff --git a/recipes-extended/sysklogd/sysklogd_%.bbappend b/recipes-extended/sysklogd/sysklogd_%.bbappend
new file mode 100644
index 0000000..81fe7b7
--- /dev/null
+++ b/recipes-extended/sysklogd/sysklogd_%.bbappend
@@ -0,0 +1 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 16/18] diffutils: remove improper patch for qoriq-ppc
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (10 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 15/18] sysklogd: update e500v2 patch Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 17/18] hyperrelay: skip ldflags check Chunrong Guo
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-extended/diffutils/diffutils_3.6.bbappend | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 recipes-extended/diffutils/diffutils_3.6.bbappend

diff --git a/recipes-extended/diffutils/diffutils_3.6.bbappend b/recipes-extended/diffutils/diffutils_3.6.bbappend
new file mode 100644
index 0000000..09d8d71
--- /dev/null
+++ b/recipes-extended/diffutils/diffutils_3.6.bbappend
@@ -0,0 +1 @@
+SRC_URI_remove_qoriq-ppc = "file://0001-explicitly-disable-replacing-getopt.patch"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 17/18] hyperrelay: skip ldflags check
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (11 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 16/18] diffutils: remove improper patch for qoriq-ppc Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:04 ` [PATCH 18/18] qe-ucode: support t1042 Chunrong Guo
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-extended/hyperrelay/hyperrelay_git.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/recipes-extended/hyperrelay/hyperrelay_git.bb b/recipes-extended/hyperrelay/hyperrelay_git.bb
index affc941..a818873 100644
--- a/recipes-extended/hyperrelay/hyperrelay_git.bb
+++ b/recipes-extended/hyperrelay/hyperrelay_git.bb
@@ -31,4 +31,4 @@ do_install() {
 
 COMPATIBLE_MACHINE = "(qoriq-ppc)"
 PACKAGE_ARCH = "${MACHINE_SOCARCH}"
-
+INSANE_SKIP_${PN} = "ldflags"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 18/18] qe-ucode: support t1042
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (12 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 17/18] hyperrelay: skip ldflags check Chunrong Guo
@ 2017-12-28 10:04 ` Chunrong Guo
  2017-12-28 10:05 ` [PATCH 10/18] binutils: add 2.25 version Chunrong Guo
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:04 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-bsp/qe-ucode/qe-ucode_git.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/recipes-bsp/qe-ucode/qe-ucode_git.bb b/recipes-bsp/qe-ucode/qe-ucode_git.bb
index 27166d0..1ab7238 100644
--- a/recipes-bsp/qe-ucode/qe-ucode_git.bb
+++ b/recipes-bsp/qe-ucode/qe-ucode_git.bb
@@ -33,6 +33,6 @@ addtask deploy before do_build after do_install
 PACKAGES += "${PN}-image"
 FILES_${PN}-image += "/boot/*"
 
-COMPATIBLE_MACHINE = "(ls1021a|ls1043a)"
+COMPATIBLE_MACHINE = "(ls1021a|ls1043a|t1042)"
 PACKAGE_ARCH = "${MACHINE_SOCARCH}"
 
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 10/18] binutils: add 2.25 version
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (13 preceding siblings ...)
  2017-12-28 10:04 ` [PATCH 18/18] qe-ucode: support t1042 Chunrong Guo
@ 2017-12-28 10:05 ` Chunrong Guo
  2018-01-12 16:32   ` Otavio Salvador
  2017-12-28 10:05 ` [PATCH 11/18] gcc : add 4.9 version Chunrong Guo
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:05 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

*ppc machine only  support binutils 2.25 version

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-devtools/binutils/binutils-2.25.inc        |    34 +
 .../binutils/binutils-cross-canadian.inc           |    29 +
 .../binutils/binutils-cross-canadian_2.25.bb       |     3 +
 recipes-devtools/binutils/binutils-cross.inc       |    30 +
 recipes-devtools/binutils/binutils-cross_2.25.bb   |     3 +
 .../binutils/binutils-crosssdk_2.25.bb             |    13 +
 .../binutils/binutils-fsl/bin.aeabi.patch          |    47 +
 .../binutils-fsl/bin.fix_e5500_e6500_dcbt.patch    |   120 +
 recipes-devtools/binutils/binutils.inc             |   153 +
 ...ild-breakage-from-bfd_set_section_vma-cha.patch |    31 +
 .../binutils/binutils/binutils-armv5e.patch        |    25 +
 .../binutils/binutils/binutils-poison.patch        |   259 +
 .../binutils/binutils-uclibc-100-uclibc-conf.patch |    40 +
 ...binutils-uclibc-300-001_ld_makefile_patch.patch |    55 +
 ...binutils-uclibc-300-006_better_file_error.patch |    45 +
 ...ils-uclibc-300-012_check_ldrunpath_length.patch |    49 +
 .../binutils/binutils-uclibc-gas-needs-libm.patch  |    38 +
 .../binutils/binutils-uninitialised-warning.patch  |    50 +
 .../binutils/binutils/binutils-xlp-support.patch   |   402 +
 .../binutils/binutils/libiberty_path_fix.patch     |    22 +
 .../binutils/binutils/libtool-2.4-update.patch     | 19322 +++++++++++++++++++
 .../binutils/binutils/libtool-rpath-fix.patch      |    39 +
 .../binutils/mips64-default-ld-emulation.patch     |    48 +
 .../binutils/binutils/relocatable_sdk.patch        |    49 +
 recipes-devtools/binutils/binutils_2.25.bb         |    45 +
 25 files changed, 20951 insertions(+)
 create mode 100644 recipes-devtools/binutils/binutils-2.25.inc
 create mode 100644 recipes-devtools/binutils/binutils-cross-canadian.inc
 create mode 100644 recipes-devtools/binutils/binutils-cross-canadian_2.25.bb
 create mode 100644 recipes-devtools/binutils/binutils-cross.inc
 create mode 100644 recipes-devtools/binutils/binutils-cross_2.25.bb
 create mode 100644 recipes-devtools/binutils/binutils-crosssdk_2.25.bb
 create mode 100755 recipes-devtools/binutils/binutils-fsl/bin.aeabi.patch
 create mode 100755 recipes-devtools/binutils/binutils-fsl/bin.fix_e5500_e6500_dcbt.patch
 create mode 100644 recipes-devtools/binutils/binutils.inc
 create mode 100644 recipes-devtools/binutils/binutils/0001-Fix-MMIX-build-breakage-from-bfd_set_section_vma-cha.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-armv5e.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-poison.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-uclibc-100-uclibc-conf.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-uclibc-300-001_ld_makefile_patch.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-uclibc-300-006_better_file_error.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-uclibc-300-012_check_ldrunpath_length.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-uclibc-gas-needs-libm.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-uninitialised-warning.patch
 create mode 100644 recipes-devtools/binutils/binutils/binutils-xlp-support.patch
 create mode 100644 recipes-devtools/binutils/binutils/libiberty_path_fix.patch
 create mode 100644 recipes-devtools/binutils/binutils/libtool-2.4-update.patch
 create mode 100644 recipes-devtools/binutils/binutils/libtool-rpath-fix.patch
 create mode 100644 recipes-devtools/binutils/binutils/mips64-default-ld-emulation.patch
 create mode 100644 recipes-devtools/binutils/binutils/relocatable_sdk.patch
 create mode 100644 recipes-devtools/binutils/binutils_2.25.bb

diff --git a/recipes-devtools/binutils/binutils-2.25.inc b/recipes-devtools/binutils/binutils-2.25.inc
new file mode 100644
index 0000000..52c604c
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-2.25.inc
@@ -0,0 +1,34 @@
+LIC_FILES_CHKSUM="\
+    file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552\
+    file://COPYING.LIB;md5=9f604d8a4f8e74f4f5140845a21b6674\
+    file://COPYING3;md5=d32239bcb673463ab874e80d47fae504\
+    file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6\
+    file://gas/COPYING;md5=d32239bcb673463ab874e80d47fae504\
+    file://include/COPYING;md5=59530bdf33659b29e73d4adb9f9f6552\
+    file://include/COPYING3;md5=d32239bcb673463ab874e80d47fae504\
+    file://libiberty/COPYING.LIB;md5=a916467b91076e631dd8edb7424769c7\
+    file://bfd/COPYING;md5=d32239bcb673463ab874e80d47fae504\
+    "
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/binutils-fsl:"
+
+SRC_URI = "\
+     ${GNU_MIRROR}/binutils/binutils-${PV}.tar.bz2 \
+     file://binutils-uclibc-100-uclibc-conf.patch \
+     file://binutils-uclibc-300-001_ld_makefile_patch.patch \
+     file://binutils-uclibc-300-006_better_file_error.patch \
+     file://binutils-uclibc-300-012_check_ldrunpath_length.patch \
+     file://binutils-uclibc-gas-needs-libm.patch \
+     file://libtool-2.4-update.patch \
+     file://libiberty_path_fix.patch \
+     file://binutils-poison.patch \
+     file://libtool-rpath-fix.patch \
+     file://binutils-armv5e.patch \
+     file://mips64-default-ld-emulation.patch \
+     file://binutils-xlp-support.patch \
+     file://bin.aeabi.patch \
+     file://bin.fix_e5500_e6500_dcbt.patch \
+     "
+SRC_URI[md5sum] = "d9f3303f802a5b6b0bb73a335ab89d66"
+SRC_URI[sha256sum] = "22defc65cfa3ef2a3395faaea75d6331c6e62ea5dfacfed3e2ec17b08c882923"
+
diff --git a/recipes-devtools/binutils/binutils-cross-canadian.inc b/recipes-devtools/binutils/binutils-cross-canadian.inc
new file mode 100644
index 0000000..ae14642
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-cross-canadian.inc
@@ -0,0 +1,29 @@
+inherit cross-canadian
+
+SUMMARY = "GNU binary utilities (cross-canadian for ${TARGET_ARCH} target)"
+PN = "binutils-cross-canadian-${TRANSLATED_TARGET_ARCH}"
+BPN = "binutils"
+
+DEPENDS = "flex-native bison-native virtual/${HOST_PREFIX}gcc-crosssdk virtual/nativesdk-libc nativesdk-zlib nativesdk-gettext nativesdk-flex"
+EXTRA_OECONF += "--with-sysroot=${SDKPATH}/sysroots/${TUNE_PKGARCH}${TARGET_VENDOR}-${TARGET_OS} \
+                "
+
+# We have to point binutils at a sysroot but we don't need to rebuild if this changes
+# e.g. we switch between different machines with different tunes.
+EXTRA_OECONF[vardepsexclude] = "TUNE_PKGARCH"
+
+do_install () {
+	autotools_do_install
+
+	# We're not interested in the libs or headers, these would come from the 
+	# nativesdk or target version of the binutils recipe
+	rm -rf ${D}${prefix}/${TARGET_SYS}
+	rm -f ${D}${libdir}/libbfd*
+	rm -f ${D}${libdir}/libiberty*
+	rm -f ${D}${libdir}/libopcodes*
+	rm -f ${D}${includedir}/*.h
+	
+	cross_canadian_bindirlinks
+}
+
+BBCLASSEXTEND = ""
diff --git a/recipes-devtools/binutils/binutils-cross-canadian_2.25.bb b/recipes-devtools/binutils/binutils-cross-canadian_2.25.bb
new file mode 100644
index 0000000..5dbaa03
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-cross-canadian_2.25.bb
@@ -0,0 +1,3 @@
+require binutils.inc
+require binutils-${PV}.inc
+require binutils-cross-canadian.inc
diff --git a/recipes-devtools/binutils/binutils-cross.inc b/recipes-devtools/binutils/binutils-cross.inc
new file mode 100644
index 0000000..fd3d801
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-cross.inc
@@ -0,0 +1,30 @@
+inherit cross
+PROVIDES = "virtual/${TARGET_PREFIX}binutils"
+
+PN = "binutils-cross-${TARGET_ARCH}"
+BPN = "binutils"
+
+INHIBIT_DEFAULT_DEPS = "1"
+INHIBIT_AUTOTOOLS_DEPS = "1"
+
+EXTRA_OECONF += "--with-sysroot=${STAGING_DIR_TARGET} \
+                --disable-install-libbfd \
+                --enable-poison-system-directories \
+                "
+do_install () {
+	oe_runmake 'DESTDIR=${D}' install
+
+	# We don't really need these, so we'll remove them...
+	rm -rf ${D}${STAGING_DIR_NATIVE}${libdir_native}/libiberty.a
+	rm -rf ${D}${STAGING_DIR_NATIVE}${prefix_native}/${TARGET_SYS}
+	rm -rf ${D}${STAGING_DIR_NATIVE}${prefix_native}/lib/ldscripts
+	rm -rf ${D}${STAGING_DIR_NATIVE}${prefix_native}/share/info
+	rm -rf ${D}${STAGING_DIR_NATIVE}${prefix_native}/share/locale
+	rm -rf ${D}${STAGING_DIR_NATIVE}${prefix_native}/share/man
+	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/share || :
+	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${libdir}/gcc-lib || :
+	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${libdir}64/gcc-lib || :
+	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${libdir} || :
+	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${libdir}64 || :
+	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${prefix} || :
+}
diff --git a/recipes-devtools/binutils/binutils-cross_2.25.bb b/recipes-devtools/binutils/binutils-cross_2.25.bb
new file mode 100644
index 0000000..fbd1f7d
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-cross_2.25.bb
@@ -0,0 +1,3 @@
+require binutils.inc
+require binutils-${PV}.inc
+require binutils-cross.inc
diff --git a/recipes-devtools/binutils/binutils-crosssdk_2.25.bb b/recipes-devtools/binutils/binutils-crosssdk_2.25.bb
new file mode 100644
index 0000000..e88d8fa
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-crosssdk_2.25.bb
@@ -0,0 +1,13 @@
+require binutils-cross_${PV}.bb
+
+inherit crosssdk
+
+PN = "binutils-crosssdk-${SDK_SYS}"
+
+PROVIDES = "virtual/${TARGET_PREFIX}binutils-crosssdk"
+
+SRC_URI += "file://relocatable_sdk.patch"
+
+do_configure_prepend () {
+	sed -i 's#/usr/local/lib /lib /usr/lib#${SDKPATHNATIVE}/lib ${SDKPATHNATIVE}/usr/lib /usr/local/lib /lib /usr/lib#' ${S}/ld/configure.tgt
+}
diff --git a/recipes-devtools/binutils/binutils-fsl/bin.aeabi.patch b/recipes-devtools/binutils/binutils-fsl/bin.aeabi.patch
new file mode 100755
index 0000000..b68b930
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-fsl/bin.aeabi.patch
@@ -0,0 +1,47 @@
+diff -Naur binutils-2.25/bfd/config.bfd binutils-2.25_new/bfd/config.bfd
+--- binutils-2.25/bfd/config.bfd	2014-10-14 02:32:02.000000000 -0500
++++ binutils-2.25_new/bfd/config.bfd	2015-02-10 05:03:54.372951932 -0600
+@@ -1262,7 +1262,7 @@
+     targ_selvecs="rs6000_xcoff_vec powerpc_elf32_vec powerpc_elf32_le_vec powerpc_boot_vec"
+     targ64_selvecs="powerpc_elf64_vec powerpc_elf64_le_vec powerpc_elf64_fbsd_vec"
+     ;;
+-  powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \
++  powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | powerpc-*-aeabi* | \
+   powerpc-*-solaris2* | powerpc-*-linux-* | powerpc-*-rtems* | \
+   powerpc-*-chorus*)
+     targ_defvec=powerpc_elf32_vec
+diff -Naur binutils-2.25/config.sub binutils-2.25_new/config.sub
+--- binutils-2.25/config.sub	2014-10-14 02:32:02.000000000 -0500
++++ binutils-2.25_new/config.sub	2015-02-10 05:06:05.878951927 -0600
+@@ -1372,7 +1372,7 @@
+ 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
++	      | -udi* | -eabi* | -aeabi* | -lites* | -ieee* | -go32* | -aux* \
+ 	      | -chorusos* | -chorusrdb* | -cegcc* \
+ 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ 	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+diff -Naur binutils-2.25/gas/configure.tgt binutils-2.25_new/gas/configure.tgt
+--- binutils-2.25/gas/configure.tgt	2014-10-14 02:32:03.000000000 -0500
++++ binutils-2.25_new/gas/configure.tgt	2015-02-10 05:08:37.073952182 -0600
+@@ -376,6 +376,7 @@
+   ppc-*-beos*)				fmt=coff ;;
+   ppc-*-*n*bsd* | ppc-*-elf*)		fmt=elf ;;
+   ppc-*-eabi* | ppc-*-sysv4*)		fmt=elf ;;
++  ppc-*-aeabi*)				fmt=elf ;;
+   ppc-*-linux-*)			fmt=elf em=linux ;;
+   ppc-*-solaris*)			fmt=elf em=solaris ;;
+   ppc-*-rtems*)				fmt=elf ;;
+diff -Naur binutils-2.25/ld/configure.tgt binutils-2.25_new/ld/configure.tgt
+--- binutils-2.25/ld/configure.tgt	2014-10-14 02:32:04.000000000 -0500
++++ binutils-2.25_new/ld/configure.tgt	2015-02-10 05:25:14.293951859 -0600
+@@ -556,7 +556,7 @@
+ powerpc-*-vxworks*)
+ 			targ_emul=elf32ppcvxworks
+ 			targ_extra_emuls="elf32ppc elf32ppclinux elf32ppcsim" ;;
+-powerpc*-*-elf* | powerpc*-*-eabi* | powerpc*-*-sysv* \
++powerpc*-*-elf* | powerpc*-*-eabi* | powerpc*-*-aeabi* | powerpc*-*-sysv* \
+   | powerpc*-*-linux* | powerpc*-*-netbsd* | powerpc*-*-openbsd* \
+   | powerpc*-*-solaris* | powerpc*-*-kaos* | powerpc*-*-vxworks*)
+ 			case "${targ}" in
diff --git a/recipes-devtools/binutils/binutils-fsl/bin.fix_e5500_e6500_dcbt.patch b/recipes-devtools/binutils/binutils-fsl/bin.fix_e5500_e6500_dcbt.patch
new file mode 100755
index 0000000..0c4f2ae
--- /dev/null
+++ b/recipes-devtools/binutils/binutils-fsl/bin.fix_e5500_e6500_dcbt.patch
@@ -0,0 +1,120 @@
+diff -Naur binutils-2.25/gas/testsuite/gas/ppc/e5500_dcbt.d binutils-2.25_new/gas/testsuite/gas/ppc/e5500_dcbt.d
+--- binutils-2.25/gas/testsuite/gas/ppc/e5500_dcbt.d	1969-12-31 18:00:00.000000000 -0600
++++ binutils-2.25_new/gas/testsuite/gas/ppc/e5500_dcbt.d	2015-02-10 22:39:48.675952006 -0600
+@@ -0,0 +1,11 @@
++#as: -mppc -me5500
++#objdump: -dr -Me5500
++#name: Power E5500 dcbt tests
++
++.*: +file format elf(32)?(64)?-powerpc.*
++
++Disassembly of section \.text:
++
++0+00 <start>:
++   0:	7c 00 2a 2c 	dcbt    0,r5
++   4:	7c 00 29 ec 	dcbtst  0,r5
+diff -Naur binutils-2.25/gas/testsuite/gas/ppc/e5500_dcbt.s binutils-2.25_new/gas/testsuite/gas/ppc/e5500_dcbt.s
+--- binutils-2.25/gas/testsuite/gas/ppc/e5500_dcbt.s	1969-12-31 18:00:00.000000000 -0600
++++ binutils-2.25_new/gas/testsuite/gas/ppc/e5500_dcbt.s	2015-02-10 22:39:48.675952006 -0600
+@@ -0,0 +1,5 @@
++# Power E5500 dcbt tests
++	.section ".text"
++start:
++	dcbt	0, 0, 5
++	dcbtst	0, 0, 5
+diff -Naur binutils-2.25/gas/testsuite/gas/ppc/e6500_dcbt.d binutils-2.25_new/gas/testsuite/gas/ppc/e6500_dcbt.d
+--- binutils-2.25/gas/testsuite/gas/ppc/e6500_dcbt.d	1969-12-31 18:00:00.000000000 -0600
++++ binutils-2.25_new/gas/testsuite/gas/ppc/e6500_dcbt.d	2015-02-10 22:39:48.676952006 -0600
+@@ -0,0 +1,11 @@
++#as: -mppc -me6500
++#objdump: -dr -Me6500
++#name: Power E6500 dcbt tests
++
++.*: +file format elf(32)?(64)?-powerpc.*
++
++Disassembly of section \.text:
++
++0+00 <start>:
++   0:	7c 00 2a 2c 	dcbt    0,r5
++   4:	7c 00 29 ec 	dcbtst  0,r5
+diff -Naur binutils-2.25/gas/testsuite/gas/ppc/e6500_dcbt.s binutils-2.25_new/gas/testsuite/gas/ppc/e6500_dcbt.s
+--- binutils-2.25/gas/testsuite/gas/ppc/e6500_dcbt.s	1969-12-31 18:00:00.000000000 -0600
++++ binutils-2.25_new/gas/testsuite/gas/ppc/e6500_dcbt.s	2015-02-10 22:39:48.676952006 -0600
+@@ -0,0 +1,6 @@
++# Power E6500 dcbt tests
++        .section ".text"
++start:
++        dcbt    0, 0, 5
++        dcbtst  0, 0, 5
++
+diff -Naur binutils-2.25/gas/testsuite/gas/ppc/ppc.exp binutils-2.25_new/gas/testsuite/gas/ppc/ppc.exp
+--- binutils-2.25/gas/testsuite/gas/ppc/ppc.exp	2014-10-14 02:32:03.000000000 -0500
++++ binutils-2.25_new/gas/testsuite/gas/ppc/ppc.exp	2015-02-10 22:57:03.477952006 -0600
+@@ -78,7 +78,9 @@
+ 	run_dump_test "e6500"
+ 	run_dump_test "e500mc64_nop"
+ 	run_dump_test "e5500_nop"
++	run_dump_test "e5500_dcbt"
+ 	run_dump_test "e6500_nop"
++	run_dump_test "e6500_dcbt"
+ 	run_dump_test "cell"
+ 	run_dump_test "power4_32"
+ 	run_dump_test "power6"
+diff -Naur binutils-2.25/include/opcode/ppc.h binutils-2.25_new/include/opcode/ppc.h
+--- binutils-2.25/include/opcode/ppc.h	2014-10-14 02:32:04.000000000 -0500
++++ binutils-2.25_new/include/opcode/ppc.h	2015-02-10 22:59:11.476952006 -0600
+@@ -190,6 +190,9 @@
+ /* Opcode is only supported by Power8 architecture.  */
+ #define PPC_OPCODE_POWER8     0x2000000000ull
+ 
++/* Opcode is supported by Power E5500 */
++#define PPC_OPCODE_E5500      0x4000000000ull
++
+ /* Opcode which is supported by the Hardware Transactional Memory extension.  */
+ /* Currently, this is the same as the POWER8 mask.  If another cpu comes out
+    that isn't a superset of POWER8, we can define this to its own mask.  */
+diff -Naur binutils-2.25/opcodes/ppc-dis.c binutils-2.25_new/opcodes/ppc-dis.c
+--- binutils-2.25/opcodes/ppc-dis.c	2014-10-14 02:32:04.000000000 -0500
++++ binutils-2.25_new/opcodes/ppc-dis.c	2015-02-10 23:04:45.005952006 -0600
+@@ -117,8 +117,8 @@
+     0 },
+   { "e5500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+ 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+-		| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+-		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
++		| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_E5500
++		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+ 		| PPC_OPCODE_POWER7),
+     0 },
+   { "e6500",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+diff -Naur binutils-2.25/opcodes/ppc-opc.c binutils-2.25_new/opcodes/ppc-opc.c
+--- binutils-2.25/opcodes/ppc-opc.c	2014-12-23 02:47:10.000000000 -0600
++++ binutils-2.25_new/opcodes/ppc-opc.c	2015-02-10 23:45:51.734952006 -0600
+@@ -2755,6 +2755,7 @@
+ #define E500	PPC_OPCODE_E500
+ #define E6500	PPC_OPCODE_E6500
+ #define PPCVLE  PPC_OPCODE_VLE
++#define E5500  PPC_OPCODE_E5500
+ #define PPCHTM  PPC_OPCODE_HTM
+ \f
+ /* The opcode table.
+@@ -4711,7 +4712,8 @@
+ {"mtvsrwz",	X(31,243),	XX1RB_MASK,   PPCVSX2,	PPCNONE,	{XT6, RA}},
+ 
+ {"dcbtstt",	XRT(31,246,0x10), XRT_MASK,  POWER7,	PPCNONE,	{RA0, RB}},
+-{"dcbtst",	X(31,246),	X_MASK,      POWER4,	PPCNONE,	{RA0, RB, CT}},
++{"dcbtst",	X(31,246),	X_MASK,      POWER4,	E5500|E6500,	{RA0, RB, CT}},
++{"dcbtst",	X(31,246),	X_MASK,      E5500|E6500, PPCNONE,	{CT, RA0, RB}},
+ {"dcbtst",	X(31,246),	X_MASK,      PPC|PPCVLE, POWER4,	{CT, RA0, RB}},
+  
+ {"stbux",	X(31,247),	X_MASK,	     COM|PPCVLE, PPCNONE,	{RS, RAS, RB}},
+@@ -4753,7 +4755,8 @@
+ {"lscbx.",	XRC(31,277,1),	X_MASK,      M601,	PPCNONE,	{RT, RA, RB}},
+ 
+ {"dcbtt",	XRT(31,278,0x10), XRT_MASK,  POWER7,	PPCNONE,	{RA0, RB}},
+-{"dcbt",	X(31,278),	X_MASK,      POWER4,	PPCNONE,	{RA0, RB, CT}},
++{"dcbt",	X(31,278),	X_MASK,      POWER4,	E5500|E6500,	{RA0, RB, CT}},
++{"dcbt",	X(31,278),	X_MASK,      E5500|E6500, PPCNONE,	{CT, RA0, RB}},
+ {"dcbt",	X(31,278),	X_MASK,      PPC|PPCVLE, POWER4,	{CT, RA0, RB}},
+  
+ {"lhzx",	X(31,279),	X_MASK,      COM|PPCVLE, PPCNONE,	{RT, RA0, RB}},
diff --git a/recipes-devtools/binutils/binutils.inc b/recipes-devtools/binutils/binutils.inc
new file mode 100644
index 0000000..afb582a
--- /dev/null
+++ b/recipes-devtools/binutils/binutils.inc
@@ -0,0 +1,153 @@
+SUMMARY = "GNU binary utilities"
+DESCRIPTION = "The GNU Binutils are a collection of binary tools. \
+The main ones are ld (GNU Linker), and as (GNU Assembler). This \
+package also includes addition tools such as addr2line (Converts \
+addresses into filenames and line numbers), ar (utility for creating, \
+modifying and extracting archives), nm (list symbols in object \
+files), objcopy (copy and translate object files), objdump (Display \
+object information), and other tools and related libraries."
+HOMEPAGE = "http://www.gnu.org/software/binutils/"
+BUGTRACKER = "http://sourceware.org/bugzilla/"
+SECTION = "devel"
+LICENSE = "GPLv3"
+
+DEPENDS = "flex-native bison-native zlib-native gnu-config-native autoconf-native"
+
+inherit autotools gettext multilib_header texinfo
+
+FILES_${PN} = " \
+	${bindir}/${TARGET_PREFIX}* \
+	${libdir}/lib*-*.so \
+	${prefix}/${TARGET_SYS}/bin/* \
+        ${bindir}/embedspu"
+
+RPROVIDES_${PN} += "${PN}-symlinks"
+
+FILES_${PN}-dev = " \
+	${includedir} \
+	${libdir}/*.la \
+	${libdir}/libbfd.so \
+	${libdir}/libopcodes.so"
+
+# Rather than duplicating multiple entries for these, make one
+# list and reuse it.
+
+USE_ALTERNATIVES_FOR = " \
+	addr2line \
+	ar \
+	as \
+	c++filt \
+	elfedit \
+	gprof \
+	ld \
+	ld.bfd \
+	${@bb.utils.contains('DISTRO_FEATURES', 'ld-is-gold', 'ld.gold dwp', '', d)} \
+	nm \
+	objcopy \
+	objdump \
+	ranlib \
+	readelf \
+	size \
+	strings \
+	strip \
+"
+
+python do_package_prepend() {
+    make_alts = d.getVar("USE_ALTERNATIVES_FOR", True) or ""
+    prefix = d.getVar("TARGET_PREFIX", True)
+    bindir = d.getVar("bindir", True)
+    for alt in make_alts.split():
+        d.setVarFlag('ALTERNATIVE_TARGET', alt, bindir + "/" + prefix + alt)
+        d.setVarFlag('ALTERNATIVE_LINK_NAME', alt, bindir + "/" + alt)
+}
+
+# FILES_${PN}-dbg = "${prefix}/${TARGET_SYS}/bin/.debug ${prefix}/${libdir}/.debug"
+
+B = "${S}/build.${HOST_SYS}.${TARGET_SYS}"
+
+EXTRA_OECONF = "--program-prefix=${TARGET_PREFIX} \
+                --disable-werror \
+                --enable-plugins \
+                ${LDGOLD} \
+                ${@bb.utils.contains('DISTRO_FEATURES', 'multiarch', '--enable-64-bit-bfd', '', d)}"
+
+LDGOLD_class-native = ""
+LDGOLD_class-crosssdk = ""
+LDGOLD ?= "${@bb.utils.contains('DISTRO_FEATURES', 'ld-is-gold', '--enable-gold=default --enable-threads', '', d)}"
+
+# This is necessary due to a bug in the binutils Makefiles
+# EXTRA_OEMAKE = "configure-build-libiberty all"
+
+export AR = "${HOST_PREFIX}ar"
+export AS = "${HOST_PREFIX}as"
+export LD = "${HOST_PREFIX}ld"
+export NM = "${HOST_PREFIX}nm"
+export RANLIB = "${HOST_PREFIX}ranlib"
+export OBJCOPY = "${HOST_PREFIX}objcopy"
+export OBJDUMP = "${HOST_PREFIX}objdump"
+
+export AR_FOR_TARGET = "${TARGET_PREFIX}ar"
+export AS_FOR_TARGET = "${TARGET_PREFIX}as"
+export LD_FOR_TARGET = "${TARGET_PREFIX}ld"
+export NM_FOR_TARGET = "${TARGET_PREFIX}nm"
+export RANLIB_FOR_TARGET = "${TARGET_PREFIX}ranlib"
+
+export CC_FOR_HOST = "${CCACHE}${HOST_PREFIX}gcc ${HOST_CC_ARCH}"
+export CXX_FOR_HOST = "${CCACHE}${HOST_PREFIX}gcc ${HOST_CC_ARCH}"
+
+# autotools.bbclass sets the _FOR_BUILD variables, but for some reason we need
+# to unset LD_LIBRARY_PATH.
+export CC_FOR_BUILD = "LD_LIBRARY_PATH= ${BUILD_CC}"
+
+MULTIARCH := "${@bb.utils.contains("DISTRO_FEATURES", "multiarch", "yes", "no", d)}"
+do_configure[vardeps] += "MULTIARCH"
+do_configure () {
+	(cd ${S}; gnu-configize) || die "Failed to run gnu-configize"
+	oe_runconf
+#
+# must prime config.cache to ensure the build of libiberty
+#
+	mkdir -p ${B}/build-${BUILD_SYS}
+	for i in ${CONFIG_SITE}; do
+		cat $i >> ${B}/build-${BUILD_SYS}/config.cache || true
+	done
+}
+
+do_install () {
+	autotools_do_install
+
+	# We don't really need these, so we'll remove them...
+	rm -rf ${D}${libdir}/ldscripts
+
+	# Fix the /usr/${TARGET_SYS}/bin/* links
+	for l in ${D}${prefix}/${TARGET_SYS}/bin/*; do
+		rm -f $l
+		ln -sf `echo ${prefix}/${TARGET_SYS}/bin \
+			| tr -s / \
+			| sed -e 's,^/,,' -e 's,[^/]*,..,g'`${bindir}/${TARGET_PREFIX}`basename $l` $l
+	done
+
+	# Install the libiberty header
+	install -d ${D}${includedir}
+	install -m 644 ${S}/include/ansidecl.h ${D}${includedir}
+	install -m 644 ${S}/include/libiberty.h ${D}${includedir}
+
+	cd ${D}${bindir}
+
+	# Symlinks for ease of running these on the native target
+	for p in ${TARGET_PREFIX}* ; do
+		ln -sf $p `echo $p | sed -e s,${TARGET_PREFIX},,`
+	done
+
+	for alt in ${USE_ALTERNATIVES_FOR}; do
+		rm -f ${D}${bindir}/$alt
+	done
+
+	oe_multilib_header bfd.h
+}
+
+inherit update-alternatives
+
+ALTERNATIVE_PRIORITY = "100"
+
+ALTERNATIVE_${PN}_class-target = "${USE_ALTERNATIVES_FOR}"
diff --git a/recipes-devtools/binutils/binutils/0001-Fix-MMIX-build-breakage-from-bfd_set_section_vma-cha.patch b/recipes-devtools/binutils/binutils/0001-Fix-MMIX-build-breakage-from-bfd_set_section_vma-cha.patch
new file mode 100644
index 0000000..f786b17
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/0001-Fix-MMIX-build-breakage-from-bfd_set_section_vma-cha.patch
@@ -0,0 +1,31 @@
+Upstream-Status: Backport
+
+From 0a09fb4a09e80c36fa3ef763ae276fd13d272a36 Mon Sep 17 00:00:00 2001
+From: Hans-Peter Nilsson <hp@bitrange.com>
+Date: Sat, 1 Feb 2014 01:11:28 +0100
+Subject: [PATCH] Fix MMIX build breakage from bfd_set_section_vma change.
+
+	* emultempl/mmix-elfnmmo.em (mmix_after_allocation): Fix typo in
+	call to bfd_set_section_vma exposed by recent bfd_set_section_vma
+	change.
+---
+ ld/ChangeLog                 |    6 ++++++
+ ld/emultempl/mmix-elfnmmo.em |    2 +-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/ld/emultempl/mmix-elfnmmo.em b/ld/emultempl/mmix-elfnmmo.em
+index 0059792..5e9781a 100644
+--- a/ld/emultempl/mmix-elfnmmo.em
++++ b/ld/emultempl/mmix-elfnmmo.em
+@@ -102,7 +102,7 @@ mmix_after_allocation (void)
+      This section is only present when there are register symbols.  */
+   sec = bfd_get_section_by_name (link_info.output_bfd, MMIX_REG_SECTION_NAME);
+   if (sec != NULL)
+-    bfd_set_section_vma (abfd, sec, 0);
++    bfd_set_section_vma (sec->owner, sec, 0);
+ 
+   if (!_bfd_mmix_after_linker_allocation (link_info.output_bfd, &link_info))
+     {
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/binutils/binutils/binutils-armv5e.patch b/recipes-devtools/binutils/binutils/binutils-armv5e.patch
new file mode 100644
index 0000000..97ad6df
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-armv5e.patch
@@ -0,0 +1,25 @@
+Add the armv5e architecture to binutils
+
+Binutils has a comment that indicates it is supposed to match gcc for all of
+the support "-march=" settings, but it was lacking the armv5e setting.  This
+was a simple way to add it, as thumb instructions shouldn't be generated by
+the compiler anyway.
+
+Upstream-Status: Denied
+Upstream maintainer indicated that we should not be using armv5e, even though
+it is a legal archicture defined by our gcc.
+
+Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
+
+Index: binutils-2.22.90/gas/config/tc-arm.c
+===================================================================
+--- binutils-2.22.90.orig/gas/config/tc-arm.c	2012-07-24 09:38:32.000000000 -0700
++++ binutils-2.22.90/gas/config/tc-arm.c	2012-08-07 23:41:59.822564075 -0700
+@@ -23162,6 +23162,7 @@
+   ARM_ARCH_OPT ("armv4t",	ARM_ARCH_V4T,	 FPU_ARCH_FPA),
+   ARM_ARCH_OPT ("armv4txm",	ARM_ARCH_V4TxM,	 FPU_ARCH_FPA),
+   ARM_ARCH_OPT ("armv5",	ARM_ARCH_V5,	 FPU_ARCH_VFP),
++  ARM_ARCH_OPT ("armv5e",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP),
+   ARM_ARCH_OPT ("armv5t",	ARM_ARCH_V5T,	 FPU_ARCH_VFP),
+   ARM_ARCH_OPT ("armv5txm",	ARM_ARCH_V5TxM,	 FPU_ARCH_VFP),
+   ARM_ARCH_OPT ("armv5te",	ARM_ARCH_V5TE,	 FPU_ARCH_VFP),
diff --git a/recipes-devtools/binutils/binutils/binutils-poison.patch b/recipes-devtools/binutils/binutils/binutils-poison.patch
new file mode 100644
index 0000000..eb54076
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-poison.patch
@@ -0,0 +1,259 @@
+Upstream-Status: Inappropriate [distribution: codesourcery]
+
+Patch originally created by Mark Hatle, forward-ported to
+binutils 2.21 by Scott Garman.
+
+purpose:  warn for uses of system directories when cross linking
+
+Code Merged from Sourcery G++ binutils 2.19 - 4.4-277
+
+2008-07-02  Joseph Myers  <joseph@codesourcery.com>
+
+    ld/
+    * ld.h (args_type): Add error_poison_system_directories.
+    * ld.texinfo (--error-poison-system-directories): Document.
+    * ldfile.c (ldfile_add_library_path): Check
+    command_line.error_poison_system_directories.
+    * ldmain.c (main): Initialize
+    command_line.error_poison_system_directories.
+    * lexsup.c (enum option_values): Add
+    OPTION_ERROR_POISON_SYSTEM_DIRECTORIES.
+    (ld_options): Add --error-poison-system-directories.
+    (parse_args): Handle new option.
+
+2007-06-13  Joseph Myers  <joseph@codesourcery.com>
+
+    ld/
+    * config.in: Regenerate.
+    * ld.h (args_type): Add poison_system_directories.
+    * ld.texinfo (--no-poison-system-directories): Document.
+    * ldfile.c (ldfile_add_library_path): Check
+    command_line.poison_system_directories.
+    * ldmain.c (main): Initialize
+    command_line.poison_system_directories.
+    * lexsup.c (enum option_values): Add
+    OPTION_NO_POISON_SYSTEM_DIRECTORIES.
+    (ld_options): Add --no-poison-system-directories.
+    (parse_args): Handle new option.
+
+2007-04-20  Joseph Myers  <joseph@codesourcery.com>
+
+    Merge from Sourcery G++ binutils 2.17:
+
+    2007-03-20  Joseph Myers  <joseph@codesourcery.com>
+    Based on patch by Mark Hatle <mark.hatle@windriver.com>.
+    ld/
+    * configure.in (--enable-poison-system-directories): New option.
+    * configure, config.in: Regenerate.
+    * ldfile.c (ldfile_add_library_path): If
+    ENABLE_POISON_SYSTEM_DIRECTORIES defined, warn for use of /lib,
+    /usr/lib, /usr/local/lib or /usr/X11R6/lib.
+
+Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
+Index: binutils-2.24/ld/config.in
+===================================================================
+--- binutils-2.24.orig/ld/config.in	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/config.in	2013-12-15 11:46:59.810435651 -0800
+@@ -11,6 +11,9 @@
+    language is requested. */
+ #undef ENABLE_NLS
+ 
++/* Define to warn for use of native system library directories */
++#undef ENABLE_POISON_SYSTEM_DIRECTORIES
++
+ /* Additional extension a shared object might have. */
+ #undef EXTRA_SHLIB_EXTENSION
+ 
+Index: binutils-2.24/ld/configure
+===================================================================
+--- binutils-2.24.orig/ld/configure	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/configure	2013-12-15 11:46:59.810435651 -0800
+@@ -777,6 +777,7 @@
+ enable_targets
+ enable_64_bit_bfd
+ with_sysroot
++enable_poison_system_directories
+ enable_gold
+ enable_got
+ enable_werror
+@@ -1433,6 +1434,8 @@
+ 			  (and sometimes confusing) to the casual installer
+   --enable-targets        alternative target configurations
+   --enable-64-bit-bfd     64-bit support (on hosts with narrower word sizes)
++  --enable-poison-system-directories
++                          warn for use of native system library directories
+   --enable-gold[=ARG]     build gold [ARG={default,yes,no}]
+   --enable-got=<type>     GOT handling scheme (target, single, negative,
+                           multigot)
+@@ -4345,7 +4348,18 @@
+ fi
+ 
+ 
++# Check whether --enable-poison-system-directories was given.
++if test "${enable_poison_system_directories+set}" = set; then :
++  enableval=$enable_poison_system_directories;
++else
++  enable_poison_system_directories=no
++fi
++
++if test "x${enable_poison_system_directories}" = "xyes"; then
+ 
++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h
++
++fi
+ 
+ # Check whether --enable-got was given.
+ if test "${enable_got+set}" = set; then :
+Index: binutils-2.24/ld/configure.ac
+===================================================================
+--- binutils-2.24.orig/ld/configure.ac	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/configure.ac	2013-12-15 11:46:59.810435651 -0800
+@@ -87,6 +87,16 @@
+ AC_SUBST(TARGET_SYSTEM_ROOT)
+ AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
+ 
++AC_ARG_ENABLE([poison-system-directories],
++         AS_HELP_STRING([--enable-poison-system-directories],
++                [warn for use of native system library directories]),,
++         [enable_poison_system_directories=no])
++if test "x${enable_poison_system_directories}" = "xyes"; then
++  AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES],
++       [1],
++       [Define to warn for use of native system library directories])
++fi
++
+ dnl Use --enable-gold to decide if this linker should be the default.
+ dnl "install_as_default" is set to false if gold is the default linker.
+ dnl "installed_linker" is the installed BFD linker name.
+Index: binutils-2.24/ld/ldfile.c
+===================================================================
+--- binutils-2.24.orig/ld/ldfile.c	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/ldfile.c	2013-12-15 11:46:59.813768989 -0800
+@@ -116,6 +116,23 @@
+     new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL);
+   else
+     new_dirs->name = xstrdup (name);
++
++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES
++  if (command_line.poison_system_directories
++  && ((!strncmp (name, "/lib", 4))
++      || (!strncmp (name, "/usr/lib", 8))
++      || (!strncmp (name, "/usr/local/lib", 14))
++      || (!strncmp (name, "/usr/X11R6/lib", 14))))
++   {
++     if (command_line.error_poison_system_directories)
++       einfo (_("%X%P: error: library search path \"%s\" is unsafe for "
++            "cross-compilation\n"), name);
++     else
++       einfo (_("%P: warning: library search path \"%s\" is unsafe for "
++            "cross-compilation\n"), name);
++   }
++#endif
++
+ }
+ 
+ /* Try to open a BFD for a lang_input_statement.  */
+Index: binutils-2.24/ld/ld.h
+===================================================================
+--- binutils-2.24.orig/ld/ld.h	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/ld.h	2013-12-15 11:46:59.813768989 -0800
+@@ -180,6 +180,14 @@
+   /* If TRUE we'll just print the default output on stdout.  */
+   bfd_boolean print_output_format;
+ 
++  /* If TRUE (the default) warn for uses of system directories when
++     cross linking.  */
++  bfd_boolean poison_system_directories;
++
++  /* If TRUE (default FALSE) give an error for uses of system
++     directories when cross linking instead of a warning.  */
++  bfd_boolean error_poison_system_directories;
++
+   /* Big or little endian as set on command line.  */
+   enum endian_enum endian;
+ 
+Index: binutils-2.24/ld/ldmain.c
+===================================================================
+--- binutils-2.24.orig/ld/ldmain.c	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/ldmain.c	2013-12-15 11:48:12.087101740 -0800
+@@ -266,6 +266,8 @@
+   command_line.warn_mismatch = TRUE;
+   command_line.warn_search_mismatch = TRUE;
+   command_line.check_section_addresses = -1;
++  command_line.poison_system_directories = TRUE;
++  command_line.error_poison_system_directories = FALSE;
+ 
+   /* We initialize DEMANGLING based on the environment variable
+      COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
+Index: binutils-2.24/ld/ld.texinfo
+===================================================================
+--- binutils-2.24.orig/ld/ld.texinfo	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/ld.texinfo	2013-12-15 11:46:59.813768989 -0800
+@@ -2175,6 +2175,18 @@
+ 
+ Passing @code{none} for @var{style} disables the setting from any
+ @code{--build-id} options earlier on the command line.
++
++@kindex --no-poison-system-directories
++@item --no-poison-system-directories
++Do not warn for @option{-L} options using system directories such as
++@file{/usr/lib} when cross linking.  This option is intended for use
++in chroot environments when such directories contain the correct
++libraries for the target system rather than the host.
++
++@kindex --error-poison-system-directories
++@item --error-poison-system-directories
++Give an error instead of a warning for @option{-L} options using
++system directories when cross linking.
+ @end table
+ 
+ @c man end
+Index: binutils-2.24/ld/lexsup.c
+===================================================================
+--- binutils-2.24.orig/ld/lexsup.c	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/lexsup.c	2013-12-15 11:49:28.950434490 -0800
+@@ -513,6 +513,14 @@ static const struct ld_option ld_options[] =
+   { {"pop-state", no_argument, NULL, OPTION_POP_STATE},
+     '\0', NULL, N_("Pop state of flags governing input file handling"),
+     TWO_DASHES },
++  { {"no-poison-system-directories", no_argument, NULL,
++     OPTION_NO_POISON_SYSTEM_DIRECTORIES},
++    '\0', NULL, N_("Do not warn for -L options using system directories"),
++    TWO_DASHES },
++  { {"error-poison-system-directories", no_argument, NULL,
++    +     OPTION_ERROR_POISON_SYSTEM_DIRECTORIES},
++    '\0', NULL, N_("Give an error for -L options using system directories"),
++    TWO_DASHES },
+ };
+ 
+ #define OPTION_COUNT ARRAY_SIZE (ld_options)
+@@ -1474,6 +1482,14 @@ parse_args (unsigned argc, char **argv)
+ 	      free (oldp);
+ 	    }
+ 	  break;
++
++	case OPTION_NO_POISON_SYSTEM_DIRECTORIES:
++	  command_line.poison_system_directories = FALSE;
++	  break;
++
++	case OPTION_ERROR_POISON_SYSTEM_DIRECTORIES:
++	  command_line.error_poison_system_directories = TRUE;
++	  break;
+ 	}
+     }
+ 
+Index: binutils-2.24/ld/ldlex.h
+===================================================================
+--- binutils-2.24.orig/ld/ldlex.h	2013-12-15 11:46:17.000000000 -0800
++++ binutils-2.24/ld/ldlex.h	2013-12-15 11:47:43.230435299 -0800
+@@ -140,6 +140,8 @@ enum option_values
+   OPTION_IGNORE_UNRESOLVED_SYMBOL,
+   OPTION_PUSH_STATE,
+   OPTION_POP_STATE,
++  OPTION_NO_POISON_SYSTEM_DIRECTORIES,
++  OPTION_ERROR_POISON_SYSTEM_DIRECTORIES,
+ };
+ 
+ /* The initial parser states.  */
diff --git a/recipes-devtools/binutils/binutils/binutils-uclibc-100-uclibc-conf.patch b/recipes-devtools/binutils/binutils/binutils-uclibc-100-uclibc-conf.patch
new file mode 100644
index 0000000..b5a25c2
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-uclibc-100-uclibc-conf.patch
@@ -0,0 +1,40 @@
+Upstream-Status: Pending
+
+Index: binutils-2.22/configure
+===================================================================
+--- binutils-2.22.orig/configure
++++ binutils-2.22/configure
+@@ -3130,7 +3130,7 @@ case "${target}" in
+     ;;
+   s390-*-* | s390x-*-*)
+     ;;
+-  sh-*-* | sh[34]*-*-*)
++  sh*-*-* | sh[34]*-*-*)
+     ;;
+   sh64-*-* | sh5*-*-*)
+     ;;
+@@ -3570,7 +3570,7 @@ case "${target}" in
+   mips*-*-*)
+     noconfigdirs="$noconfigdirs gprof"
+     ;;
+-  sh-*-* | sh64-*-*)
++  sh*-*-* | sh64-*-*)
+     case "${target}" in
+       sh*-*-elf)
+          ;;
+Index: binutils-2.22/gprof/configure
+===================================================================
+--- binutils-2.22.orig/gprof/configure
++++ binutils-2.22/gprof/configure
+@@ -6103,6 +6103,11 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+   lt_cv_deplibs_check_method=pass_all
+   ;;
+ 
++linux-uclibc*)
++  lt_cv_deplibs_check_method=pass_all
++  lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so`
++  ;;
++
+ netbsd*)
+   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
diff --git a/recipes-devtools/binutils/binutils/binutils-uclibc-300-001_ld_makefile_patch.patch b/recipes-devtools/binutils/binutils/binutils-uclibc-300-001_ld_makefile_patch.patch
new file mode 100644
index 0000000..c6e1efc
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-uclibc-300-001_ld_makefile_patch.patch
@@ -0,0 +1,55 @@
+#!/bin/sh -e
+## 001_ld_makefile_patch.dpatch
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: correct where ld scripts are installed
+## DP: Author: Chris Chimelis <chris@debian.org>
+## DP: Upstream status: N/A
+## DP: Date: ??
+
+if [ $# -ne 1 ]; then
+    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+       -patch) patch $patch_opts -p1 < $0;;
+       -unpatch) patch $patch_opts -p1 -R < $0;;
+        *)
+                echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+                exit 1;;
+esac
+
+exit 0
+Upstream-Status: Inappropriate [debian patch]
+
+@DPATCH@
+Index: binutils-2.22/ld/Makefile.am
+===================================================================
+--- binutils-2.22.orig/ld/Makefile.am
++++ binutils-2.22/ld/Makefile.am
+@@ -37,7 +37,7 @@ endif
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+ 
+ EMUL = @EMUL@
+ EMULATION_OFILES = @EMULATION_OFILES@
+Index: binutils-2.22/ld/Makefile.in
+===================================================================
+--- binutils-2.22.orig/ld/Makefile.in
++++ binutils-2.22/ld/Makefile.in
+@@ -366,7 +366,7 @@ AM_CFLAGS = $(WARN_CFLAGS)
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+ BASEDIR = $(srcdir)/..
+ BFDDIR = $(BASEDIR)/bfd
+ INCDIR = $(BASEDIR)/include
diff --git a/recipes-devtools/binutils/binutils/binutils-uclibc-300-006_better_file_error.patch b/recipes-devtools/binutils/binutils/binutils-uclibc-300-006_better_file_error.patch
new file mode 100644
index 0000000..47bd8ff
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-uclibc-300-006_better_file_error.patch
@@ -0,0 +1,45 @@
+#!/bin/sh -e
+## 006_better_file_error.dpatch by David Kimdon <dwhedon@gordian.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Specify which filename is causing an error if the filename is a
+## DP: directory. (#45832)
+
+if [ $# -ne 1 ]; then
+    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+       -patch) patch $patch_opts -p1 < $0;;
+       -unpatch) patch $patch_opts -p1 -R < $0;;
+        *)
+                echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+                exit 1;;
+esac
+
+exit 0
+Upstream-Status: Inappropriate [debian patch]
+
+@DPATCH@
+Index: binutils-2.22/bfd/opncls.c
+===================================================================
+--- binutils-2.22.orig/bfd/opncls.c
++++ binutils-2.22/bfd/opncls.c
+@@ -197,6 +197,13 @@ bfd_fopen (const char *filename, const c
+ {
+   bfd *nbfd;
+   const bfd_target *target_vec;
++  struct stat s;
++
++  if (stat (filename, &s) == 0)
++    if (S_ISDIR(s.st_mode)) {
++      bfd_set_error (bfd_error_file_not_recognized);
++      return NULL;
++    }
+ 
+   nbfd = _bfd_new_bfd ();
+   if (nbfd == NULL)
diff --git a/recipes-devtools/binutils/binutils/binutils-uclibc-300-012_check_ldrunpath_length.patch b/recipes-devtools/binutils/binutils/binutils-uclibc-300-012_check_ldrunpath_length.patch
new file mode 100644
index 0000000..d31f80c
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-uclibc-300-012_check_ldrunpath_length.patch
@@ -0,0 +1,49 @@
+#!/bin/sh -e
+## 012_check_ldrunpath_length.dpatch by Chris Chimelis <chris@debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Only generate an RPATH entry if LD_RUN_PATH is not empty, for
+## DP: cases where -rpath isn't specified. (#151024)
+
+if [ $# -ne 1 ]; then
+    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+       -patch) patch $patch_opts -p1 < $0;;
+       -unpatch) patch $patch_opts -p1 -R < $0;;
+        *)
+                echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+                exit 1;;
+esac
+
+exit 0
+Upstream-Status: Inappropriate [debian patch]
+
+@DPATCH@
+Index: binutils-2.22/ld/emultempl/elf32.em
+===================================================================
+--- binutils-2.22.orig/ld/emultempl/elf32.em
++++ binutils-2.22/ld/emultempl/elf32.em
+@@ -1273,6 +1273,8 @@ fragment <<EOF
+ 	      && command_line.rpath == NULL)
+ 	    {
+ 	      lib_path = (const char *) getenv ("LD_RUN_PATH");
++	      if ((lib_path) && (strlen (lib_path) == 0))
++		  lib_path = NULL;
+ 	      if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
+ 						      force))
+ 		break;
+@@ -1500,6 +1502,8 @@ gld${EMULATION_NAME}_before_allocation (
+   rpath = command_line.rpath;
+   if (rpath == NULL)
+     rpath = (const char *) getenv ("LD_RUN_PATH");
++  if ((rpath) && (strlen (rpath) == 0))
++    rpath = NULL;
+ 
+   for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+     if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
diff --git a/recipes-devtools/binutils/binutils/binutils-uclibc-gas-needs-libm.patch b/recipes-devtools/binutils/binutils/binutils-uclibc-gas-needs-libm.patch
new file mode 100644
index 0000000..3869faf
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-uclibc-gas-needs-libm.patch
@@ -0,0 +1,38 @@
+Source: Khem Raj <raj.khem@gmail.com>
+Disposition: submit upstream.
+Upstream-Status: Pending
+
+Description:
+
+We do not need to have the libtool patch anymore for binutils after
+libtool has been updated upstream it include support for it. However
+for building gas natively on uclibc systems we have to link it with
+-lm so that it picks up missing symbols.
+
+/local/build_area/BUILD/arm_v5t_le_uclibc/binutils-2.17.50/objdir/libiberty/pic/libiberty.a(floatformat.o): In function `floatformat_from_double':
+floatformat.c:(.text+0x1ec): undefined reference to `frexp'
+floatformat.c:(.text+0x2f8): undefined reference to `ldexp'
+/local/build_area/BUILD/arm_v5t_le_uclibc/binutils-2.17.50/objdir/libiberty/pic/libiberty.a(floatformat.o): In function `floatformat_to_double':
+floatformat.c:(.text+0x38a): undefined reference to `ldexp'
+floatformat.c:(.text+0x3d2): undefined reference to `ldexp'
+floatformat.c:(.text+0x43e): undefined reference to `ldexp'                     floatformat.c:(.text+0x4e2): undefined reference to `ldexp'
+collect2: ld returned 1 exit status
+make[4]: *** [as-new] Error 1
+
+Index: binutils-2.22/gas/configure.tgt
+===================================================================
+--- binutils-2.22.orig/gas/configure.tgt
++++ binutils-2.22/gas/configure.tgt
+@@ -428,6 +428,12 @@ case ${generic_target} in
+   *-*-netware)				fmt=elf em=netware ;;
+ esac
+ 
++case ${generic_target} in
++  arm-*-*uclibc*)
++    need_libm=yes
++    ;;
++esac
++
+ case ${cpu_type} in
+   alpha | arm | i386 | ia64 | microblaze | mips | ns32k | pdp11 | ppc | sparc | z80 | z8k)
+     bfd_gas=yes
diff --git a/recipes-devtools/binutils/binutils/binutils-uninitialised-warning.patch b/recipes-devtools/binutils/binutils/binutils-uninitialised-warning.patch
new file mode 100644
index 0000000..2feb80c
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-uninitialised-warning.patch
@@ -0,0 +1,50 @@
+From f9c316c4d75be236bbaa8464ef803ed2d3859d6d Mon Sep 17 00:00:00 2001
+From: H.J. Lu <hjl.tools@gmail.com>
+Date: Wed, 15 Jan 2014 07:43:19 -0800
+Subject: [PATCH 1/1] Silence uninitialized warning on ehdr_start_save
+
+Older GCC, like 4.1/4.2, will issue an uninitialized warning on
+ehdr_start_save.  This patch silences by using
+
+struct bfd_link_hash_entry ehdr_start_save = ehdr_start_save;
+
+	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+	Silence uninitialized warning on ehdr_start_save with older
+	GCC.
+
+Upstream-Status: Backport
+---
+ ld/ChangeLog          |    6 ++++++
+ ld/emultempl/elf32.em |    2 +-
+ 2 files changed, 7 insertions(+), 1 deletions(-)
+
+#diff --git a/ld/ChangeLog b/ld/ChangeLog
+#index eaa6b93..91055de 100644
+#--- a/ld/ChangeLog
+#+++ b/ld/ChangeLog
+#@@ -1,3 +1,9 @@
+#+2014-01-15  H.J. Lu  <hongjiu.lu@intel.com>
+#+
+#+	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+#+	Silence uninitialized warning on ehdr_start_save with older
+#+	GCC.
+#+
+# 2014-01-15  Alan Modra  <amodra@gmail.com>
+# 
+# 	* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Define
+diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
+index 13f86f0..569c7f7 100644
+--- a/ld/emultempl/elf32.em
++++ b/ld/emultempl/elf32.em
+@@ -1481,7 +1481,7 @@ gld${EMULATION_NAME}_before_allocation (void)
+   asection *sinterp;
+   bfd *abfd;
+   struct elf_link_hash_entry *ehdr_start = NULL;
+-  struct bfd_link_hash_entry ehdr_start_save;
++  struct bfd_link_hash_entry ehdr_start_save = ehdr_start_save;
+ 
+   if (is_elf_hash_table (link_info.hash))
+     {
+-- 
+1.7.1
+
diff --git a/recipes-devtools/binutils/binutils/binutils-xlp-support.patch b/recipes-devtools/binutils/binutils/binutils-xlp-support.patch
new file mode 100644
index 0000000..b03bb28
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/binutils-xlp-support.patch
@@ -0,0 +1,402 @@
+Upstream-Status: Unknown
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+From 26adb06ce515aadfec08ce13109b4b98287f677b Mon Sep 17 00:00:00 2001
+From: Nebu Philips <nphilips@netlogicmicro.com>
+Date: Fri, 30 Jul 2010 15:10:03 -0700
+Subject: [PATCH] Add support for Netlogic XLP
+
+Using the mipsisa64r2nlm target, add support for XLP from
+Netlogic. Also, update vendor name to NLM wherever applicable.
+---
+ bfd/aoutx.h           |    1 +
+ bfd/archures.c        |    1 +
+ bfd/bfd-in2.h         |    1 +
+ bfd/config.bfd        |    5 +++++
+ bfd/cpu-mips.c        |    6 ++++--
+ bfd/elfxx-mips.c      |    8 ++++++++
+ binutils/readelf.c    |    1 +
+ gas/config/tc-mips.c  |    4 +++-
+ gas/configure         |    3 +++
+ gas/configure.tgt     |    2 +-
+ include/elf/mips.h    |    1 +
+ include/opcode/mips.h |   10 ++++++++--
+ ld/configure.tgt      |    2 ++
+ opcodes/mips-dis.c    |   12 +++++-------
+ opcodes/mips-opc.c    |   33 +++++++++++++++++++++------------
+ 15 files changed, 65 insertions(+), 25 deletions(-)
+
+diff --git a/bfd/aoutx.h b/bfd/aoutx.h
+index 9385a98..a88df99 100644
+--- a/bfd/aoutx.h
++++ b/bfd/aoutx.h
+@@ -802,6 +802,7 @@ NAME (aout, machine_type) (enum bfd_architecture arch,
+ 	case bfd_mach_mipsisa64r6:
+ 	case bfd_mach_mips_sb1:
+ 	case bfd_mach_mips_xlr:
++	case bfd_mach_mips_xlp:
+ 	  /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc.  */
+ 	  arch_flags = M_MIPS2;
+ 	  break;
+diff --git a/bfd/archures.c b/bfd/archures.c
+index c9fd6c8..547bd09 100644
+--- a/bfd/archures.c
++++ b/bfd/archures.c
+@@ -180,6 +180,7 @@ DESCRIPTION
+ .#define bfd_mach_mips_octeonp		6601
+ .#define bfd_mach_mips_octeon2		6502
+ .#define bfd_mach_mips_xlr              887682   {* decimal 'XLR'  *}
++.#define bfd_mach_mips_xlp              887680   {* decimal 'XLP'  *}
+ .#define bfd_mach_mipsisa32             32
+ .#define bfd_mach_mipsisa32r2           33
+ .#define bfd_mach_mipsisa32r3           34
+diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
+index c7a2bb5..413b773 100644
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
+@@ -1967,6 +1967,7 @@ enum bfd_architecture
+ #define bfd_mach_mips_octeonp          6601
+ #define bfd_mach_mips_octeon2          6502
+ #define bfd_mach_mips_xlr              887682   /* decimal 'XLR'  */
++#define bfd_mach_mips_xlp              887680   /* decimal 'XLP'  */
+ #define bfd_mach_mipsisa32             32
+ #define bfd_mach_mipsisa32r2           33
+ #define bfd_mach_mipsisa32r3           34
+diff --git a/bfd/config.bfd b/bfd/config.bfd
+index 03d2c6f..91cedb8 100644
+--- a/bfd/config.bfd
++++ b/bfd/config.bfd
+@@ -1041,6 +1041,11 @@ case "${targ}" in
+     targ_defvec=mips_elf32_le_vec
+     targ_selvecs="mips_elf32_be_vec mips_elf64_be_vec mips_elf64_le_vec"
+     ;;
++  mipsisa64*-*-elf*)
++	targ_defvec=mips_elf32_trad_be_vec
++	targ_selvecs="mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
++	want64=true
++	;;
+   mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks | mips*-*-windiss)
+     targ_defvec=mips_elf32_be_vec
+     targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec"
+diff --git a/bfd/cpu-mips.c b/bfd/cpu-mips.c
+index b617aaa..19a99d1 100644
+--- a/bfd/cpu-mips.c
++++ b/bfd/cpu-mips.c
+@@ -103,7 +103,8 @@ enum
+   I_mipsocteonp,
+   I_mipsocteon2,
+   I_xlr,
+-  I_micromips
++  I_micromips,
++  I_xlp
+ };
+ 
+ #define NN(index) (&arch_info_struct[(index) + 1])
+@@ -153,7 +154,8 @@ static const bfd_arch_info_type arch_info_struct[] =
+   N (64, 64, bfd_mach_mips_octeonp,"mips:octeon+",  FALSE, NN(I_mipsocteonp)),
+   N (64, 64, bfd_mach_mips_octeon2,"mips:octeon2",  FALSE, NN(I_mipsocteon2)),
+   N (64, 64, bfd_mach_mips_xlr, "mips:xlr",       FALSE, NN(I_xlr)),
+-  N (64, 64, bfd_mach_mips_micromips,"mips:micromips",FALSE,0)
++  N (64, 64, bfd_mach_mips_micromips,"mips:micromips",FALSE,NN(I_micromips)),
++  N (64, 64, bfd_mach_mips_xlp, "mips:xlp",      FALSE, 0)
+ };
+ 
+ /* The default architecture is mips:3000, but with a machine number of
+diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
+index a0cc26e..672d5b3 100644
+--- a/bfd/elfxx-mips.c
++++ b/bfd/elfxx-mips.c
+@@ -6608,6 +6608,9 @@ _bfd_elf_mips_mach (flagword flags)
+     case E_MIPS_MACH_XLR:
+       return bfd_mach_mips_xlr;
+ 
++	case E_MIPS_MACH_XLP:
++      return bfd_mach_mips_xlp;
++
+     default:
+       switch (flags & EF_MIPS_ARCH)
+ 	{
+@@ -11878,6 +11881,10 @@ mips_set_isa_flags (bfd *abfd)
+       val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_OCTEON2;
+       break;
+ 
++	case bfd_mach_mips_xlp:
++	  val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_XLP;
++	  break;
++
+     case bfd_mach_mipsisa32:
+       val = E_MIPS_ARCH_32;
+       break;
+@@ -14753,6 +14760,7 @@ static const struct mips_mach_extension mips_mach_extensions[] =
+   { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
+   { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
+   { bfd_mach_mips_loongson_3a, bfd_mach_mipsisa64r2 },
++  { bfd_mach_mips_xlp, bfd_mach_mipsisa64r2 },
+ 
+   /* MIPS64 extensions.  */
+   { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
+diff --git a/binutils/readelf.c b/binutils/readelf.c
+index 0c00b2f..6e9d5e4 100644
+--- a/binutils/readelf.c
++++ b/binutils/readelf.c
+@@ -2898,6 +2898,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
+ 	    case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
+ 	    case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
+ 	    case E_MIPS_MACH_XLR:  strcat (buf, ", xlr"); break;
++		case E_MIPS_MACH_XLP:  strcat (buf, ", xlp"); break;
+ 	    case 0:
+ 	    /* We simply ignore the field in this case to avoid confusion:
+ 	       MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
+diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
+index c3e3e2a..8d64344 100644
+--- a/gas/config/tc-mips.c
++++ b/gas/config/tc-mips.c
+@@ -551,6 +551,7 @@ static int mips_32bitmode = 0;
+    || mips_opts.arch == CPU_RM7000                    \
+    || mips_opts.arch == CPU_VR5500                    \
+    || mips_opts.micromips                             \
++   || mips_opts.arch == CPU_XLP                       \
+    )
+ 
+ /* Whether the processor uses hardware interlocks to protect reads
+@@ -580,6 +581,7 @@ static int mips_32bitmode = 0;
+     && mips_opts.isa != ISA_MIPS3)                    \
+    || mips_opts.arch == CPU_R4300                     \
+    || mips_opts.micromips                             \
++   || mips_opts.arch == CPU_XLP                       \
+    )
+ 
+ /* Whether the processor uses hardware interlocks to protect reads
+@@ -18682,7 +18684,7 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
+   /* Broadcom XLP.
+      XLP is mostly like XLR, with the prominent exception that it is
+      MIPS64R2 rather than MIPS64.  */
+-  { "xlp",	      0, 0,			ISA_MIPS64R2, CPU_XLR },
++  { "xlp",	      0, 0,			ISA_MIPS64R2, CPU_XLP },
+ 
+   /* End marker */
+   { NULL, 0, 0, 0, 0 }
+diff --git a/gas/configure b/gas/configure
+index 9529f1a..63bba5b 100755
+--- a/gas/configure
++++ b/gas/configure
+@@ -12808,6 +12808,9 @@ _ACEOF
+ 	  mipsisa64r6 | mipsisa64r6el)
+ 	    mips_cpu=mips64r6
+ 	    ;;
++	  mipsisa64r2nlm | mipsisa64r2nlmel)
++		mips_cpu=xlp
++		;;
+ 	  mipstx39 | mipstx39el)
+ 	    mips_cpu=r3900
+ 	    ;;
+diff --git a/gas/configure.tgt b/gas/configure.tgt
+index 05546ca..bb859d6 100644
+--- a/gas/configure.tgt
++++ b/gas/configure.tgt
+@@ -332,7 +332,7 @@ case ${generic_target} in
+   mips-*-sysv4*MP* | mips-*-gnu*)	fmt=elf em=tmips ;;
+   mips*-sde-elf* | mips*-mti-elf* | mips*-img-elf*)
+ 					fmt=elf em=tmips ;;
+-  mips-*-elf* | mips-*-rtems*)		fmt=elf ;;
++  mips-*-elf* | mips-*-rtems*)		fmt=elf em=tmips ;;
+   mips-*-netbsd*)			fmt=elf em=tmips ;;
+   mips-*-openbsd*)			fmt=elf em=tmips ;;
+ 
+diff --git a/include/elf/mips.h b/include/elf/mips.h
+index 2ed6acd..899b1e5 100644
+--- a/include/elf/mips.h
++++ b/include/elf/mips.h
+@@ -285,6 +285,7 @@ END_RELOC_NUMBERS (R_MIPS_maxext)
+ #define E_MIPS_MACH_SB1         0x008a0000
+ #define E_MIPS_MACH_OCTEON	0x008b0000
+ #define E_MIPS_MACH_XLR     	0x008c0000
++#define E_MIPS_MACH_XLP         0x008f0000
+ #define E_MIPS_MACH_OCTEON2	0x008d0000
+ #define E_MIPS_MACH_OCTEON3	0x008e0000
+ #define E_MIPS_MACH_5400	0x00910000
+diff --git a/include/opcode/mips.h b/include/opcode/mips.h
+index ef26167..ef53ec6 100644
+--- a/include/opcode/mips.h
++++ b/include/opcode/mips.h
+@@ -1227,8 +1227,10 @@ static const unsigned int mips_isa_table[] = {
+ #define INSN_LOONGSON_2F          0x80000000
+ /* Loongson 3A.  */
+ #define INSN_LOONGSON_3A          0x00000400
+-/* RMI Xlr instruction */
+-#define INSN_XLR                 0x00000020
++/* Netlogic Xlr instruction */
++#define INSN_XLR		0x00000020
++/* Netlogic XlP instruction */
++#define INSN_XLP		0x00000040
+ 
+ /* DSP ASE */
+ #define ASE_DSP			0x00000001
+@@ -1324,6 +1326,7 @@ static const unsigned int mips_isa_table[] = {
+ #define CPU_OCTEONP	6601
+ #define CPU_OCTEON2	6502
+ #define CPU_XLR     	887682   	/* decimal 'XLR'   */
++#define CPU_XLP         887680      /* decimal 'XLP'   */
+ 
+ /* Return true if the given CPU is included in INSN_* mask MASK.  */
+ 
+@@ -1398,6 +1401,9 @@ cpu_is_member (int cpu, unsigned int mask)
+       return ((mask & INSN_ISA_MASK) == INSN_ISA32R6)
+ 	     || ((mask & INSN_ISA_MASK) == INSN_ISA64R6);
+ 
++    case CPU_XLP:
++      return (mask & INSN_XLP) != 0;
++
+     default:
+       return FALSE;
+     }
+diff --git a/ld/configure.tgt b/ld/configure.tgt
+index 740b2ea..4df13a7 100644
+--- a/ld/configure.tgt
++++ b/ld/configure.tgt
+@@ -462,6 +462,8 @@ mips*el-sde-elf*)	targ_emul=elf32ltsmip
+ mips*-sde-elf* | mips*-mti-elf* | mips*-img-elf*)
+ 			targ_emul=elf32btsmip
+ 			targ_extra_emuls="elf32ltsmip elf32btsmipn32 elf64btsmip elf32ltsmipn32 elf64ltsmip" ;;
++mipsisa64*-*-elf*)	targ_emul=elf32btsmip
++			targ_extra_emuls="elf32ltsmip elf64btsmip elf64ltsmip" ;;
+ mips64*el-ps2-elf*)	targ_emul=elf32lr5900n32
+ 			targ_extra_emuls="elf32lr5900"
+ 			targ_extra_libpath=$targ_extra_emuls ;;
+diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
+index 1eb1d45..d6881af 100644
+--- a/opcodes/mips-dis.c
++++ b/opcodes/mips-dis.c
+@@ -655,13 +655,11 @@ const struct mips_arch_choice mips_arch_choices[] =
+     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
+     mips_cp1_names_mips3264, mips_hwr_names_numeric },
+ 
+-  /* XLP is mostly like XLR, with the prominent exception it is being
+-     MIPS64R2.  */
+-  { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
+-    ISA_MIPS64R2 | INSN_XLR, 0,
+-    mips_cp0_names_xlr,
+-    mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
+-    mips_cp1_names_mips3264, mips_hwr_names_numeric },
++  { "xlp", 1, bfd_mach_mips_xlp, CPU_XLP,
++    ISA_MIPS64R2 | INSN_XLP, 0,
++    mips_cp0_names_mips3264r2,
++    mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
++    mips_hwr_names_mips3264r2 },
+ 
+   /* This entry, mips16, is here only for ISA/processor selection; do
+      not print its name.  */
+diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
+index 2c3bbad..86eb95b 100644
+--- a/opcodes/mips-opc.c
++++ b/opcodes/mips-opc.c
+@@ -319,7 +319,8 @@ decode_mips_operand (const char *p)
+ #define IOCT	(INSN_OCTEON | INSN_OCTEONP | INSN_OCTEON2)
+ #define IOCTP	(INSN_OCTEONP | INSN_OCTEON2)
+ #define IOCT2	INSN_OCTEON2
+-#define XLR     INSN_XLR
++#define XLR	INSN_XLR
++#define XLP	INSN_XLP
+ #define IVIRT	ASE_VIRT
+ #define IVIRT64	ASE_VIRT64
+ 
+@@ -956,6 +957,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ {"clo",			"U,s",		0x70000021, 0xfc0007ff, WR_1|RD_2,		0,		I32|N55,	0,	I37 },
+ {"clz",			"d,s",		0x00000050, 0xfc1f07ff, WR_1|RD_2,		0,		I37,		0,	0 },
+ {"clz",			"U,s",		0x70000020, 0xfc0007ff, WR_1|RD_2,		0,		I32|N55,	0,	I37 },
++{"crc",			"d,s,t",	0x7000001c, 0xfc0007ff,	WR_1|RD_2|RD_3,	0,		XLP, 		0,	0 },
+ /* ctc0 is at the bottom of the table.  */
+ {"ctc1",		"t,G",		0x44c00000, 0xffe007ff,	RD_1|WR_CC|CM,		0,		I1,		0,	0 },
+ {"ctc1",		"t,S",		0x44c00000, 0xffe007ff,	RD_1|WR_CC|CM,		0,		I1,		0,	0 },
+@@ -988,12 +990,13 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ {"daddiu",		"t,r,j",	0x64000000, 0xfc000000, WR_1|RD_2,		0,		I3,		0,	0 },
+ {"daddu",		"d,v,t",	0x0000002d, 0xfc0007ff, WR_1|RD_2|RD_3,		0,		I3,		0,	0 },
+ {"daddu",		"t,r,I",	0,    (int) M_DADDU_I,	INSN_MACRO,		0,		I3,		0,	0 },
+-{"daddwc",		"d,s,t", 	0x70000038, 0xfc0007ff, WR_1|RD_2|RD_3|WR_C0|RD_C0, 0,		XLR,		0,	0 },
++{"daddwc",		"d,s,t", 	0x70000038, 0xfc0007ff, WR_1|RD_2|RD_3|WR_C0|RD_C0, 0,		XLR|XLP,	0,	0 },
+ {"dbreak",		"",		0x7000003f, 0xffffffff,	0,			0,		N5,		0,	0 },
+ {"dclo",		"d,s",		0x00000053, 0xfc1f07ff, WR_1|RD_2,		0,		I69,		0,	0 },
+ {"dclo",		"U,s",	 	0x70000025, 0xfc0007ff, WR_1|RD_2, 	0,		I64|N55,	0,	I69 },
+ {"dclz",		"d,s",		0x00000052, 0xfc1f07ff, WR_1|RD_2,		0,		I69,		0,	0 },
+ {"dclz",		"U,s",	 	0x70000024, 0xfc0007ff, WR_1|RD_2, 	0,		I64|N55,	0,	I69 },
++{"dcrc",		"d,s,t",	0x7000001d, 0xfc0007ff, WR_1|RD_2|RD_3,	0,		XLP, 		0,	0 },
+ /* dctr and dctw are used on the r5000.  */
+ {"dctr",		"o(b)",	 	0xbc050000, 0xfc1f0000, RD_2,			0,		I3,		0,	0 },
+ {"dctw",		"o(b)",		0xbc090000, 0xfc1f0000, RD_2,			0,		I3,		0,	0 },
+@@ -1065,6 +1068,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ {"dmfc0",		"t,G,H",	0x40200000, 0xffe007f8,	WR_1|RD_C0|LC,		0,		I64,		0,	0 },
+ {"dmfgc0",		"t,G",		0x40600100, 0xffe007ff, WR_1|RD_C0|LC,		0,		0,		IVIRT64, 0 },
+ {"dmfgc0",		"t,G,H",	0x40600100, 0xffe007f8, WR_1|RD_C0|LC,		0,		0,		IVIRT64, 0 },
++{"dmfur",		"t,d",		0x7000001e, 0xffe007ff, WR_1,			0,		XLP,		0,	0 },
+ {"dmt",			"",		0x41600bc1, 0xffffffff, TRAP,			0,		0,		MT32,	0 },
+ {"dmt",			"t",		0x41600bc1, 0xffe0ffff, WR_1|TRAP,		0,		0,		MT32,	0 },
+ {"dmtc0",		"t,G",		0x40a00000, 0xffe007ff,	RD_1|WR_C0|WR_CC|CM,	0,		I3,		0,	EE },
+@@ -1079,6 +1083,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ /* dmtc2 is at the bottom of the table.  */
+ /* dmfc3 is at the bottom of the table.  */
+ /* dmtc3 is at the bottom of the table.  */
+ {"dmuh",		"d,s,t",	0x000000dc, 0xfc0007ff, WR_1|RD_2|RD_3,		0,		I69,		0,	0 },
++{"dmtur",		"t,d",		0x7000001f, 0xffe007ff,	RD_1,			0,		XLP,		0,	0 },
++{"dmul",		"d,s,t",	0x70000006, 0xfc0007ff,	WR_1|RD_2|RD_3,		0,		XLP,		0,	0 },
+ {"dmul",		"d,s,t",	0x0000009c, 0xfc0007ff, WR_1|RD_2|RD_3,		0,		I69,		0,	0 },
+ {"dmul",		"d,v,t",	0x70000003, 0xfc0007ff, WR_1|RD_2|RD_3|WR_HILO,	0,		IOCT,		0,	0 },
+@@ -1229,9 +1235,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ {"ld",			"s,-b(+R)",	0xec180000, 0xfc1c0000, WR_1,			RD_pc,		I69,		0,	0 },
+ {"ld",			"t,A(b)",	0,    (int) M_LD_AB,	INSN_MACRO,		0,		I1,		0,	0 },
+ {"ld",			"t,o(b)",	0xdc000000, 0xfc000000, WR_1|RD_3|LM,		0,		I3,		0,	0 },
+-{"ldaddw",		"t,b",		0x70000010, 0xfc00ffff,	MOD_1|RD_2|LM|SM,	0,		XLR,		0,	0 },
+-{"ldaddwu",		"t,b",		0x70000011, 0xfc00ffff,	MOD_1|RD_2|LM|SM,	0,		XLR,		0,	0 },
+-{"ldaddd",		"t,b",		0x70000012, 0xfc00ffff,	MOD_1|RD_2|LM|SM,	0,		XLR,		0,	0 },
++{"ldaddw",		"t,b",		0x70000010, 0xfc00ffff,	MOD_1|RD_2|SM,		0,		XLR|XLP,	0,	0 },
++{"ldaddwu",		"t,b",		0x70000011, 0xfc00ffff,	MOD_1|RD_2|SM,		0,		XLR|XLP,	0,	0 },
++{"ldaddd",		"t,b",		0x70000012, 0xfc00ffff,	MOD_1|RD_2|SM,		0,		XLR|XLP,	0,	0 },
+ {"ldc1",		"T,o(b)",	0xd4000000, 0xfc000000, WR_1|RD_3|CLD|FP_D,	0,		I2,		0,	SF },
+ {"ldc1",		"E,o(b)",	0xd4000000, 0xfc000000, WR_1|RD_3|CLD|FP_D,	0,		I2,		0,	SF },
+ {"ldc1",		"T,A(b)",	0,    (int) M_LDC1_AB,	INSN_MACRO,		INSN2_M_FP_D,	I2,		0,	SF },
+@@ -1396,7 +1402,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ {"mflo",		"d,9",		0x00000012, 0xff9f07ff, WR_1|RD_LO,		0,		0,		D32,	0 },
+ {"mflo1",		"d",		0x70000012, 0xffff07ff,	WR_1|RD_LO,		0,		EE,		0,	0 },
+ {"mflhxu",		"d",		0x00000052, 0xffff07ff,	WR_1|MOD_HILO,		0,		0,		SMT,	0 },
+-{"mfcr",		"t,s",		0x70000018, 0xfc00ffff, WR_1|RD_2,		0,		XLR,		0,	0 },
++{"mfcr",		"t,s",		0x70000018, 0xfc00ffff, WR_1,			0,		XLR|XLP,	0,	0 },
+ {"mfsa",		"d",		0x00000028, 0xffff07ff,	WR_1,			0,		EE,		0,	0 },
+ {"min.ob",		"X,Y,Q",	0x78000006, 0xfc20003f,	WR_1|RD_2|RD_3|FP_D,	0,		SB1,		MX,	0 },
+ {"min.ob",		"D,S,Q",	0x48000006, 0xfc20003f,	WR_1|RD_2|RD_3|FP_D,	0,		N54,		0,	0 },
+@@ -1441,10 +1447,13 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ /* move is at the top of the table.  */
+ {"msgn.qh",		"X,Y,Q",	0x78200000, 0xfc20003f,	WR_1|RD_2|RD_3|FP_D,	0,		0,		MX,	0 },
+ {"msgsnd",		"t",		0,    (int) M_MSGSND,	INSN_MACRO,		0,		XLR,		0,	0 },
++{"msgsnds",		"d,t",		0x4a000001, 0xffe007ff,	WR_1|RD_2|RD_C0|WR_C0,	0,		XLP,		0,	0 },
+ {"msgld",		"", 		0,    (int) M_MSGLD,	INSN_MACRO,		0,		XLR,		0,	0 },
+ {"msgld",		"t",		0,    (int) M_MSGLD_T,	INSN_MACRO,		0,		XLR,		0,	0 },
+-{"msgwait",		"", 		0,    (int) M_MSGWAIT,	INSN_MACRO,		0,		XLR,		0,	0 },
+-{"msgwait",		"t",		0,    (int) M_MSGWAIT_T,INSN_MACRO,		0,		XLR,		0,	0 },
++{"msglds",		"d,t",		0x4a000002, 0xffe007ff,	WR_1|RD_2|RD_C0|WR_C0,	0,		XLP,		0,	0 },
++{"msgwait",		"",		0,    (int) M_MSGWAIT,  INSN_MACRO,		0,		XLR|XLP,	0,	0 },
++{"msgwait",		"t",		0,    (int) M_MSGWAIT_T,INSN_MACRO,		0,		XLR|XLP,	0,	0 },
++{"msgsync",		"",		0x4a000004, 0xffffffff,0,			0,		XLP,		0,	0 },
+ {"msub.d",		"D,R,S,T",	0x4c000029, 0xfc00003f, WR_1|RD_2|RD_3|RD_4|FP_D, 0,		I4_33,		0,	I37 },
+ {"msub.d",		"D,S,T",	0x46200019, 0xffe0003f,	WR_1|RD_2|RD_3|FP_D,	0,		IL2E,		0,	0 },
+ {"msub.d",		"D,S,T",	0x72200019, 0xffe0003f,	WR_1|RD_2|RD_3|FP_D,	0,		IL2F,		0,	0 },
+@@ -1494,7 +1503,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ {"mtlo",		"s,7",		0x00000013, 0xfc1fe7ff, RD_1|WR_LO,		0,		0,		D32,	0 },
+ {"mtlo1",		"s",		0x70000013, 0xfc1fffff,	RD_1|WR_LO,		0,		EE,		0,	0 },
+ {"mtlhx",		"s",		0x00000053, 0xfc1fffff,	RD_1|MOD_HILO,		0,		0,		SMT,	0 },
+-{"mtcr",		"t,s",		0x70000019, 0xfc00ffff, RD_1|RD_2,		0,		XLR,		0,	0 },
++{"mtcr",		"t,s",		0x70000019, 0xfc00ffff, RD_1,			0,		XLR|XLP,	0,	0 },
+ {"mtm0",		"s",		0x70000008, 0xfc1fffff, RD_1,			0,		IOCT,		0,	0 },
+ {"mtm1",		"s",		0x7000000c, 0xfc1fffff, RD_1,			0,		IOCT,		0,	0 },
+ {"mtm2",		"s",		0x7000000d, 0xfc1fffff, RD_1,			0,		IOCT,		0,	0 },
+@@ -1924,9 +1933,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
+ {"suxc1",		"S,t(b)",	0x4c00000d, 0xfc0007ff, RD_1|RD_2|RD_3|SM|FP_D,	0,		I5_33|N55,	0,	I37},
+ {"sw",			"t,o(b)",	0xac000000, 0xfc000000,	RD_1|RD_3|SM,		0,		I1,		0,	0 },
+ {"sw",			"t,A(b)",	0,    (int) M_SW_AB,	INSN_MACRO,		0,		I1,		0,	0 },
+-{"swapw",		"t,b",		0x70000014, 0xfc00ffff, MOD_1|RD_2|LM|SM,	0,		XLR,		0,	0 },
+-{"swapwu",		"t,b",		0x70000015, 0xfc00ffff, MOD_1|RD_2|LM|SM,	0,		XLR,		0,	0 },
+-{"swapd",		"t,b",		0x70000016, 0xfc00ffff, MOD_1|RD_2|LM|SM,	0,		XLR,		0,	0 },
++{"swapw",		"t,b",		0x70000014, 0xfc00ffff, MOD_1|RD_2|SM,		0,		XLR|XLP,	0,	0 },
++{"swapwu",		"t,b",		0x70000015, 0xfc00ffff, MOD_1|RD_2|SM,		0,		XLR|XLP,	0,	0 },
++{"swapd",		"t,b",		0x70000016, 0xfc00ffff, MOD_1|RD_2|SM,		0,		XLR|XLP,	0,	0 },
+ {"swc0",		"E,o(b)",	0xe0000000, 0xfc000000,	RD_3|RD_C0|SM,		0,		I1,		0,	IOCT|IOCTP|IOCT2|I37 },
+ {"swc0",		"E,A(b)",	0,    (int) M_SWC0_AB,	INSN_MACRO,		0,		I1,		0,	IOCT|IOCTP|IOCT2|I37 },
+ {"swc1",		"T,o(b)",	0xe4000000, 0xfc000000,	RD_1|RD_3|SM|FP_S,	0,		I1,		0,	0 },
diff --git a/recipes-devtools/binutils/binutils/libiberty_path_fix.patch b/recipes-devtools/binutils/binutils/libiberty_path_fix.patch
new file mode 100644
index 0000000..6e732fb
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/libiberty_path_fix.patch
@@ -0,0 +1,22 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+don't let the distro compiler point to the wrong installation location
+
+Thanks to RP for helping find the source code causing the issue.
+
+2010/08/13
+Nitin A Kamble <nitin.a.kamble@intel.com>
+Index: binutils-2.22/libiberty/Makefile.in
+===================================================================
+--- binutils-2.22.orig/libiberty/Makefile.in
++++ binutils-2.22/libiberty/Makefile.in
+@@ -350,7 +350,8 @@ install-strip: install
+ # multilib-specific flags, it's overridden by FLAGS_TO_PASS from the
+ # default multilib, so we have to take CFLAGS into account as well,
+ # since it will be passed the multilib flags.
+-MULTIOSDIR = `$(CC) $(CFLAGS) -print-multi-os-directory`
++#MULTIOSDIR = `$(CC) $(CFLAGS) -print-multi-os-directory`
++MULTIOSDIR = ""
+ install_to_libdir: all
+ 	${mkinstalldirs} $(DESTDIR)$(libdir)/$(MULTIOSDIR)
+ 	$(INSTALL_DATA) $(TARGETLIB) $(DESTDIR)$(libdir)/$(MULTIOSDIR)/$(TARGETLIB)n
diff --git a/recipes-devtools/binutils/binutils/libtool-2.4-update.patch b/recipes-devtools/binutils/binutils/libtool-2.4-update.patch
new file mode 100644
index 0000000..9aaecd9
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/libtool-2.4-update.patch
@@ -0,0 +1,19322 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+Index: binutils-2.24/libtool.m4
+===================================================================
+--- binutils-2.24.orig/libtool.m4	2013-11-04 07:33:40.000000000 -0800
++++ binutils-2.24/libtool.m4	2013-12-15 11:10:23.863785363 -0800
+@@ -1,7 +1,8 @@
+ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+ #
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ # This file is free software; the Free Software Foundation gives
+@@ -10,7 +11,8 @@
+ 
+ m4_define([_LT_COPYING], [dnl
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ #   This file is part of GNU Libtool.
+@@ -37,7 +39,7 @@
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ])
+ 
+-# serial 56 LT_INIT
++# serial 57 LT_INIT
+ 
+ 
+ # LT_PREREQ(VERSION)
+@@ -92,7 +94,8 @@
+ LIBTOOL_DEPS="$ltmain"
+ 
+ # Always use our own libtool.
+-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++LIBTOOL='$(SHELL) $(top_builddir)'
++LIBTOOL="$LIBTOOL/${host_alias}-libtool"
+ AC_SUBST(LIBTOOL)dnl
+ 
+ _LT_SETUP
+@@ -166,10 +169,13 @@
+ dnl
+ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+ m4_require([_LT_CHECK_SHELL_FEATURES])dnl
++m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+ m4_require([_LT_CMD_RELOAD])dnl
+ m4_require([_LT_CHECK_MAGIC_METHOD])dnl
++m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+ m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+ m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
++m4_require([_LT_WITH_SYSROOT])dnl
+ 
+ _LT_CONFIG_LIBTOOL_INIT([
+ # See if we are running on zsh, and set the options which allow our
+@@ -199,7 +205,7 @@
+ esac
+ 
+ # Global variables:
+-ofile=libtool
++ofile=${host_alias}-libtool
+ can_build_shared=yes
+ 
+ # All known linkers require a `.a' archive for static linking (except MSVC,
+@@ -632,7 +638,7 @@
+ m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+ configured by $[0], generated by m4_PACKAGE_STRING.
+ 
+-Copyright (C) 2009 Free Software Foundation, Inc.
++Copyright (C) 2010 Free Software Foundation, Inc.
+ This config.lt script is free software; the Free Software Foundation
+ gives unlimited permision to copy, distribute and modify it."
+ 
+@@ -746,15 +752,12 @@
+   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+   # text mode, it properly converts lines to CR/LF.  This bash problem
+   # is reportedly fixed, but why not run on old versions too?
+-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
++  sed '$q' "$ltmain" >> "$cfgfile" \
++     || (rm -f "$cfgfile"; exit 1)
+ 
+-  _LT_PROG_XSI_SHELLFNS
++  _LT_PROG_REPLACE_SHELLFNS
+ 
+-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  mv -f "$cfgfile" "$ofile" ||
++   mv -f "$cfgfile" "$ofile" ||
+     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+   chmod +x "$ofile"
+ ],
+@@ -980,6 +983,8 @@
+       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+       echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+       $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
++      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
++      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+       cat > conftest.c << _LT_EOF
+ int main() { return 0;}
+ _LT_EOF
+@@ -1069,30 +1074,41 @@
+   fi
+ ])
+ 
+-# _LT_SYS_MODULE_PATH_AIX
+-# -----------------------
++# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
++# ----------------------------------
+ # Links a minimal program and checks the executable
+ # for the system default hardcoded library path. In most cases,
+ # this is /usr/lib:/lib, but when the MPI compilers are used
+ # the location of the communication and MPI libs are included too.
+ # If we don't find anything, use the default library path according
+ # to the aix ld manual.
++# Store the results from the different compilers for each TAGNAME.
++# Allow to override them for all tags through lt_cv_aix_libpath.
+ m4_defun([_LT_SYS_MODULE_PATH_AIX],
+ [m4_require([_LT_DECL_SED])dnl
+-AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi],[])
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
++  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
++  lt_aix_libpath_sed='[
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }]'
++  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
++    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi],[])
++  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
++    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
++  fi
++  ])
++  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
++fi
+ ])# _LT_SYS_MODULE_PATH_AIX
+ 
+ 
+@@ -1117,7 +1133,7 @@
+ 
+ AC_MSG_CHECKING([how to print strings])
+ # Test print first, because it will be a builtin if present.
+-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+    test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+   ECHO='print -r --'
+ elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+@@ -1161,6 +1177,39 @@
+ ])# _LT_PROG_ECHO_BACKSLASH
+ 
+ 
++# _LT_WITH_SYSROOT
++# ----------------
++AC_DEFUN([_LT_WITH_SYSROOT],
++[AC_MSG_CHECKING([for sysroot])
++AC_ARG_WITH([libtool-sysroot],
++[  --with-libtool-sysroot[=DIR] Search for dependent libraries within DIR
++                        (or the compiler's sysroot if not specified).],
++[], [with_libtool_sysroot=no])
++
++dnl lt_sysroot will always be passed unquoted.  We quote it here
++dnl in case the user passed a directory name.
++lt_sysroot=
++case ${with_libtool_sysroot} in #(
++ yes)
++   if test "$GCC" = yes; then
++     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
++   fi
++   ;; #(
++ /*)
++   lt_sysroot=`echo "$with_libtool_sysroot" | sed -e "$sed_quote_subst"`
++   ;; #(
++ no|'')
++   ;; #(
++ *)
++   AC_MSG_RESULT([${with_libtool_sysroot}])
++   AC_MSG_ERROR([The sysroot must be an absolute path.])
++   ;;
++esac
++
++ AC_MSG_RESULT([${lt_sysroot:-no}])
++_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
++[dependent libraries, and in which our libraries should be installed.])])
++
+ # _LT_ENABLE_LOCK
+ # ---------------
+ m4_defun([_LT_ENABLE_LOCK],
+@@ -1320,14 +1369,47 @@
+ ])# _LT_ENABLE_LOCK
+ 
+ 
++# _LT_PROG_AR
++# -----------
++m4_defun([_LT_PROG_AR],
++[AC_CHECK_TOOLS(AR, [ar], false)
++: ${AR=ar}
++: ${AR_FLAGS=cru}
++_LT_DECL([], [AR], [1], [The archiver])
++_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
++
++AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
++  [lt_cv_ar_at_file=no
++   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
++     [echo conftest.$ac_objext > conftest.lst
++      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
++      AC_TRY_EVAL([lt_ar_try])
++      if test "$ac_status" -eq 0; then
++	# Ensure the archiver fails upon bogus file names.
++	rm -f conftest.$ac_objext libconftest.a
++	AC_TRY_EVAL([lt_ar_try])
++	if test "$ac_status" -ne 0; then
++          lt_cv_ar_at_file=@
++        fi
++      fi
++      rm -f conftest.* libconftest.a
++     ])
++  ])
++
++if test "x$lt_cv_ar_at_file" = xno; then
++  archiver_list_spec=
++else
++  archiver_list_spec=$lt_cv_ar_at_file
++fi
++_LT_DECL([], [archiver_list_spec], [1],
++  [How to feed a file listing to the archiver])
++])# _LT_PROG_AR
++
++
+ # _LT_CMD_OLD_ARCHIVE
+ # -------------------
+ m4_defun([_LT_CMD_OLD_ARCHIVE],
+-[AC_CHECK_TOOL(AR, ar, false)
+-test -z "$AR" && AR=ar
+-test -z "$AR_FLAGS" && AR_FLAGS=cru
+-_LT_DECL([], [AR], [1], [The archiver])
+-_LT_DECL([], [AR_FLAGS], [1])
++[_LT_PROG_AR
+ 
+ AC_CHECK_TOOL(STRIP, strip, :)
+ test -z "$STRIP" && STRIP=:
+@@ -1623,7 +1705,7 @@
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-[#line __oline__ "configure"
++[#line $LINENO "configure"
+ #include "confdefs.h"
+ 
+ #if HAVE_DLFCN_H
+@@ -1667,10 +1749,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -2210,8 +2292,9 @@
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -2244,13 +2327,71 @@
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -2342,7 +2483,7 @@
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -2950,6 +3091,11 @@
+ esac
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ case $host_os in
++  cygwin* | mingw* | pw32* | cegcc*)
++    if test "$GCC" != yes; then
++      reload_cmds=false
++    fi
++    ;;
+   darwin*)
+     if test "$GCC" = yes; then
+       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+@@ -3016,7 +3162,8 @@
+     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+     lt_cv_file_magic_cmd='func_win32_libid'
+   else
+-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++    # Keep this pattern in sync with the one in func_win32_libid.
++    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+     lt_cv_file_magic_cmd='$OBJDUMP -f'
+   fi
+   ;;
+@@ -3167,6 +3314,21 @@
+   ;;
+ esac
+ ])
++
++file_magic_glob=
++want_nocaseglob=no
++if test "$build" = "$host"; then
++  case $host_os in
++  mingw* | pw32*)
++    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
++      want_nocaseglob=yes
++    else
++      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
++    fi
++    ;;
++  esac
++fi
++
+ file_magic_cmd=$lt_cv_file_magic_cmd
+ deplibs_check_method=$lt_cv_deplibs_check_method
+ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+@@ -3174,7 +3336,11 @@
+ _LT_DECL([], [deplibs_check_method], [1],
+     [Method to check whether dependent libraries are shared objects])
+ _LT_DECL([], [file_magic_cmd], [1],
+-    [Command to use when deplibs_check_method == "file_magic"])
++    [Command to use when deplibs_check_method = "file_magic"])
++_LT_DECL([], [file_magic_glob], [1],
++    [How to find potential files when deplibs_check_method = "file_magic"])
++_LT_DECL([], [want_nocaseglob], [1],
++    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+ ])# _LT_CHECK_MAGIC_METHOD
+ 
+ 
+@@ -3277,6 +3443,67 @@
+ dnl AC_DEFUN([AM_PROG_NM], [])
+ dnl AC_DEFUN([AC_PROG_NM], [])
+ 
++# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
++# --------------------------------
++# how to determine the name of the shared library
++# associated with a specific link library.
++#  -- PORTME fill in with the dynamic library characteristics
++m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
++[m4_require([_LT_DECL_EGREP])
++m4_require([_LT_DECL_OBJDUMP])
++m4_require([_LT_DECL_DLLTOOL])
++AC_CACHE_CHECK([how to associate runtime and link libraries],
++lt_cv_sharedlib_from_linklib_cmd,
++[lt_cv_sharedlib_from_linklib_cmd='unknown'
++
++case $host_os in
++cygwin* | mingw* | pw32* | cegcc*)
++  # two different shell functions defined in ltmain.sh
++  # decide which to use based on capabilities of $DLLTOOL
++  case `$DLLTOOL --help 2>&1` in
++  *--identify-strict*)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
++    ;;
++  *)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
++    ;;
++  esac
++  ;;
++*)
++  # fallback: assume linklib IS sharedlib
++  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
++  ;;
++esac
++])
++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
++
++_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
++    [Command to associate shared and link libraries])
++])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
++
++
++# _LT_PATH_MANIFEST_TOOL
++# ----------------------
++# locate the manifest tool
++m4_defun([_LT_PATH_MANIFEST_TOOL],
++[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
++AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
++  [lt_cv_path_mainfest_tool=no
++  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
++  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
++  cat conftest.err >&AS_MESSAGE_LOG_FD
++  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
++    lt_cv_path_mainfest_tool=yes
++  fi
++  rm -f conftest*])
++if test "x$lt_cv_path_mainfest_tool" != xyes; then
++  MANIFEST_TOOL=:
++fi
++_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
++])# _LT_PATH_MANIFEST_TOOL
++
+ 
+ # LT_LIB_M
+ # --------
+@@ -3403,8 +3630,8 @@
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ 
+ # Transform an extracted symbol line into symbol name and symbol address
+-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+ 
+ # Handle CRLF in mingw tool chain
+ opt_cr=
+@@ -3440,6 +3667,7 @@
+   else
+     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+   fi
++  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+ 
+   # Check to see that the pipe works correctly.
+   pipe_works=no
+@@ -3473,6 +3701,18 @@
+       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ 	  cat <<_LT_EOF > conftest.$ac_ext
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT@&t@_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT@&t@_DLSYM_CONST
++#else
++# define LT@&t@_DLSYM_CONST const
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -3484,7 +3724,7 @@
+ 	  cat <<_LT_EOF >> conftest.$ac_ext
+ 
+ /* The mapping between symbol names and symbols.  */
+-const struct {
++LT@&t@_DLSYM_CONST struct {
+   const char *name;
+   void       *address;
+ }
+@@ -3510,15 +3750,15 @@
+ _LT_EOF
+ 	  # Now try linking the two files.
+ 	  mv conftest.$ac_objext conftstm.$ac_objext
+-	  lt_save_LIBS="$LIBS"
+-	  lt_save_CFLAGS="$CFLAGS"
++	  lt_globsym_save_LIBS=$LIBS
++	  lt_globsym_save_CFLAGS=$CFLAGS
+ 	  LIBS="conftstm.$ac_objext"
+ 	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ 	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ 	    pipe_works=yes
+ 	  fi
+-	  LIBS="$lt_save_LIBS"
+-	  CFLAGS="$lt_save_CFLAGS"
++	  LIBS=$lt_globsym_save_LIBS
++	  CFLAGS=$lt_globsym_save_CFLAGS
+ 	else
+ 	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ 	fi
+@@ -3551,6 +3791,13 @@
+   AC_MSG_RESULT(ok)
+ fi
+ 
++# Response file support.
++if test "$lt_cv_nm_interface" = "MS dumpbin"; then
++  nm_file_list_spec='@'
++elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
++  nm_file_list_spec='@'
++fi
++
+ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+     [Take the output of nm and produce a listing of raw symbols and C names])
+ _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+@@ -3561,6 +3808,8 @@
+ _LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+     [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+     [Transform the output of nm in a C name address pair when lib prefix is needed])
++_LT_DECL([], [nm_file_list_spec], [1],
++    [Specify filename containing input files for $NM])
+ ]) # _LT_CMD_GLOBAL_SYMBOLS
+ 
+ 
+@@ -3572,7 +3821,6 @@
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ 
+-AC_MSG_CHECKING([for $compiler option to produce PIC])
+ m4_if([$1], [CXX], [
+   # C++ specific cases for pic, static, wl, etc.
+   if test "$GXX" = yes; then
+@@ -3678,6 +3926,12 @@
+ 	  ;;
+ 	esac
+ 	;;
++      mingw* | cygwin* | os2* | pw32* | cegcc*)
++	# This hack is so that the source file can tell whether it is being
++	# built for inclusion in a dll (and should export symbols for example).
++	m4_if([$1], [GCJ], [],
++	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
++	;;
+       dgux*)
+ 	case $cc_basename in
+ 	  ec++*)
+@@ -3830,7 +4084,7 @@
+ 	;;
+       solaris*)
+ 	case $cc_basename in
+-	  CC*)
++	  CC* | sunCC*)
+ 	    # Sun C++ 4.2, 5.x and Centerline C++
+ 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ 	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+@@ -4053,6 +4307,12 @@
+ 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ 	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ 	;;
++      nagfor*)
++	# NAG Fortran compiler
++	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
++	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
++	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
++	;;
+       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+         # Portland Group compilers (*not* the Pentium gcc compiler,
+ 	# which looks to be a dead project)
+@@ -4115,7 +4375,7 @@
+       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+       _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+       case $cc_basename in
+-      f77* | f90* | f95*)
++      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+       *)
+ 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+@@ -4172,9 +4432,11 @@
+     _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+     ;;
+ esac
+-AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+-_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+-	[How to pass a linker flag through the compiler])
++
++AC_CACHE_CHECK([for $compiler option to produce PIC],
++  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
++  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
++_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -4193,6 +4455,8 @@
+ _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ 	[Additional compiler flags for building library objects])
+ 
++_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
++	[How to pass a linker flag through the compiler])
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -4213,6 +4477,7 @@
+ m4_defun([_LT_LINKER_SHLIBS],
+ [AC_REQUIRE([LT_PATH_LD])dnl
+ AC_REQUIRE([LT_PATH_NM])dnl
++m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+ m4_require([_LT_DECL_EGREP])dnl
+ m4_require([_LT_DECL_SED])dnl
+@@ -4221,6 +4486,7 @@
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ m4_if([$1], [CXX], [
+   _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
++  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+   case $host_os in
+   aix[[4-9]]*)
+     # If we're using GNU nm, then we don't want the "-C" option.
+@@ -4235,15 +4501,20 @@
+     ;;
+   pw32*)
+     _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+-  ;;
++    ;;
+   cygwin* | mingw* | cegcc*)
+-    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+-  ;;
++    case $cc_basename in
++    cl*) ;;
++    *)
++      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
++      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
++      ;;
++    esac
++    ;;
+   *)
+     _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+-  ;;
++    ;;
+   esac
+-  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ ], [
+   runpath_var=
+   _LT_TAGVAR(allow_undefined_flag, $1)=
+@@ -4411,7 +4682,8 @@
+       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+       _LT_TAGVAR(always_export_symbols, $1)=no
+       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
++      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
++      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ 
+       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+@@ -4459,7 +4731,7 @@
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -4510,12 +4782,12 @@
+ 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ 	  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+-	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
++	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ 	  if test "x$supports_anon_versioning" = xyes; then
+ 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ 	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ 	      echo "local: *; };" >> $output_objdir/$libname.ver~
+-	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
++	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ 	  fi
+ 	  ;;
+ 	esac
+@@ -4529,8 +4801,8 @@
+ 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ 	wlarc=
+       else
+-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       fi
+       ;;
+ 
+@@ -4548,8 +4820,8 @@
+ 
+ _LT_EOF
+       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	_LT_TAGVAR(ld_shlibs, $1)=no
+       fi
+@@ -4595,8 +4867,8 @@
+ 
+     *)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	_LT_TAGVAR(ld_shlibs, $1)=no
+       fi
+@@ -4726,7 +4998,7 @@
+ 	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+         # Determine the default libpath from the value encoded in an
+         # empty executable.
+-        _LT_SYS_MODULE_PATH_AIX
++        _LT_SYS_MODULE_PATH_AIX([$1])
+         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+         _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+@@ -4737,7 +5009,7 @@
+ 	else
+ 	 # Determine the default libpath from the value encoded in an
+ 	 # empty executable.
+-	 _LT_SYS_MODULE_PATH_AIX
++	 _LT_SYS_MODULE_PATH_AIX([$1])
+ 	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	  # Warning - without using the other run time loading flags,
+ 	  # -berok will link without error, but may produce a broken library.
+@@ -4781,20 +5053,63 @@
+       # Microsoft Visual C++.
+       # hardcode_libdir_flag_spec is actually meaningless, as there is
+       # no search path for DLLs.
+-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+-      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+-      # Tell ltmain to make .lib files, not .a files.
+-      libext=lib
+-      # Tell ltmain to make .dll files, not .so files.
+-      shrext_cmds=".dll"
+-      # FIXME: Setting linknames here is a bad hack.
+-      _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+-      # The linker will automatically build a .lib file if we build a DLL.
+-      _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+-      # FIXME: Should let the user specify the lib program.
+-      _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+-      _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
++      case $cc_basename in
++      cl*)
++	# Native MSVC
++	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
++	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
++	_LT_TAGVAR(always_export_symbols, $1)=yes
++	_LT_TAGVAR(file_list_spec, $1)='@'
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	  else
++	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	  fi~
++	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	  linknames='
++	# The linker will not automatically build a static lib if we build a DLL.
++	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
++	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
++	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
++	# Don't use ranlib
++	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
++	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
++	  lt_tool_outputfile="@TOOL_OUTPUT@"~
++	  case $lt_outputfile in
++	    *.exe|*.EXE) ;;
++	    *)
++	      lt_outputfile="$lt_outputfile.exe"
++	      lt_tool_outputfile="$lt_tool_outputfile.exe"
++	      ;;
++	  esac~
++	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	    $RM "$lt_outputfile.manifest";
++	  fi'
++	;;
++      *)
++	# Assume MSVC wrapper
++	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
++	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
++	# The linker will automatically build a .lib file if we build a DLL.
++	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
++	# FIXME: Should let the user specify the lib program.
++	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
++	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
++	;;
++      esac
+       ;;
+ 
+     darwin* | rhapsody*)
+@@ -4828,7 +5143,7 @@
+ 
+     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+     freebsd* | dragonfly*)
+-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+       _LT_TAGVAR(hardcode_direct, $1)=yes
+       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+@@ -4836,7 +5151,7 @@
+ 
+     hpux9*)
+       if test "$GCC" = yes; then
+-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       else
+ 	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       fi
+@@ -4852,7 +5167,7 @@
+ 
+     hpux10*)
+       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       else
+ 	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+       fi
+@@ -4876,10 +5191,10 @@
+ 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	ia64*)
+-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
++	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	*)
+-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	esac
+       else
+@@ -4926,16 +5241,31 @@
+ 
+     irix5* | irix6* | nonstopux*)
+       if test "$GCC" = yes; then
+-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	# Try to use the -exported_symbol ld option, if it does not
+ 	# work, assume that -exports_file does not work either and
+ 	# implicitly export all symbols.
+-        save_LDFLAGS="$LDFLAGS"
+-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+-        AC_LINK_IFELSE(int foo(void) {},
+-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+-        )
+-        LDFLAGS="$save_LDFLAGS"
++	# This should be the same for all languages, so no per-tag cache variable.
++	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
++	  [lt_cv_irix_exported_symbol],
++	  [save_LDFLAGS="$LDFLAGS"
++	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
++	   AC_LINK_IFELSE(
++	     [AC_LANG_SOURCE(
++	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
++			      [C++], [[int foo (void) { return 0; }]],
++			      [Fortran 77], [[
++      subroutine foo
++      end]],
++			      [Fortran], [[
++      subroutine foo
++      end]])])],
++	      [lt_cv_irix_exported_symbol=yes],
++	      [lt_cv_irix_exported_symbol=no])
++           LDFLAGS="$save_LDFLAGS"])
++	if test "$lt_cv_irix_exported_symbol" = yes; then
++          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
++	fi
+       else
+ 	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ 	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+@@ -5020,7 +5350,7 @@
+     osf4* | osf5*)	# as osf3* with the addition of -msym flag
+       if test "$GCC" = yes; then
+ 	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+       else
+ 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+@@ -5039,9 +5369,9 @@
+       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+       if test "$GCC" = yes; then
+ 	wlarc='${wl}'
+-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
++	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+       else
+ 	case `$CC -V 2>&1` in
+ 	*"Compilers 5.0"*)
+@@ -5313,8 +5643,6 @@
+     to runtime path list])
+ _LT_TAGDECL([], [link_all_deplibs], [0],
+     [Whether libtool must link a program against all its dependency libraries])
+-_LT_TAGDECL([], [fix_srcfile_path], [1],
+-    [Fix the shell variable $srcfile for the compiler])
+ _LT_TAGDECL([], [always_export_symbols], [0],
+     [Set to "yes" if exported symbols are required])
+ _LT_TAGDECL([], [export_symbols_cmds], [2],
+@@ -5325,6 +5653,8 @@
+     [Symbols that must always be exported])
+ _LT_TAGDECL([], [prelink_cmds], [2],
+     [Commands necessary for linking programs (against libraries) with templates])
++_LT_TAGDECL([], [postlink_cmds], [2],
++    [Commands necessary for finishing linking programs])
+ _LT_TAGDECL([], [file_list_spec], [1],
+     [Specify filename containing input files])
+ dnl FIXME: Not yet implemented
+@@ -5426,6 +5756,7 @@
+ m4_defun([_LT_LANG_CXX_CONFIG],
+ [m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+ m4_require([_LT_DECL_EGREP])dnl
++m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+ if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+     ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+     (test "X$CXX" != "Xg++"))) ; then
+@@ -5487,6 +5818,7 @@
+ 
+   # Allow CC to be a program name with arguments.
+   lt_save_CC=$CC
++  lt_save_CFLAGS=$CFLAGS
+   lt_save_LD=$LD
+   lt_save_GCC=$GCC
+   GCC=$GXX
+@@ -5504,6 +5836,7 @@
+   fi
+   test -z "${LDCXX+set}" || LD=$LDCXX
+   CC=${CXX-"c++"}
++  CFLAGS=$CXXFLAGS
+   compiler=$CC
+   _LT_TAGVAR(compiler, $1)=$CC
+   _LT_CC_BASENAME([$compiler])
+@@ -5525,8 +5858,8 @@
+       # Check if GNU C++ uses GNU ld as the underlying linker, since the
+       # archiving commands below assume that GNU ld is being used.
+       if test "$with_gnu_ld" = yes; then
+-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
++        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ 
+         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+@@ -5667,7 +6000,7 @@
+           _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+           # Determine the default libpath from the value encoded in an empty
+           # executable.
+-          _LT_SYS_MODULE_PATH_AIX
++          _LT_SYS_MODULE_PATH_AIX([$1])
+           _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 
+           _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+@@ -5679,7 +6012,7 @@
+           else
+ 	    # Determine the default libpath from the value encoded in an
+ 	    # empty executable.
+-	    _LT_SYS_MODULE_PATH_AIX
++	    _LT_SYS_MODULE_PATH_AIX([$1])
+ 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	    # Warning - without using the other run time loading flags,
+ 	    # -berok will link without error, but may produce a broken library.
+@@ -5721,29 +6054,75 @@
+         ;;
+ 
+       cygwin* | mingw* | pw32* | cegcc*)
+-        # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+-        # as there is no search path for DLLs.
+-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+-        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+-        _LT_TAGVAR(always_export_symbols, $1)=no
+-        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+-
+-        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+-          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+-          # If the export-symbols file already is a .def file (1st line
+-          # is EXPORTS), use it as is; otherwise, prepend...
+-          _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+-	    cp $export_symbols $output_objdir/$soname.def;
+-          else
+-	    echo EXPORTS > $output_objdir/$soname.def;
+-	    cat $export_symbols >> $output_objdir/$soname.def;
+-          fi~
+-          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+-        else
+-          _LT_TAGVAR(ld_shlibs, $1)=no
+-        fi
+-        ;;
++	case $GXX,$cc_basename in
++	,cl* | no,cl*)
++	  # Native MSVC
++	  # hardcode_libdir_flag_spec is actually meaningless, as there is
++	  # no search path for DLLs.
++	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
++	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
++	  _LT_TAGVAR(always_export_symbols, $1)=yes
++	  _LT_TAGVAR(file_list_spec, $1)='@'
++	  # Tell ltmain to make .lib files, not .a files.
++	  libext=lib
++	  # Tell ltmain to make .dll files, not .so files.
++	  shrext_cmds=".dll"
++	  # FIXME: Setting linknames here is a bad hack.
++	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	    else
++	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	    fi~
++	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	    linknames='
++	  # The linker will not automatically build a static lib if we build a DLL.
++	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
++	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
++	  # Don't use ranlib
++	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
++	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
++	    lt_tool_outputfile="@TOOL_OUTPUT@"~
++	    case $lt_outputfile in
++	      *.exe|*.EXE) ;;
++	      *)
++		lt_outputfile="$lt_outputfile.exe"
++		lt_tool_outputfile="$lt_tool_outputfile.exe"
++		;;
++	    esac~
++	    func_to_tool_file "$lt_outputfile"~
++	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	      $RM "$lt_outputfile.manifest";
++	    fi'
++	  ;;
++	*)
++	  # g++
++	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
++	  # as there is no search path for DLLs.
++	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
++	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
++	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
++	  _LT_TAGVAR(always_export_symbols, $1)=no
++	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
++
++	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
++	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
++	    # If the export-symbols file already is a .def file (1st line
++	    # is EXPORTS), use it as is; otherwise, prepend...
++	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	      cp $export_symbols $output_objdir/$soname.def;
++	    else
++	      echo EXPORTS > $output_objdir/$soname.def;
++	      cat $export_symbols >> $output_objdir/$soname.def;
++	    fi~
++	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
++	  else
++	    _LT_TAGVAR(ld_shlibs, $1)=no
++	  fi
++	  ;;
++	esac
++	;;
+       darwin* | rhapsody*)
+         _LT_DARWIN_LINKER_FEATURES($1)
+ 	;;
+@@ -5818,7 +6197,7 @@
+             ;;
+           *)
+             if test "$GXX" = yes; then
+-              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+             else
+               # FIXME: insert proper C++ library support
+               _LT_TAGVAR(ld_shlibs, $1)=no
+@@ -5889,10 +6268,10 @@
+ 	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ 	            ;;
+ 	          ia64*)
+-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
++	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ 	            ;;
+ 	          *)
+-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
++	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ 	            ;;
+ 	        esac
+ 	      fi
+@@ -5933,9 +6312,9 @@
+           *)
+ 	    if test "$GXX" = yes; then
+ 	      if test "$with_gnu_ld" = no; then
+-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	      else
+-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
++	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ 	      fi
+ 	    fi
+ 	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+@@ -6005,20 +6384,20 @@
+ 	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+-		compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
++		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ 	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+-		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
++		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ 		$RANLIB $oldlib'
+ 	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+-		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
++		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ 	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+-		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
++		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ 	      ;;
+ 	    *) # Version 6 and above use weak symbols
+ 	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+@@ -6213,7 +6592,7 @@
+ 	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 		  ;;
+ 	        *)
+-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 		  ;;
+ 	      esac
+ 
+@@ -6259,7 +6638,7 @@
+ 
+       solaris*)
+         case $cc_basename in
+-          CC*)
++          CC* | sunCC*)
+ 	    # Sun C++ 4.2, 5.x and Centerline C++
+             _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ 	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+@@ -6300,9 +6679,9 @@
+ 	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ 	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
++	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-		  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
++		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ 
+ 	        # Commands to make compiler produce verbose output that lists
+ 	        # what "hidden" libraries, object files and flags are used when
+@@ -6431,6 +6810,7 @@
+   fi # test -n "$compiler"
+ 
+   CC=$lt_save_CC
++  CFLAGS=$lt_save_CFLAGS
+   LDCXX=$LD
+   LD=$lt_save_LD
+   GCC=$lt_save_GCC
+@@ -6445,6 +6825,29 @@
+ ])# _LT_LANG_CXX_CONFIG
+ 
+ 
++# _LT_FUNC_STRIPNAME_CNF
++# ----------------------
++# func_stripname_cnf prefix suffix name
++# strip PREFIX and SUFFIX off of NAME.
++# PREFIX and SUFFIX must not contain globbing or regex special
++# characters, hashes, percent signs, but SUFFIX may contain a leading
++# dot (in which case that matches only a dot).
++#
++# This function is identical to the (non-XSI) version of func_stripname,
++# except this one can be used by m4 code that may be executed by configure,
++# rather than the libtool script.
++m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
++AC_REQUIRE([_LT_DECL_SED])
++AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
++func_stripname_cnf ()
++{
++  case ${2} in
++  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
++  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
++  esac
++} # func_stripname_cnf
++])# _LT_FUNC_STRIPNAME_CNF
++
+ # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+ # ---------------------------------
+ # Figure out "hidden" library dependencies from verbose
+@@ -6453,6 +6856,7 @@
+ # objects, libraries and library flags.
+ m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+ [m4_require([_LT_FILEUTILS_DEFAULTS])dnl
++AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+ # Dependencies to place before and after the object being linked:
+ _LT_TAGVAR(predep_objects, $1)=
+ _LT_TAGVAR(postdep_objects, $1)=
+@@ -6503,6 +6907,13 @@
+ };
+ _LT_EOF
+ ])
++
++_lt_libdeps_save_CFLAGS=$CFLAGS
++case "$CC $CFLAGS " in #(
++*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
++*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
++esac
++
+ dnl Parse the compiler output and extract the necessary
+ dnl objects, libraries and library flags.
+ if AC_TRY_EVAL(ac_compile); then
+@@ -6514,7 +6925,7 @@
+   pre_test_object_deps_done=no
+ 
+   for p in `eval "$output_verbose_link_cmd"`; do
+-    case $p in
++    case ${prev}${p} in
+ 
+     -L* | -R* | -l*)
+        # Some compilers place space between "-{L,R}" and the path.
+@@ -6523,13 +6934,22 @@
+           test $p = "-R"; then
+ 	 prev=$p
+ 	 continue
+-       else
+-	 prev=
+        fi
+ 
++       # Expand the sysroot to ease extracting the directories later.
++       if test -z "$prev"; then
++         case $p in
++         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
++         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
++         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
++         esac
++       fi
++       case $p in
++       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
++       esac
+        if test "$pre_test_object_deps_done" = no; then
+-	 case $p in
+-	 -L* | -R*)
++	 case ${prev} in
++	 -L | -R)
+ 	   # Internal compiler library paths should come after those
+ 	   # provided the user.  The postdeps already come after the
+ 	   # user supplied libs so there is no need to process them.
+@@ -6549,8 +6969,10 @@
+ 	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ 	 fi
+        fi
++       prev=
+        ;;
+ 
++    *.lto.$objext) ;; # Ignore GCC LTO objects
+     *.$objext)
+        # This assumes that the test object file only shows up
+        # once in the compiler output.
+@@ -6586,6 +7008,7 @@
+ fi
+ 
+ $RM -f confest.$objext
++CFLAGS=$_lt_libdeps_save_CFLAGS
+ 
+ # PORTME: override above test on systems where it is broken
+ m4_if([$1], [CXX],
+@@ -6622,7 +7045,7 @@
+ 
+ solaris*)
+   case $cc_basename in
+-  CC*)
++  CC* | sunCC*)
+     # The more standards-conforming stlport4 library is
+     # incompatible with the Cstd library. Avoid specifying
+     # it if it's in CXXFLAGS. Ignore libCrun as
+@@ -6735,7 +7158,9 @@
+   # Allow CC to be a program name with arguments.
+   lt_save_CC="$CC"
+   lt_save_GCC=$GCC
++  lt_save_CFLAGS=$CFLAGS
+   CC=${F77-"f77"}
++  CFLAGS=$FFLAGS
+   compiler=$CC
+   _LT_TAGVAR(compiler, $1)=$CC
+   _LT_CC_BASENAME([$compiler])
+@@ -6789,6 +7214,7 @@
+ 
+   GCC=$lt_save_GCC
+   CC="$lt_save_CC"
++  CFLAGS="$lt_save_CFLAGS"
+ fi # test "$_lt_disable_F77" != yes
+ 
+ AC_LANG_POP
+@@ -6865,7 +7291,9 @@
+   # Allow CC to be a program name with arguments.
+   lt_save_CC="$CC"
+   lt_save_GCC=$GCC
++  lt_save_CFLAGS=$CFLAGS
+   CC=${FC-"f95"}
++  CFLAGS=$FCFLAGS
+   compiler=$CC
+   GCC=$ac_cv_fc_compiler_gnu
+ 
+@@ -6921,7 +7349,8 @@
+   fi # test -n "$compiler"
+ 
+   GCC=$lt_save_GCC
+-  CC="$lt_save_CC"
++  CC=$lt_save_CC
++  CFLAGS=$lt_save_CFLAGS
+ fi # test "$_lt_disable_FC" != yes
+ 
+ AC_LANG_POP
+@@ -6958,10 +7387,12 @@
+ _LT_LINKER_BOILERPLATE
+ 
+ # Allow CC to be a program name with arguments.
+-lt_save_CC="$CC"
++lt_save_CC=$CC
++lt_save_CFLAGS=$CFLAGS
+ lt_save_GCC=$GCC
+ GCC=yes
+ CC=${GCJ-"gcj"}
++CFLAGS=$GCJFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_TAGVAR(LD, $1)="$LD"
+@@ -6992,7 +7423,8 @@
+ AC_LANG_RESTORE
+ 
+ GCC=$lt_save_GCC
+-CC="$lt_save_CC"
++CC=$lt_save_CC
++CFLAGS=$lt_save_CFLAGS
+ ])# _LT_LANG_GCJ_CONFIG
+ 
+ 
+@@ -7027,9 +7459,11 @@
+ 
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
++lt_save_CFLAGS=$CFLAGS
+ lt_save_GCC=$GCC
+ GCC=
+ CC=${RC-"windres"}
++CFLAGS=
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+@@ -7042,7 +7476,8 @@
+ 
+ GCC=$lt_save_GCC
+ AC_LANG_RESTORE
+-CC="$lt_save_CC"
++CC=$lt_save_CC
++CFLAGS=$lt_save_CFLAGS
+ ])# _LT_LANG_RC_CONFIG
+ 
+ 
+@@ -7101,6 +7536,15 @@
+ AC_SUBST([OBJDUMP])
+ ])
+ 
++# _LT_DECL_DLLTOOL
++# ----------------
++# Ensure DLLTOOL variable is set.
++m4_defun([_LT_DECL_DLLTOOL],
++[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
++AC_SUBST([DLLTOOL])
++])
+ 
+ # _LT_DECL_SED
+ # ------------
+@@ -7194,8 +7638,8 @@
+ # Try some XSI features
+ xsi_shell=no
+ ( _lt_dummy="a/b/c"
+-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+-      = c,a/b,, \
++  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
++      = c,a/b,b/c, \
+     && eval 'test $(( 1 + 1 )) -eq 2 \
+     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+   && xsi_shell=yes
+@@ -7234,206 +7678,162 @@
+ ])# _LT_CHECK_SHELL_FEATURES
+ 
+ 
+-# _LT_PROG_XSI_SHELLFNS
+-# ---------------------
+-# Bourne and XSI compatible variants of some useful shell functions.
+-m4_defun([_LT_PROG_XSI_SHELLFNS],
+-[case $xsi_shell in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_dirname_and_basename file append nondir_replacement
+-# perform func_basename and func_dirname in a single function
+-# call:
+-#   dirname:  Compute the dirname of FILE.  If nonempty,
+-#             add APPEND to the result, otherwise set result
+-#             to NONDIR_REPLACEMENT.
+-#             value returned in "$func_dirname_result"
+-#   basename: Compute filename of FILE.
+-#             value retuned in "$func_basename_result"
+-# Implementation must be kept synchronized with func_dirname
+-# and func_basename. For efficiency, we do not delegate to
+-# those functions but instead duplicate the functionality here.
+-func_dirname_and_basename ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-func_stripname ()
+-{
+-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+-  # positional parameters, so assign one to ordinary parameter first.
+-  func_stripname_result=${3}
+-  func_stripname_result=${func_stripname_result#"${1}"}
+-  func_stripname_result=${func_stripname_result%"${2}"}
+-}
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=${1%%=*}
+-  func_opt_split_arg=${1#*=}
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  case ${1} in
+-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+-    *)    func_lo2o_result=${1} ;;
+-  esac
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=${1%.*}.lo
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=$(( $[*] ))
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=${#1}
+-}
+-
+-_LT_EOF
+-    ;;
+-  *) # Bourne compatible functions.
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+-}
++# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
++# ------------------------------------------------------
++# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
++# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
++m4_defun([_LT_PROG_FUNCTION_REPLACE],
++[dnl {
++sed -e '/^$1 ()$/,/^} # $1 /c\
++$1 ()\
++{\
++m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
++} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++])
+ 
+-dnl func_dirname_and_basename
+-dnl A portable version of this function is already defined in general.m4sh
+-dnl so there is no need for it here.
+ 
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-# func_strip_suffix prefix name
+-func_stripname ()
+-{
+-  case ${2} in
+-    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+-    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+-  esac
+-}
++# _LT_PROG_REPLACE_SHELLFNS
++# -------------------------
++# Replace existing portable implementations of several shell functions with
++# equivalent extended shell implementations where those features are available..
++m4_defun([_LT_PROG_REPLACE_SHELLFNS],
++[if test x"$xsi_shell" = xyes; then
++  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
++    case ${1} in
++      */*) func_dirname_result="${1%/*}${2}" ;;
++      *  ) func_dirname_result="${3}" ;;
++    esac])
++
++  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
++    func_basename_result="${1##*/}"])
++
++  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
++    case ${1} in
++      */*) func_dirname_result="${1%/*}${2}" ;;
++      *  ) func_dirname_result="${3}" ;;
++    esac
++    func_basename_result="${1##*/}"])
+ 
+-# sed scripts:
+-my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+-my_sed_long_arg='1s/^-[[^=]]*=//'
++  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
++    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
++    # positional parameters, so assign one to ordinary parameter first.
++    func_stripname_result=${3}
++    func_stripname_result=${func_stripname_result#"${1}"}
++    func_stripname_result=${func_stripname_result%"${2}"}])
++
++  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
++    func_split_long_opt_name=${1%%=*}
++    func_split_long_opt_arg=${1#*=}])
++
++  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
++    func_split_short_opt_arg=${1#??}
++    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
++
++  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
++    case ${1} in
++      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
++      *)    func_lo2o_result=${1} ;;
++    esac])
+ 
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+-  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+-}
++  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+ 
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+-}
++  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+ 
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=`$ECHO "${1}" | $SED 's/\.[[^.]]*$/.lo/'`
+-}
++  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
++fi
+ 
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=`expr "$[@]"`
+-}
++if test x"$lt_shell_append" = xyes; then
++  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+ 
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+-}
++  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
++    func_quote_for_eval "${2}"
++dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
++    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
++
++  # Save a `func_append' function call where possible by direct use of '+='
++  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++else
++  # Save a `func_append' function call even when '+=' is not available
++  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++fi
+ 
+-_LT_EOF
+-esac
++if test x"$_lt_function_replace_fail" = x":"; then
++  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
++fi
++])
+ 
+-case $lt_shell_append in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$[1]+=\$[2]"
+-}
+-_LT_EOF
++# _LT_PATH_CONVERSION_FUNCTIONS
++# -----------------------------
++# Determine which file name conversion functions should be used by
++# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
++# for certain cross-compile configurations and native mingw.
++m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
++[AC_REQUIRE([AC_CANONICAL_HOST])dnl
++AC_REQUIRE([AC_CANONICAL_BUILD])dnl
++AC_MSG_CHECKING([how to convert $build file names to $host format])
++AC_CACHE_VAL(lt_cv_to_host_file_cmd,
++[case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
++        ;;
++    esac
+     ;;
+-  *)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$[1]=\$$[1]\$[2]"
+-}
+-
+-_LT_EOF
++  *-*-cygwin* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_noop
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
++        ;;
++    esac
+     ;;
+-  esac
++  * ) # unhandled hosts (and "normal" native builds)
++    lt_cv_to_host_file_cmd=func_convert_file_noop
++    ;;
++esac
++])
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
++_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
++         [0], [convert $build file names to $host format])dnl
++
++AC_MSG_CHECKING([how to convert $build file names to toolchain format])
++AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
++[#assume ordinary cross tools, or native build.
++lt_cv_to_tool_file_cmd=func_convert_file_noop
++case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
++        ;;
++    esac
++    ;;
++esac
+ ])
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
++_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
++         [0], [convert $build files to toolchain format])dnl
++])# _LT_PATH_CONVERSION_FUNCTIONS
+Index: binutils-2.24/ltmain.sh
+===================================================================
+--- binutils-2.24.orig/ltmain.sh	2013-11-04 07:33:40.000000000 -0800
++++ binutils-2.24/ltmain.sh	2013-12-15 11:10:23.867118697 -0800
+@@ -1,10 +1,9 @@
+-# Generated from ltmain.m4sh.
+ 
+-# libtool (GNU libtool 1.3134 2009-11-29) 2.2.7a
++# libtool (GNU libtool) 2.4
+ # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+ 
+ # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+-# 2007, 2008, 2009 Free Software Foundation, Inc.
++# 2007, 2008, 2009, 2010 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.
+ 
+@@ -38,7 +37,6 @@
+ #   -n, --dry-run            display commands without modifying any files
+ #       --features           display basic configuration information and exit
+ #       --mode=MODE          use operation mode MODE
+-#       --no-finish          let install mode avoid finish commands
+ #       --preserve-dup-deps  don't remove duplicate dependency libraries
+ #       --quiet, --silent    don't print informational messages
+ #       --no-quiet, --no-silent
+@@ -71,17 +69,19 @@
+ #         compiler:		$LTCC
+ #         compiler flags:		$LTCFLAGS
+ #         linker:		$LD (gnu? $with_gnu_ld)
+-#         $progname:	(GNU libtool 1.3134 2009-11-29) 2.2.7a
++#         $progname:	(GNU libtool) 2.4
+ #         automake:	$automake_version
+ #         autoconf:	$autoconf_version
+ #
+ # Report bugs to <bug-libtool@gnu.org>.
++# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
++# General help using GNU software: <http://www.gnu.org/gethelp/>.
+ 
+ PROGRAM=libtool
+ PACKAGE=libtool
+-VERSION=2.2.7a
+-TIMESTAMP=" 1.3134 2009-11-29"
+-package_revision=1.3134
++VERSION=2.4
++TIMESTAMP=""
++package_revision=1.3293
+ 
+ # Be Bourne compatible
+ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+@@ -106,9 +106,6 @@
+ }
+ 
+ # NLS nuisances: We save the old values to restore during execute mode.
+-# Only set LANG and LC_ALL to C if already set.
+-# These must not be set unconditionally because not all systems understand
+-# e.g. LANG=C (notably SCO).
+ lt_user_locale=
+ lt_safe_locale=
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+@@ -121,15 +118,13 @@
+ 	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ 	fi"
+ done
++LC_ALL=C
++LANGUAGE=C
++export LANGUAGE LC_ALL
+ 
+ $lt_unset CDPATH
+ 
+ 
+-
+-
+-
+-
+-
+ # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+ # is ksh but when the shell is invoked as "sh" and the current value of
+ # the _XPG environment variable is not equal to 1 (one), the special
+@@ -140,7 +135,7 @@
+ 
+ 
+ : ${CP="cp -f"}
+-: ${ECHO=$as_echo}
++test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+ : ${EGREP="/bin/grep -E"}
+ : ${FGREP="/bin/grep -F"}
+ : ${GREP="/bin/grep"}
+@@ -149,7 +144,7 @@
+ : ${MKDIR="mkdir"}
+ : ${MV="mv -f"}
+ : ${RM="rm -f"}
+-: ${SED="/mount/endor/wildenhu/local-x86_64/bin/sed"}
++: ${SED="/bin/sed"}
+ : ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+ : ${Xsed="$SED -e 1s/^X//"}
+ 
+@@ -169,6 +164,27 @@
+ dirname="s,/[^/]*$,,"
+ basename="s,^.*/,,"
+ 
++# func_dirname file append nondir_replacement
++# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
++# otherwise set result to NONDIR_REPLACEMENT.
++func_dirname ()
++{
++    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
++    if test "X$func_dirname_result" = "X${1}"; then
++      func_dirname_result="${3}"
++    else
++      func_dirname_result="$func_dirname_result${2}"
++    fi
++} # func_dirname may be replaced by extended shell implementation
++
++
++# func_basename file
++func_basename ()
++{
++    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
++} # func_basename may be replaced by extended shell implementation
++
++
+ # func_dirname_and_basename file append nondir_replacement
+ # perform func_basename and func_dirname in a single function
+ # call:
+@@ -183,17 +199,31 @@
+ # those functions but instead duplicate the functionality here.
+ func_dirname_and_basename ()
+ {
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-  func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+-}
++    # Extract subdirectory from the argument.
++    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
++    if test "X$func_dirname_result" = "X${1}"; then
++      func_dirname_result="${3}"
++    else
++      func_dirname_result="$func_dirname_result${2}"
++    fi
++    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
++} # func_dirname_and_basename may be replaced by extended shell implementation
++
++
++# func_stripname prefix suffix name
++# strip PREFIX and SUFFIX off of NAME.
++# PREFIX and SUFFIX must not contain globbing or regex special
++# characters, hashes, percent signs, but SUFFIX may contain a leading
++# dot (in which case that matches only a dot).
++# func_strip_suffix prefix name
++func_stripname ()
++{
++    case ${2} in
++      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
++      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
++    esac
++} # func_stripname may be replaced by extended shell implementation
+ 
+-# Generated shell functions inserted here.
+ 
+ # These SED scripts presuppose an absolute path with a trailing slash.
+ pathcar='s,^/\([^/]*\).*$,\1,'
+@@ -376,6 +406,15 @@
+ # Same as above, but do not quote variable references.
+ double_quote_subst='s/\(["`\\]\)/\\\1/g'
+ 
++# Sed substitution that turns a string into a regex matching for the
++# string literally.
++sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
++
++# Sed substitution that converts a w32 file name or path
++# which contains forward slashes, into one that contains
++# (escaped) backslashes.  A very naive implementation.
++lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
++
+ # Re-`\' parameter expansions in output of double_quote_subst that were
+ # `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+ # in input to double_quote_subst, that '$' was protected from expansion.
+@@ -404,7 +443,7 @@
+ # name if it has been set yet.
+ func_echo ()
+ {
+-    $ECHO "$progname${mode+: }$mode: $*"
++    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+ }
+ 
+ # func_verbose arg...
+@@ -430,14 +469,14 @@
+ # Echo program name prefixed message to standard error.
+ func_error ()
+ {
+-    $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
++    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+ }
+ 
+ # func_warning arg...
+ # Echo program name prefixed warning message to standard error.
+ func_warning ()
+ {
+-    $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
++    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+ 
+     # bash bug again:
+     :
+@@ -656,19 +695,35 @@
+     fi
+ }
+ 
+-
+-
++# func_tr_sh
++# Turn $1 into a string suitable for a shell variable name.
++# Result is stored in $func_tr_sh_result.  All characters
++# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
++# if $1 begins with a digit, a '_' is prepended as well.
++func_tr_sh ()
++{
++  case $1 in
++  [0-9]* | *[!a-zA-Z0-9_]*)
++    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
++    ;;
++  * )
++    func_tr_sh_result=$1
++    ;;
++  esac
++}
+ 
+ 
+ # func_version
+ # Echo version message to standard output and exit.
+ func_version ()
+ {
++    $opt_debug
++
+     $SED -n '/(C)/!b go
+ 	:more
+ 	/\./!{
+ 	  N
+-	  s/\n# //
++	  s/\n# / /
+ 	  b more
+ 	}
+ 	:go
+@@ -685,7 +740,9 @@
+ # Echo short help message to standard output and exit.
+ func_usage ()
+ {
+-    $SED -n '/^# Usage:/,/^#  *-h/ {
++    $opt_debug
++
++    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+         s/^# //
+ 	s/^# *$//
+ 	s/\$progname/'$progname'/
+@@ -701,7 +758,10 @@
+ # unless 'noexit' is passed as argument.
+ func_help ()
+ {
++    $opt_debug
++
+     $SED -n '/^# Usage:/,/# Report bugs to/ {
++	:print
+         s/^# //
+ 	s/^# *$//
+ 	s*\$progname*'$progname'*
+@@ -714,7 +774,11 @@
+ 	s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+ 	s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+ 	p
+-     }' < "$progpath"
++	d
++     }
++     /^# .* home page:/b print
++     /^# General help using/b print
++     ' < "$progpath"
+     ret=$?
+     if test -z "$1"; then
+       exit $ret
+@@ -726,12 +790,39 @@
+ # exit_cmd.
+ func_missing_arg ()
+ {
+-    func_error "missing argument for $1"
++    $opt_debug
++
++    func_error "missing argument for $1."
+     exit_cmd=exit
+ }
+ 
+-exit_cmd=:
+ 
++# func_split_short_opt shortopt
++# Set func_split_short_opt_name and func_split_short_opt_arg shell
++# variables after splitting SHORTOPT after the 2nd character.
++func_split_short_opt ()
++{
++    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
++    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
++
++    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
++    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
++} # func_split_short_opt may be replaced by extended shell implementation
++
++
++# func_split_long_opt longopt
++# Set func_split_long_opt_name and func_split_long_opt_arg shell
++# variables after splitting LONGOPT at the `=' sign.
++func_split_long_opt ()
++{
++    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
++    my_sed_long_arg='1s/^--[^=]*=//'
++
++    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
++    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
++} # func_split_long_opt may be replaced by extended shell implementation
++
++exit_cmd=:
+ 
+ 
+ 
+@@ -741,26 +832,64 @@
+ magic_exe="%%%MAGIC EXE variable%%%"
+ 
+ # Global variables.
+-# $mode is unset
+ nonopt=
+-execute_dlfiles=
+ preserve_args=
+ lo2o="s/\\.lo\$/.${objext}/"
+ o2lo="s/\\.${objext}\$/.lo/"
+ extracted_archives=
+ extracted_serial=0
+ 
+-opt_dry_run=false
+-opt_finish=:
+-opt_duplicate_deps=false
+-opt_silent=false
+-opt_debug=:
+-
+ # If this variable is set in any of the actions, the command in it
+ # will be execed at the end.  This prevents here-documents from being
+ # left over by shells.
+ exec_cmd=
+ 
++# func_append var value
++# Append VALUE to the end of shell variable VAR.
++func_append ()
++{
++    eval "${1}=\$${1}\${2}"
++} # func_append may be replaced by extended shell implementation
++
++# func_append_quoted var value
++# Quote VALUE and append to the end of shell variable VAR, separated
++# by a space.
++func_append_quoted ()
++{
++    func_quote_for_eval "${2}"
++    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
++} # func_append_quoted may be replaced by extended shell implementation
++
++
++# func_arith arithmetic-term...
++func_arith ()
++{
++    func_arith_result=`expr "${@}"`
++} # func_arith may be replaced by extended shell implementation
++
++
++# func_len string
++# STRING may not start with a hyphen.
++func_len ()
++{
++    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
++} # func_len may be replaced by extended shell implementation
++
++
++# func_lo2o object
++func_lo2o ()
++{
++    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
++} # func_lo2o may be replaced by extended shell implementation
++
++
++# func_xform libobj-or-source
++func_xform ()
++{
++    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
++} # func_xform may be replaced by extended shell implementation
++
++
+ # func_fatal_configuration arg...
+ # Echo program name prefixed message to standard error, followed by
+ # a configuration failure hint, and exit.
+@@ -850,130 +979,204 @@
+   esac
+ }
+ 
+-# Parse options once, thoroughly.  This comes as soon as possible in
+-# the script to make things like `libtool --version' happen quickly.
++# func_check_version_match
++# Ensure that we are using m4 macros, and libtool script from the same
++# release of libtool.
++func_check_version_match ()
+ {
++  if test "$package_revision" != "$macro_revision"; then
++    if test "$VERSION" != "$macro_version"; then
++      if test -z "$macro_version"; then
++        cat >&2 <<_LT_EOF
++$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
++$progname: definition of this LT_INIT comes from an older release.
++$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
++$progname: and run autoconf again.
++_LT_EOF
++      else
++        cat >&2 <<_LT_EOF
++$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
++$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
++$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
++$progname: and run autoconf again.
++_LT_EOF
++      fi
++    else
++      cat >&2 <<_LT_EOF
++$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
++$progname: but the definition of this LT_INIT comes from revision $macro_revision.
++$progname: You should recreate aclocal.m4 with macros from revision $package_revision
++$progname: of $PACKAGE $VERSION and run autoconf again.
++_LT_EOF
++    fi
++
++    exit $EXIT_MISMATCH
++  fi
++}
++
++
++# Shorthand for --mode=foo, only valid as the first argument
++case $1 in
++clean|clea|cle|cl)
++  shift; set dummy --mode clean ${1+"$@"}; shift
++  ;;
++compile|compil|compi|comp|com|co|c)
++  shift; set dummy --mode compile ${1+"$@"}; shift
++  ;;
++execute|execut|execu|exec|exe|ex|e)
++  shift; set dummy --mode execute ${1+"$@"}; shift
++  ;;
++finish|finis|fini|fin|fi|f)
++  shift; set dummy --mode finish ${1+"$@"}; shift
++  ;;
++install|instal|insta|inst|ins|in|i)
++  shift; set dummy --mode install ${1+"$@"}; shift
++  ;;
++link|lin|li|l)
++  shift; set dummy --mode link ${1+"$@"}; shift
++  ;;
++uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
++  shift; set dummy --mode uninstall ${1+"$@"}; shift
++  ;;
++esac
+ 
+-  # Shorthand for --mode=foo, only valid as the first argument
+-  case $1 in
+-  clean|clea|cle|cl)
+-    shift; set dummy --mode clean ${1+"$@"}; shift
+-    ;;
+-  compile|compil|compi|comp|com|co|c)
+-    shift; set dummy --mode compile ${1+"$@"}; shift
+-    ;;
+-  execute|execut|execu|exec|exe|ex|e)
+-    shift; set dummy --mode execute ${1+"$@"}; shift
+-    ;;
+-  finish|finis|fini|fin|fi|f)
+-    shift; set dummy --mode finish ${1+"$@"}; shift
+-    ;;
+-  install|instal|insta|inst|ins|in|i)
+-    shift; set dummy --mode install ${1+"$@"}; shift
+-    ;;
+-  link|lin|li|l)
+-    shift; set dummy --mode link ${1+"$@"}; shift
+-    ;;
+-  uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+-    shift; set dummy --mode uninstall ${1+"$@"}; shift
+-    ;;
+-  esac
+ 
+-  # Parse non-mode specific arguments:
+-  while test "$#" -gt 0; do
++
++# Option defaults:
++opt_debug=:
++opt_dry_run=false
++opt_config=false
++opt_preserve_dup_deps=false
++opt_features=false
++opt_finish=false
++opt_help=false
++opt_help_all=false
++opt_silent=:
++opt_verbose=:
++opt_silent=false
++opt_verbose=false
++
++
++# Parse options once, thoroughly.  This comes as soon as possible in the
++# script to make things like `--version' happen as quickly as we can.
++{
++  # this just eases exit handling
++  while test $# -gt 0; do
+     opt="$1"
+     shift
+-
+     case $opt in
+-      --config)		func_config					;;
+-
+-      --debug)		preserve_args="$preserve_args $opt"
++      --debug|-x)	opt_debug='set -x'
+ 			func_echo "enabling shell trace mode"
+-			opt_debug='set -x'
+ 			$opt_debug
+ 			;;
+-
+-      -dlopen)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+-			execute_dlfiles="$execute_dlfiles $1"
+-			shift
++      --dry-run|--dryrun|-n)
++			opt_dry_run=:
+ 			;;
+-
+-      --dry-run | -n)	opt_dry_run=:					;;
+-      --features)       func_features					;;
+-      --finish)		mode="finish"					;;
+-      --no-finish)	opt_finish=false				;;
+-
+-      --mode)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+-			case $1 in
+-			  # Valid mode arguments:
+-			  clean)	;;
+-			  compile)	;;
+-			  execute)	;;
+-			  finish)	;;
+-			  install)	;;
+-			  link)		;;
+-			  relink)	;;
+-			  uninstall)	;;
+-
+-			  # Catch anything else as an error
+-			  *) func_error "invalid argument for $opt"
+-			     exit_cmd=exit
+-			     break
+-			     ;;
+-		        esac
+-
+-			mode="$1"
++      --config)
++			opt_config=:
++func_config
++			;;
++      --dlopen|-dlopen)
++			optarg="$1"
++			opt_dlopen="${opt_dlopen+$opt_dlopen
++}$optarg"
+ 			shift
+ 			;;
+-
+       --preserve-dup-deps)
+-			opt_duplicate_deps=:				;;
+-
+-      --quiet|--silent)	preserve_args="$preserve_args $opt"
+-			opt_silent=:
+-			opt_verbose=false
++			opt_preserve_dup_deps=:
+ 			;;
+-
+-      --no-quiet|--no-silent)
+-			preserve_args="$preserve_args $opt"
+-			opt_silent=false
++      --features)
++			opt_features=:
++func_features
+ 			;;
+-
+-      --verbose| -v)	preserve_args="$preserve_args $opt"
++      --finish)
++			opt_finish=:
++set dummy --mode finish ${1+"$@"}; shift
++			;;
++      --help)
++			opt_help=:
++			;;
++      --help-all)
++			opt_help_all=:
++opt_help=': help-all'
++			;;
++      --mode)
++			test $# = 0 && func_missing_arg $opt && break
++			optarg="$1"
++			opt_mode="$optarg"
++case $optarg in
++  # Valid mode arguments:
++  clean|compile|execute|finish|install|link|relink|uninstall) ;;
++
++  # Catch anything else as an error
++  *) func_error "invalid argument for $opt"
++     exit_cmd=exit
++     break
++     ;;
++esac
++			shift
++			;;
++      --no-silent|--no-quiet)
+ 			opt_silent=false
+-			opt_verbose=:
++func_append preserve_args " $opt"
+ 			;;
+-
+-      --no-verbose)	preserve_args="$preserve_args $opt"
++      --no-verbose)
+ 			opt_verbose=false
++func_append preserve_args " $opt"
+ 			;;
+-
+-      --tag)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+-			preserve_args="$preserve_args $opt $1"
+-			func_enable_tag "$1"	# tagname is set here
++      --silent|--quiet)
++			opt_silent=:
++func_append preserve_args " $opt"
++        opt_verbose=false
++			;;
++      --verbose|-v)
++			opt_verbose=:
++func_append preserve_args " $opt"
++opt_silent=false
++			;;
++      --tag)
++			test $# = 0 && func_missing_arg $opt && break
++			optarg="$1"
++			opt_tag="$optarg"
++func_append preserve_args " $opt $optarg"
++func_enable_tag "$optarg"
+ 			shift
+ 			;;
+ 
++      -\?|-h)		func_usage				;;
++      --help)		func_help				;;
++      --version)	func_version				;;
++
+       # Separate optargs to long options:
+-      -dlopen=*|--mode=*|--tag=*)
+-			func_opt_split "$opt"
+-			set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
++      --*=*)
++			func_split_long_opt "$opt"
++			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ 			shift
+ 			;;
+ 
+-      -\?|-h)		func_usage					;;
+-      --help)		opt_help=:					;;
+-      --help-all)	opt_help=': help-all'				;;
+-      --version)	func_version					;;
+-
+-      -*)		func_fatal_help "unrecognized option \`$opt'"	;;
+-
+-      *)		nonopt="$opt"
+-			break
++      # Separate non-argument short options:
++      -\?*|-h*|-n*|-v*)
++			func_split_short_opt "$opt"
++			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
++			shift
+ 			;;
++
++      --)		break					;;
++      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
++      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+     esac
+   done
+ 
++  # Validate options:
++
++  # save first non-option argument
++  if test "$#" -gt 0; then
++    nonopt="$opt"
++    shift
++  fi
++
++  # preserve --debug
++  test "$opt_debug" = : || func_append preserve_args " --debug"
+ 
+   case $host in
+     *cygwin* | *mingw* | *pw32* | *cegcc*)
+@@ -981,82 +1184,44 @@
+       opt_duplicate_compiler_generated_deps=:
+       ;;
+     *)
+-      opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
++      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+       ;;
+   esac
+ 
+-  # Having warned about all mis-specified options, bail out if
+-  # anything was wrong.
+-  $exit_cmd $EXIT_FAILURE
+-}
++  $opt_help || {
++    # Sanity checks first:
++    func_check_version_match
+ 
+-# func_check_version_match
+-# Ensure that we are using m4 macros, and libtool script from the same
+-# release of libtool.
+-func_check_version_match ()
+-{
+-  if test "$package_revision" != "$macro_revision"; then
+-    if test "$VERSION" != "$macro_version"; then
+-      if test -z "$macro_version"; then
+-        cat >&2 <<_LT_EOF
+-$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+-$progname: definition of this LT_INIT comes from an older release.
+-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+-$progname: and run autoconf again.
+-_LT_EOF
+-      else
+-        cat >&2 <<_LT_EOF
+-$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+-$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+-$progname: and run autoconf again.
+-_LT_EOF
+-      fi
+-    else
+-      cat >&2 <<_LT_EOF
+-$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+-$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+-$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+-$progname: of $PACKAGE $VERSION and run autoconf again.
+-_LT_EOF
++    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
++      func_fatal_configuration "not configured to build any kind of library"
+     fi
+ 
+-    exit $EXIT_MISMATCH
+-  fi
+-}
+-
++    # Darwin sucks
++    eval std_shrext=\"$shrext_cmds\"
+ 
+-## ----------- ##
+-##    Main.    ##
+-## ----------- ##
+-
+-$opt_help || {
+-  # Sanity checks first:
+-  func_check_version_match
+-
+-  if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+-    func_fatal_configuration "not configured to build any kind of library"
+-  fi
++    # Only execute mode is allowed to have -dlopen flags.
++    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
++      func_error "unrecognized option \`-dlopen'"
++      $ECHO "$help" 1>&2
++      exit $EXIT_FAILURE
++    fi
+ 
+-  test -z "$mode" && func_fatal_error "error: you must specify a MODE."
++    # Change the help message to a mode-specific one.
++    generic_help="$help"
++    help="Try \`$progname --help --mode=$opt_mode' for more information."
++  }
+ 
+ 
+-  # Darwin sucks
+-  eval "std_shrext=\"$shrext_cmds\""
++  # Bail if the options were screwed
++  $exit_cmd $EXIT_FAILURE
++}
+ 
+ 
+-  # Only execute mode is allowed to have -dlopen flags.
+-  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+-    func_error "unrecognized option \`-dlopen'"
+-    $ECHO "$help" 1>&2
+-    exit $EXIT_FAILURE
+-  fi
+ 
+-  # Change the help message to a mode-specific one.
+-  generic_help="$help"
+-  help="Try \`$progname --help --mode=$mode' for more information."
+-}
+ 
++## ----------- ##
++##    Main.    ##
++## ----------- ##
+ 
+ # func_lalib_p file
+ # True iff FILE is a libtool `.la' library or `.lo' object file.
+@@ -1121,12 +1286,9 @@
+ # temporary ltwrapper_script.
+ func_ltwrapper_scriptname ()
+ {
+-    func_ltwrapper_scriptname_result=""
+-    if func_ltwrapper_executable_p "$1"; then
+-	func_dirname_and_basename "$1" "" "."
+-	func_stripname '' '.exe' "$func_basename_result"
+-	func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+-    fi
++    func_dirname_and_basename "$1" "" "."
++    func_stripname '' '.exe' "$func_basename_result"
++    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+ }
+ 
+ # func_ltwrapper_p file
+@@ -1149,7 +1311,7 @@
+     save_ifs=$IFS; IFS='~'
+     for cmd in $1; do
+       IFS=$save_ifs
+-      eval "cmd=\"$cmd\""
++      eval cmd=\"$cmd\"
+       func_show_eval "$cmd" "${2-:}"
+     done
+     IFS=$save_ifs
+@@ -1172,6 +1334,37 @@
+ }
+ 
+ 
++# func_resolve_sysroot PATH
++# Replace a leading = in PATH with a sysroot.  Store the result into
++# func_resolve_sysroot_result
++func_resolve_sysroot ()
++{
++  func_resolve_sysroot_result=$1
++  case $func_resolve_sysroot_result in
++  =*)
++    func_stripname '=' '' "$func_resolve_sysroot_result"
++    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
++    ;;
++  esac
++}
++
++# func_replace_sysroot PATH
++# If PATH begins with the sysroot, replace it with = and
++# store the result into func_replace_sysroot_result.
++func_replace_sysroot ()
++{
++  case "$lt_sysroot:$1" in
++  ?*:"$lt_sysroot"*)
++    func_stripname "$lt_sysroot" '' "$1"
++    func_replace_sysroot_result="=$func_stripname_result"
++    ;;
++  *)
++    # Including no sysroot.
++    func_replace_sysroot_result=$1
++    ;;
++  esac
++}
++
+ # func_infer_tag arg
+ # Infer tagged configuration to use if any are available and
+ # if one wasn't chosen via the "--tag" command line option.
+@@ -1184,8 +1377,7 @@
+     if test -n "$available_tags" && test -z "$tagname"; then
+       CC_quoted=
+       for arg in $CC; do
+-        func_quote_for_eval "$arg"
+-	CC_quoted="$CC_quoted $func_quote_for_eval_result"
++	func_append_quoted CC_quoted "$arg"
+       done
+       CC_expanded=`func_echo_all $CC`
+       CC_quoted_expanded=`func_echo_all $CC_quoted`
+@@ -1204,8 +1396,7 @@
+ 	    CC_quoted=
+ 	    for arg in $CC; do
+ 	      # Double-quote args containing other shell metacharacters.
+-	      func_quote_for_eval "$arg"
+-	      CC_quoted="$CC_quoted $func_quote_for_eval_result"
++	      func_append_quoted CC_quoted "$arg"
+ 	    done
+ 	    CC_expanded=`func_echo_all $CC`
+ 	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+@@ -1274,6 +1465,486 @@
+     }
+ }
+ 
++
++##################################################
++# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
++##################################################
++
++# func_convert_core_file_wine_to_w32 ARG
++# Helper function used by file name conversion functions when $build is *nix,
++# and $host is mingw, cygwin, or some other w32 environment. Relies on a
++# correctly configured wine environment available, with the winepath program
++# in $build's $PATH.
++#
++# ARG is the $build file name to be converted to w32 format.
++# Result is available in $func_convert_core_file_wine_to_w32_result, and will
++# be empty on error (or when ARG is empty)
++func_convert_core_file_wine_to_w32 ()
++{
++  $opt_debug
++  func_convert_core_file_wine_to_w32_result="$1"
++  if test -n "$1"; then
++    # Unfortunately, winepath does not exit with a non-zero error code, so we
++    # are forced to check the contents of stdout. On the other hand, if the
++    # command is not found, the shell will set an exit code of 127 and print
++    # *an error message* to stdout. So we must check for both error code of
++    # zero AND non-empty stdout, which explains the odd construction:
++    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
++    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
++      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
++        $SED -e "$lt_sed_naive_backslashify"`
++    else
++      func_convert_core_file_wine_to_w32_result=
++    fi
++  fi
++}
++# end: func_convert_core_file_wine_to_w32
++
++
++# func_convert_core_path_wine_to_w32 ARG
++# Helper function used by path conversion functions when $build is *nix, and
++# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
++# configured wine environment available, with the winepath program in $build's
++# $PATH. Assumes ARG has no leading or trailing path separator characters.
++#
++# ARG is path to be converted from $build format to win32.
++# Result is available in $func_convert_core_path_wine_to_w32_result.
++# Unconvertible file (directory) names in ARG are skipped; if no directory names
++# are convertible, then the result may be empty.
++func_convert_core_path_wine_to_w32 ()
++{
++  $opt_debug
++  # unfortunately, winepath doesn't convert paths, only file names
++  func_convert_core_path_wine_to_w32_result=""
++  if test -n "$1"; then
++    oldIFS=$IFS
++    IFS=:
++    for func_convert_core_path_wine_to_w32_f in $1; do
++      IFS=$oldIFS
++      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
++      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
++        if test -z "$func_convert_core_path_wine_to_w32_result"; then
++          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
++        else
++          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
++        fi
++      fi
++    done
++    IFS=$oldIFS
++  fi
++}
++# end: func_convert_core_path_wine_to_w32
++
++
++# func_cygpath ARGS...
++# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
++# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
++# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
++# (2), returns the Cygwin file name or path in func_cygpath_result (input
++# file name or path is assumed to be in w32 format, as previously converted
++# from $build's *nix or MSYS format). In case (3), returns the w32 file name
++# or path in func_cygpath_result (input file name or path is assumed to be in
++# Cygwin format). Returns an empty string on error.
++#
++# ARGS are passed to cygpath, with the last one being the file name or path to
++# be converted.
++#
++# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
++# environment variable; do not put it in $PATH.
++func_cygpath ()
++{
++  $opt_debug
++  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
++    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
++    if test "$?" -ne 0; then
++      # on failure, ensure result is empty
++      func_cygpath_result=
++    fi
++  else
++    func_cygpath_result=
++    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
++  fi
++}
++#end: func_cygpath
++
++
++# func_convert_core_msys_to_w32 ARG
++# Convert file name or path ARG from MSYS format to w32 format.  Return
++# result in func_convert_core_msys_to_w32_result.
++func_convert_core_msys_to_w32 ()
++{
++  $opt_debug
++  # awkward: cmd appends spaces to result
++  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
++    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
++}
++#end: func_convert_core_msys_to_w32
++
++
++# func_convert_file_check ARG1 ARG2
++# Verify that ARG1 (a file name in $build format) was converted to $host
++# format in ARG2. Otherwise, emit an error message, but continue (resetting
++# func_to_host_file_result to ARG1).
++func_convert_file_check ()
++{
++  $opt_debug
++  if test -z "$2" && test -n "$1" ; then
++    func_error "Could not determine host file name corresponding to"
++    func_error "  \`$1'"
++    func_error "Continuing, but uninstalled executables may not work."
++    # Fallback:
++    func_to_host_file_result="$1"
++  fi
++}
++# end func_convert_file_check
++
++
++# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
++# Verify that FROM_PATH (a path in $build format) was converted to $host
++# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
++# func_to_host_file_result to a simplistic fallback value (see below).
++func_convert_path_check ()
++{
++  $opt_debug
++  if test -z "$4" && test -n "$3"; then
++    func_error "Could not determine the host path corresponding to"
++    func_error "  \`$3'"
++    func_error "Continuing, but uninstalled executables may not work."
++    # Fallback.  This is a deliberately simplistic "conversion" and
++    # should not be "improved".  See libtool.info.
++    if test "x$1" != "x$2"; then
++      lt_replace_pathsep_chars="s|$1|$2|g"
++      func_to_host_path_result=`echo "$3" |
++        $SED -e "$lt_replace_pathsep_chars"`
++    else
++      func_to_host_path_result="$3"
++    fi
++  fi
++}
++# end func_convert_path_check
++
++
++# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
++# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
++# and appending REPL if ORIG matches BACKPAT.
++func_convert_path_front_back_pathsep ()
++{
++  $opt_debug
++  case $4 in
++  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
++    ;;
++  esac
++  case $4 in
++  $2 ) func_append func_to_host_path_result "$3"
++    ;;
++  esac
++}
++# end func_convert_path_front_back_pathsep
++
++
++##################################################
++# $build to $host FILE NAME CONVERSION FUNCTIONS #
++##################################################
++# invoked via `$to_host_file_cmd ARG'
++#
++# In each case, ARG is the path to be converted from $build to $host format.
++# Result will be available in $func_to_host_file_result.
++
++
++# func_to_host_file ARG
++# Converts the file name ARG from $build format to $host format. Return result
++# in func_to_host_file_result.
++func_to_host_file ()
++{
++  $opt_debug
++  $to_host_file_cmd "$1"
++}
++# end func_to_host_file
++
++
++# func_to_tool_file ARG LAZY
++# converts the file name ARG from $build format to toolchain format. Return
++# result in func_to_tool_file_result.  If the conversion in use is listed
++# in (the comma separated) LAZY, no conversion takes place.
++func_to_tool_file ()
++{
++  $opt_debug
++  case ,$2, in
++    *,"$to_tool_file_cmd",*)
++      func_to_tool_file_result=$1
++      ;;
++    *)
++      $to_tool_file_cmd "$1"
++      func_to_tool_file_result=$func_to_host_file_result
++      ;;
++  esac
++}
++# end func_to_tool_file
++
++
++# func_convert_file_noop ARG
++# Copy ARG to func_to_host_file_result.
++func_convert_file_noop ()
++{
++  func_to_host_file_result="$1"
++}
++# end func_convert_file_noop
++
++
++# func_convert_file_msys_to_w32 ARG
++# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
++# conversion to w32 is not available inside the cwrapper.  Returns result in
++# func_to_host_file_result.
++func_convert_file_msys_to_w32 ()
++{
++  $opt_debug
++  func_to_host_file_result="$1"
++  if test -n "$1"; then
++    func_convert_core_msys_to_w32 "$1"
++    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
++  fi
++  func_convert_file_check "$1" "$func_to_host_file_result"
++}
++# end func_convert_file_msys_to_w32
++
++
++# func_convert_file_cygwin_to_w32 ARG
++# Convert file name ARG from Cygwin to w32 format.  Returns result in
++# func_to_host_file_result.
++func_convert_file_cygwin_to_w32 ()
++{
++  $opt_debug
++  func_to_host_file_result="$1"
++  if test -n "$1"; then
++    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
++    # LT_CYGPATH in this case.
++    func_to_host_file_result=`cygpath -m "$1"`
++  fi
++  func_convert_file_check "$1" "$func_to_host_file_result"
++}
++# end func_convert_file_cygwin_to_w32
++
++
++# func_convert_file_nix_to_w32 ARG
++# Convert file name ARG from *nix to w32 format.  Requires a wine environment
++# and a working winepath. Returns result in func_to_host_file_result.
++func_convert_file_nix_to_w32 ()
++{
++  $opt_debug
++  func_to_host_file_result="$1"
++  if test -n "$1"; then
++    func_convert_core_file_wine_to_w32 "$1"
++    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
++  fi
++  func_convert_file_check "$1" "$func_to_host_file_result"
++}
++# end func_convert_file_nix_to_w32
++
++
++# func_convert_file_msys_to_cygwin ARG
++# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
++# Returns result in func_to_host_file_result.
++func_convert_file_msys_to_cygwin ()
++{
++  $opt_debug
++  func_to_host_file_result="$1"
++  if test -n "$1"; then
++    func_convert_core_msys_to_w32 "$1"
++    func_cygpath -u "$func_convert_core_msys_to_w32_result"
++    func_to_host_file_result="$func_cygpath_result"
++  fi
++  func_convert_file_check "$1" "$func_to_host_file_result"
++}
++# end func_convert_file_msys_to_cygwin
++
++
++# func_convert_file_nix_to_cygwin ARG
++# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
++# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
++# in func_to_host_file_result.
++func_convert_file_nix_to_cygwin ()
++{
++  $opt_debug
++  func_to_host_file_result="$1"
++  if test -n "$1"; then
++    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
++    func_convert_core_file_wine_to_w32 "$1"
++    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
++    func_to_host_file_result="$func_cygpath_result"
++  fi
++  func_convert_file_check "$1" "$func_to_host_file_result"
++}
++# end func_convert_file_nix_to_cygwin
++
++
++#############################################
++# $build to $host PATH CONVERSION FUNCTIONS #
++#############################################
++# invoked via `$to_host_path_cmd ARG'
++#
++# In each case, ARG is the path to be converted from $build to $host format.
++# The result will be available in $func_to_host_path_result.
++#
++# Path separators are also converted from $build format to $host format.  If
++# ARG begins or ends with a path separator character, it is preserved (but
++# converted to $host format) on output.
++#
++# All path conversion functions are named using the following convention:
++#   file name conversion function    : func_convert_file_X_to_Y ()
++#   path conversion function         : func_convert_path_X_to_Y ()
++# where, for any given $build/$host combination the 'X_to_Y' value is the
++# same.  If conversion functions are added for new $build/$host combinations,
++# the two new functions must follow this pattern, or func_init_to_host_path_cmd
++# will break.
++
++
++# func_init_to_host_path_cmd
++# Ensures that function "pointer" variable $to_host_path_cmd is set to the
++# appropriate value, based on the value of $to_host_file_cmd.
++to_host_path_cmd=
++func_init_to_host_path_cmd ()
++{
++  $opt_debug
++  if test -z "$to_host_path_cmd"; then
++    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
++    to_host_path_cmd="func_convert_path_${func_stripname_result}"
++  fi
++}
++
++
++# func_to_host_path ARG
++# Converts the path ARG from $build format to $host format. Return result
++# in func_to_host_path_result.
++func_to_host_path ()
++{
++  $opt_debug
++  func_init_to_host_path_cmd
++  $to_host_path_cmd "$1"
++}
++# end func_to_host_path
++
++
++# func_convert_path_noop ARG
++# Copy ARG to func_to_host_path_result.
++func_convert_path_noop ()
++{
++  func_to_host_path_result="$1"
++}
++# end func_convert_path_noop
++
++
++# func_convert_path_msys_to_w32 ARG
++# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
++# conversion to w32 is not available inside the cwrapper.  Returns result in
++# func_to_host_path_result.
++func_convert_path_msys_to_w32 ()
++{
++  $opt_debug
++  func_to_host_path_result="$1"
++  if test -n "$1"; then
++    # Remove leading and trailing path separator characters from ARG.  MSYS
++    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
++    # and winepath ignores them completely.
++    func_stripname : : "$1"
++    func_to_host_path_tmp1=$func_stripname_result
++    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
++    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
++    func_convert_path_check : ";" \
++      "$func_to_host_path_tmp1" "$func_to_host_path_result"
++    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
++  fi
++}
++# end func_convert_path_msys_to_w32
++
++
++# func_convert_path_cygwin_to_w32 ARG
++# Convert path ARG from Cygwin to w32 format.  Returns result in
++# func_to_host_file_result.
++func_convert_path_cygwin_to_w32 ()
++{
++  $opt_debug
++  func_to_host_path_result="$1"
++  if test -n "$1"; then
++    # See func_convert_path_msys_to_w32:
++    func_stripname : : "$1"
++    func_to_host_path_tmp1=$func_stripname_result
++    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
++    func_convert_path_check : ";" \
++      "$func_to_host_path_tmp1" "$func_to_host_path_result"
++    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
++  fi
++}
++# end func_convert_path_cygwin_to_w32
++
++
++# func_convert_path_nix_to_w32 ARG
++# Convert path ARG from *nix to w32 format.  Requires a wine environment and
++# a working winepath.  Returns result in func_to_host_file_result.
++func_convert_path_nix_to_w32 ()
++{
++  $opt_debug
++  func_to_host_path_result="$1"
++  if test -n "$1"; then
++    # See func_convert_path_msys_to_w32:
++    func_stripname : : "$1"
++    func_to_host_path_tmp1=$func_stripname_result
++    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
++    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
++    func_convert_path_check : ";" \
++      "$func_to_host_path_tmp1" "$func_to_host_path_result"
++    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
++  fi
++}
++# end func_convert_path_nix_to_w32
++
++
++# func_convert_path_msys_to_cygwin ARG
++# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
++# Returns result in func_to_host_file_result.
++func_convert_path_msys_to_cygwin ()
++{
++  $opt_debug
++  func_to_host_path_result="$1"
++  if test -n "$1"; then
++    # See func_convert_path_msys_to_w32:
++    func_stripname : : "$1"
++    func_to_host_path_tmp1=$func_stripname_result
++    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
++    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
++    func_to_host_path_result="$func_cygpath_result"
++    func_convert_path_check : : \
++      "$func_to_host_path_tmp1" "$func_to_host_path_result"
++    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
++  fi
++}
++# end func_convert_path_msys_to_cygwin
++
++
++# func_convert_path_nix_to_cygwin ARG
++# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
++# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
++# func_to_host_file_result.
++func_convert_path_nix_to_cygwin ()
++{
++  $opt_debug
++  func_to_host_path_result="$1"
++  if test -n "$1"; then
++    # Remove leading and trailing path separator characters from
++    # ARG. msys behavior is inconsistent here, cygpath turns them
++    # into '.;' and ';.', and winepath ignores them completely.
++    func_stripname : : "$1"
++    func_to_host_path_tmp1=$func_stripname_result
++    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
++    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
++    func_to_host_path_result="$func_cygpath_result"
++    func_convert_path_check : : \
++      "$func_to_host_path_tmp1" "$func_to_host_path_result"
++    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
++  fi
++}
++# end func_convert_path_nix_to_cygwin
++
++
+ # func_mode_compile arg...
+ func_mode_compile ()
+ {
+@@ -1314,12 +1985,12 @@
+ 	  ;;
+ 
+ 	-pie | -fpie | -fPIE)
+-          pie_flag="$pie_flag $arg"
++          func_append pie_flag " $arg"
+ 	  continue
+ 	  ;;
+ 
+ 	-shared | -static | -prefer-pic | -prefer-non-pic)
+-	  later="$later $arg"
++	  func_append later " $arg"
+ 	  continue
+ 	  ;;
+ 
+@@ -1340,15 +2011,14 @@
+ 	  save_ifs="$IFS"; IFS=','
+ 	  for arg in $args; do
+ 	    IFS="$save_ifs"
+-	    func_quote_for_eval "$arg"
+-	    lastarg="$lastarg $func_quote_for_eval_result"
++	    func_append_quoted lastarg "$arg"
+ 	  done
+ 	  IFS="$save_ifs"
+ 	  func_stripname ' ' '' "$lastarg"
+ 	  lastarg=$func_stripname_result
+ 
+ 	  # Add the arguments to base_compile.
+-	  base_compile="$base_compile $lastarg"
++	  func_append base_compile " $lastarg"
+ 	  continue
+ 	  ;;
+ 
+@@ -1364,8 +2034,7 @@
+       esac    #  case $arg_mode
+ 
+       # Aesthetically quote the previous argument.
+-      func_quote_for_eval "$lastarg"
+-      base_compile="$base_compile $func_quote_for_eval_result"
++      func_append_quoted base_compile "$lastarg"
+     done # for arg
+ 
+     case $arg_mode in
+@@ -1496,17 +2165,16 @@
+ 	$opt_dry_run || $RM $removelist
+ 	exit $EXIT_FAILURE
+       fi
+-      removelist="$removelist $output_obj"
++      func_append removelist " $output_obj"
+       $ECHO "$srcfile" > "$lockfile"
+     fi
+ 
+     $opt_dry_run || $RM $removelist
+-    removelist="$removelist $lockfile"
++    func_append removelist " $lockfile"
+     trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+ 
+-    if test -n "$fix_srcfile_path"; then
+-      eval "srcfile=\"$fix_srcfile_path\""
+-    fi
++    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
++    srcfile=$func_to_tool_file_result
+     func_quote_for_eval "$srcfile"
+     qsrcfile=$func_quote_for_eval_result
+ 
+@@ -1526,7 +2194,7 @@
+ 
+       if test -z "$output_obj"; then
+ 	# Place PIC objects in $objdir
+-	command="$command -o $lobj"
++	func_append command " -o $lobj"
+       fi
+ 
+       func_show_eval_locale "$command"	\
+@@ -1573,11 +2241,11 @@
+ 	command="$base_compile $qsrcfile $pic_flag"
+       fi
+       if test "$compiler_c_o" = yes; then
+-	command="$command -o $obj"
++	func_append command " -o $obj"
+       fi
+ 
+       # Suppress compiler output if we already did a PIC compilation.
+-      command="$command$suppress_output"
++      func_append command "$suppress_output"
+       func_show_eval_locale "$command" \
+         '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+ 
+@@ -1622,13 +2290,13 @@
+ }
+ 
+ $opt_help || {
+-  test "$mode" = compile && func_mode_compile ${1+"$@"}
++  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+ }
+ 
+ func_mode_help ()
+ {
+     # We need to display help for each of the modes.
+-    case $mode in
++    case $opt_mode in
+       "")
+         # Generic help is extracted from the usage comments
+         # at the start of this file.
+@@ -1659,8 +2327,8 @@
+ 
+   -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+   -no-suppress      do not suppress compiler output for multiple passes
+-  -prefer-pic       try to building PIC objects only
+-  -prefer-non-pic   try to building non-PIC objects only
++  -prefer-pic       try to build PIC objects only
++  -prefer-non-pic   try to build non-PIC objects only
+   -shared           do not build a \`.o' file suitable for static linking
+   -static           only build a \`.o' file suitable for static linking
+   -Wc,FLAG          pass FLAG directly to the compiler
+@@ -1804,7 +2472,7 @@
+         ;;
+ 
+       *)
+-        func_fatal_help "invalid operation mode \`$mode'"
++        func_fatal_help "invalid operation mode \`$opt_mode'"
+         ;;
+     esac
+ 
+@@ -1819,13 +2487,13 @@
+   else
+     {
+       func_help noexit
+-      for mode in compile link execute install finish uninstall clean; do
++      for opt_mode in compile link execute install finish uninstall clean; do
+ 	func_mode_help
+       done
+     } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+     {
+       func_help noexit
+-      for mode in compile link execute install finish uninstall clean; do
++      for opt_mode in compile link execute install finish uninstall clean; do
+ 	echo
+ 	func_mode_help
+       done
+@@ -1854,13 +2522,16 @@
+       func_fatal_help "you must specify a COMMAND"
+ 
+     # Handle -dlopen flags immediately.
+-    for file in $execute_dlfiles; do
++    for file in $opt_dlopen; do
+       test -f "$file" \
+ 	|| func_fatal_help "\`$file' is not a file"
+ 
+       dir=
+       case $file in
+       *.la)
++	func_resolve_sysroot "$file"
++	file=$func_resolve_sysroot_result
++
+ 	# Check to see that this really is a libtool archive.
+ 	func_lalib_unsafe_p "$file" \
+ 	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+@@ -1882,7 +2553,7 @@
+ 	dir="$func_dirname_result"
+ 
+ 	if test -f "$dir/$objdir/$dlname"; then
+-	  dir="$dir/$objdir"
++	  func_append dir "/$objdir"
+ 	else
+ 	  if test ! -f "$dir/$dlname"; then
+ 	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+@@ -1907,10 +2578,10 @@
+       test -n "$absdir" && dir="$absdir"
+ 
+       # Now add the directory to shlibpath_var.
+-      if eval test -z \"\$$shlibpath_var\"; then
+-	eval $shlibpath_var=\$dir
++      if eval "test -z \"\$$shlibpath_var\""; then
++	eval "$shlibpath_var=\"\$dir\""
+       else
+-	eval $shlibpath_var=\$dir:\$$shlibpath_var
++	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+       fi
+     done
+ 
+@@ -1939,8 +2610,7 @@
+ 	;;
+       esac
+       # Quote arguments (to preserve shell metacharacters).
+-      func_quote_for_eval "$file"
+-      args="$args $func_quote_for_eval_result"
++      func_append_quoted args "$file"
+     done
+ 
+     if test "X$opt_dry_run" = Xfalse; then
+@@ -1972,22 +2642,59 @@
+     fi
+ }
+ 
+-test "$mode" = execute && func_mode_execute ${1+"$@"}
++test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+ 
+ 
+ # func_mode_finish arg...
+ func_mode_finish ()
+ {
+     $opt_debug
+-    libdirs="$nonopt"
++    libs=
++    libdirs=
+     admincmds=
+ 
+-    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+-      for dir
+-      do
+-	libdirs="$libdirs $dir"
+-      done
++    for opt in "$nonopt" ${1+"$@"}
++    do
++      if test -d "$opt"; then
++	func_append libdirs " $opt"
++
++      elif test -f "$opt"; then
++	if func_lalib_unsafe_p "$opt"; then
++	  func_append libs " $opt"
++	else
++	  func_warning "\`$opt' is not a valid libtool archive"
++	fi
++
++      else
++	func_fatal_error "invalid argument \`$opt'"
++      fi
++    done
++
++    if test -n "$libs"; then
++      if test -n "$lt_sysroot"; then
++        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
++        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
++      else
++        sysroot_cmd=
++      fi
++
++      # Remove sysroot references
++      if $opt_dry_run; then
++        for lib in $libs; do
++          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
++        done
++      else
++        tmpdir=`func_mktempdir`
++        for lib in $libs; do
++	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
++	    > $tmpdir/tmp-la
++	  mv -f $tmpdir/tmp-la $lib
++	done
++        ${RM}r "$tmpdir"
++      fi
++    fi
+ 
++    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+       for libdir in $libdirs; do
+ 	if test -n "$finish_cmds"; then
+ 	  # Do each command in the finish commands.
+@@ -1997,7 +2704,7 @@
+ 	if test -n "$finish_eval"; then
+ 	  # Do the single finish_eval.
+ 	  eval cmds=\"$finish_eval\"
+-	  $opt_dry_run || eval "$cmds" || admincmds="$admincmds
++	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+        $cmds"
+ 	fi
+       done
+@@ -2006,53 +2713,55 @@
+     # Exit here if they wanted silent mode.
+     $opt_silent && exit $EXIT_SUCCESS
+ 
+-    echo "----------------------------------------------------------------------"
+-    echo "Libraries have been installed in:"
+-    for libdir in $libdirs; do
+-      $ECHO "   $libdir"
+-    done
+-    echo
+-    echo "If you ever happen to want to link against installed libraries"
+-    echo "in a given directory, LIBDIR, you must either use libtool, and"
+-    echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+-    echo "flag during linking and do at least one of the following:"
+-    if test -n "$shlibpath_var"; then
+-      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+-      echo "     during execution"
+-    fi
+-    if test -n "$runpath_var"; then
+-      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+-      echo "     during linking"
+-    fi
+-    if test -n "$hardcode_libdir_flag_spec"; then
+-      libdir=LIBDIR
+-      eval "flag=\"$hardcode_libdir_flag_spec\""
++    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
++      echo "----------------------------------------------------------------------"
++      echo "Libraries have been installed in:"
++      for libdir in $libdirs; do
++	$ECHO "   $libdir"
++      done
++      echo
++      echo "If you ever happen to want to link against installed libraries"
++      echo "in a given directory, LIBDIR, you must either use libtool, and"
++      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
++      echo "flag during linking and do at least one of the following:"
++      if test -n "$shlibpath_var"; then
++	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
++	echo "     during execution"
++      fi
++      if test -n "$runpath_var"; then
++	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
++	echo "     during linking"
++      fi
++      if test -n "$hardcode_libdir_flag_spec"; then
++	libdir=LIBDIR
++	eval flag=\"$hardcode_libdir_flag_spec\"
+ 
+-      $ECHO "   - use the \`$flag' linker flag"
+-    fi
+-    if test -n "$admincmds"; then
+-      $ECHO "   - have your system administrator run these commands:$admincmds"
+-    fi
+-    if test -f /etc/ld.so.conf; then
+-      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+-    fi
+-    echo
++	$ECHO "   - use the \`$flag' linker flag"
++      fi
++      if test -n "$admincmds"; then
++	$ECHO "   - have your system administrator run these commands:$admincmds"
++      fi
++      if test -f /etc/ld.so.conf; then
++	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
++      fi
++      echo
+ 
+-    echo "See any operating system documentation about shared libraries for"
+-    case $host in
+-      solaris2.[6789]|solaris2.1[0-9])
+-        echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+-	echo "pages."
+-	;;
+-      *)
+-        echo "more information, such as the ld(1) and ld.so(8) manual pages."
+-        ;;
+-    esac
+-    echo "----------------------------------------------------------------------"
++      echo "See any operating system documentation about shared libraries for"
++      case $host in
++	solaris2.[6789]|solaris2.1[0-9])
++	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
++	  echo "pages."
++	  ;;
++	*)
++	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
++	  ;;
++      esac
++      echo "----------------------------------------------------------------------"
++    fi
+     exit $EXIT_SUCCESS
+ }
+ 
+-test "$mode" = finish && func_mode_finish ${1+"$@"}
++test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+ 
+ 
+ # func_mode_install arg...
+@@ -2077,7 +2786,7 @@
+     # The real first argument should be the name of the installation program.
+     # Aesthetically quote it.
+     func_quote_for_eval "$arg"
+-    install_prog="$install_prog$func_quote_for_eval_result"
++    func_append install_prog "$func_quote_for_eval_result"
+     install_shared_prog=$install_prog
+     case " $install_prog " in
+       *[\\\ /]cp\ *) install_cp=: ;;
+@@ -2097,7 +2806,7 @@
+     do
+       arg2=
+       if test -n "$dest"; then
+-	files="$files $dest"
++	func_append files " $dest"
+ 	dest=$arg
+ 	continue
+       fi
+@@ -2135,11 +2844,11 @@
+ 
+       # Aesthetically quote the argument.
+       func_quote_for_eval "$arg"
+-      install_prog="$install_prog $func_quote_for_eval_result"
++      func_append install_prog " $func_quote_for_eval_result"
+       if test -n "$arg2"; then
+ 	func_quote_for_eval "$arg2"
+       fi
+-      install_shared_prog="$install_shared_prog $func_quote_for_eval_result"
++      func_append install_shared_prog " $func_quote_for_eval_result"
+     done
+ 
+     test -z "$install_prog" && \
+@@ -2151,7 +2860,7 @@
+     if test -n "$install_override_mode" && $no_mode; then
+       if $install_cp; then :; else
+ 	func_quote_for_eval "$install_override_mode"
+-	install_shared_prog="$install_shared_prog -m $func_quote_for_eval_result"
++	func_append install_shared_prog " -m $func_quote_for_eval_result"
+       fi
+     fi
+ 
+@@ -2209,10 +2918,13 @@
+       case $file in
+       *.$libext)
+ 	# Do the static libraries later.
+-	staticlibs="$staticlibs $file"
++	func_append staticlibs " $file"
+ 	;;
+ 
+       *.la)
++	func_resolve_sysroot "$file"
++	file=$func_resolve_sysroot_result
++
+ 	# Check to see that this really is a libtool archive.
+ 	func_lalib_unsafe_p "$file" \
+ 	  || func_fatal_help "\`$file' is not a valid libtool archive"
+@@ -2226,23 +2938,30 @@
+ 	if test "X$destdir" = "X$libdir"; then
+ 	  case "$current_libdirs " in
+ 	  *" $libdir "*) ;;
+-	  *) current_libdirs="$current_libdirs $libdir" ;;
++	  *) func_append current_libdirs " $libdir" ;;
+ 	  esac
+ 	else
+ 	  # Note the libdir as a future libdir.
+ 	  case "$future_libdirs " in
+ 	  *" $libdir "*) ;;
+-	  *) future_libdirs="$future_libdirs $libdir" ;;
++	  *) func_append future_libdirs " $libdir" ;;
+ 	  esac
+ 	fi
+ 
+ 	func_dirname "$file" "/" ""
+ 	dir="$func_dirname_result"
+-	dir="$dir$objdir"
++	func_append dir "$objdir"
+ 
+ 	if test -n "$relink_command"; then
++      # Strip any trailing slash from the destination.
++      func_stripname '' '/' "$libdir"
++      destlibdir=$func_stripname_result
++
++      func_stripname '' '/' "$destdir"
++      s_destdir=$func_stripname_result
++
+ 	  # Determine the prefix the user has applied to our future dir.
+-	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
++	  inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"`
+ 
+ 	  # Don't allow the user to place us outside of our expected
+ 	  # location b/c this prevents finding dependent libraries that
+@@ -2315,7 +3034,7 @@
+ 	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+ 
+ 	# Maybe install the static library, too.
+-	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
++	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ 	;;
+ 
+       *.lo)
+@@ -2503,7 +3222,7 @@
+     test -n "$future_libdirs" && \
+       func_warning "remember to run \`$progname --finish$future_libdirs'"
+ 
+-    if test -n "$current_libdirs" && $opt_finish; then
++    if test -n "$current_libdirs"; then
+       # Maybe just do a dry run.
+       $opt_dry_run && current_libdirs=" -n$current_libdirs"
+       exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+@@ -2512,7 +3231,7 @@
+     fi
+ }
+ 
+-test "$mode" = install && func_mode_install ${1+"$@"}
++test "$opt_mode" = install && func_mode_install ${1+"$@"}
+ 
+ 
+ # func_generate_dlsyms outputname originator pic_p
+@@ -2559,6 +3278,18 @@
+ #pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+ #endif
+ 
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT_DLSYM_CONST
++#else
++# define LT_DLSYM_CONST const
++#endif
++
+ /* External symbol declarations for the compiler. */\
+ "
+ 
+@@ -2570,21 +3301,22 @@
+ 	  # Add our own program objects to the symbol list.
+ 	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ 	  for progfile in $progfiles; do
+-	    func_verbose "extracting global C symbols from \`$progfile'"
+-	    $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
++	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
++	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
++	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ 	  done
+ 
+ 	  if test -n "$exclude_expsyms"; then
+ 	    $opt_dry_run || {
+-	      $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+-	      $MV "$nlist"T "$nlist"
++	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
++	      eval '$MV "$nlist"T "$nlist"'
+ 	    }
+ 	  fi
+ 
+ 	  if test -n "$export_symbols_regex"; then
+ 	    $opt_dry_run || {
+-	      $EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T
+-	      $MV "$nlist"T "$nlist"
++	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
++	      eval '$MV "$nlist"T "$nlist"'
+ 	    }
+ 	  fi
+ 
+@@ -2593,23 +3325,23 @@
+ 	    export_symbols="$output_objdir/$outputname.exp"
+ 	    $opt_dry_run || {
+ 	      $RM $export_symbols
+-	      ${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' < "$nlist" > "$export_symbols"
++	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ 	      case $host in
+ 	      *cygwin* | *mingw* | *cegcc* )
+-                echo EXPORTS > "$output_objdir/$outputname.def"
+-                cat "$export_symbols" >> "$output_objdir/$outputname.def"
++                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
++                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ 	        ;;
+ 	      esac
+ 	    }
+ 	  else
+ 	    $opt_dry_run || {
+-	      ${SED} -e 's/\([].[*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/' < "$export_symbols" > "$output_objdir/$outputname.exp"
+-	      $GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T
+-	      $MV "$nlist"T "$nlist"
++	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
++	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
++	      eval '$MV "$nlist"T "$nlist"'
+ 	      case $host in
+ 	        *cygwin* | *mingw* | *cegcc* )
+-	          echo EXPORTS > "$output_objdir/$outputname.def"
+-	          cat "$nlist" >> "$output_objdir/$outputname.def"
++	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
++	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ 	          ;;
+ 	      esac
+ 	    }
+@@ -2620,10 +3352,52 @@
+ 	  func_verbose "extracting global C symbols from \`$dlprefile'"
+ 	  func_basename "$dlprefile"
+ 	  name="$func_basename_result"
+-	  $opt_dry_run || {
+-	    $ECHO ": $name " >> "$nlist"
+-	    eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+-	  }
++          case $host in
++	    *cygwin* | *mingw* | *cegcc* )
++	      # if an import library, we need to obtain dlname
++	      if func_win32_import_lib_p "$dlprefile"; then
++	        func_tr_sh "$dlprefile"
++	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
++	        dlprefile_dlbasename=""
++	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
++	          # Use subshell, to avoid clobbering current variable values
++	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
++	          if test -n "$dlprefile_dlname" ; then
++	            func_basename "$dlprefile_dlname"
++	            dlprefile_dlbasename="$func_basename_result"
++	          else
++	            # no lafile. user explicitly requested -dlpreopen <import library>.
++	            $sharedlib_from_linklib_cmd "$dlprefile"
++	            dlprefile_dlbasename=$sharedlib_from_linklib_result
++	          fi
++	        fi
++	        $opt_dry_run || {
++	          if test -n "$dlprefile_dlbasename" ; then
++	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
++	          else
++	            func_warning "Could not compute DLL name from $name"
++	            eval '$ECHO ": $name " >> "$nlist"'
++	          fi
++	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
++	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
++	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
++	        }
++	      else # not an import lib
++	        $opt_dry_run || {
++	          eval '$ECHO ": $name " >> "$nlist"'
++	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
++	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
++	        }
++	      fi
++	    ;;
++	    *)
++	      $opt_dry_run || {
++	        eval '$ECHO ": $name " >> "$nlist"'
++	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
++	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
++	      }
++	    ;;
++          esac
+ 	done
+ 
+ 	$opt_dry_run || {
+@@ -2661,26 +3435,9 @@
+   const char *name;
+   void *address;
+ } lt_dlsymlist;
+-"
+-	  case $host in
+-	  *cygwin* | *mingw* | *cegcc* )
+-	    echo >> "$output_objdir/$my_dlsyms" "\
+-/* DATA imports from DLLs on WIN32 con't be const, because
+-   runtime relocations are performed -- see ld's documentation
+-   on pseudo-relocs.  */"
+-	    lt_dlsym_const= ;;
+-	  *osf5*)
+-	    echo >> "$output_objdir/$my_dlsyms" "\
+-/* This system does not cope well with relocations in const data */"
+-	    lt_dlsym_const= ;;
+-	  *)
+-	    lt_dlsym_const=const ;;
+-	  esac
+-
+-	  echo >> "$output_objdir/$my_dlsyms" "\
+-extern $lt_dlsym_const lt_dlsymlist
++extern LT_DLSYM_CONST lt_dlsymlist
+ lt_${my_prefix}_LTX_preloaded_symbols[];
+-$lt_dlsym_const lt_dlsymlist
++LT_DLSYM_CONST lt_dlsymlist
+ lt_${my_prefix}_LTX_preloaded_symbols[] =
+ {\
+   { \"$my_originator\", (void *) 0 },"
+@@ -2736,7 +3493,7 @@
+ 	for arg in $LTCFLAGS; do
+ 	  case $arg in
+ 	  -pie | -fpie | -fPIE) ;;
+-	  *) symtab_cflags="$symtab_cflags $arg" ;;
++	  *) func_append symtab_cflags " $arg" ;;
+ 	  esac
+ 	done
+ 
+@@ -2796,9 +3553,11 @@
+     win32_libid_type="x86 archive import"
+     ;;
+   *ar\ archive*) # could be an import, or static
+-    if $OBJDUMP -f "$1" | $SED -e '10q' 2>/dev/null |
+-       $EGREP 'file format (pe-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+-      win32_nmres=`$NM -f posix -A "$1" |
++    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
++    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
++       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
++      func_to_tool_file "$1" func_convert_file_msys_to_w32
++      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ 	$SED -n -e '
+ 	    1,100{
+ 		/ I /{
+@@ -2827,6 +3586,131 @@
+   $ECHO "$win32_libid_type"
+ }
+ 
++# func_cygming_dll_for_implib ARG
++#
++# Platform-specific function to extract the
++# name of the DLL associated with the specified
++# import library ARG.
++# Invoked by eval'ing the libtool variable
++#    $sharedlib_from_linklib_cmd
++# Result is available in the variable
++#    $sharedlib_from_linklib_result
++func_cygming_dll_for_implib ()
++{
++  $opt_debug
++  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
++}
++
++# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
++#
++# The is the core of a fallback implementation of a
++# platform-specific function to extract the name of the
++# DLL associated with the specified import library LIBNAME.
++#
++# SECTION_NAME is either .idata$6 or .idata$7, depending
++# on the platform and compiler that created the implib.
++#
++# Echos the name of the DLL associated with the
++# specified import library.
++func_cygming_dll_for_implib_fallback_core ()
++{
++  $opt_debug
++  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
++  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
++    $SED '/^Contents of section '"$match_literal"':/{
++      # Place marker at beginning of archive member dllname section
++      s/.*/====MARK====/
++      p
++      d
++    }
++    # These lines can sometimes be longer than 43 characters, but
++    # are always uninteresting
++    /:[	 ]*file format pe[i]\{,1\}-/d
++    /^In archive [^:]*:/d
++    # Ensure marker is printed
++    /^====MARK====/p
++    # Remove all lines with less than 43 characters
++    /^.\{43\}/!d
++    # From remaining lines, remove first 43 characters
++    s/^.\{43\}//' |
++    $SED -n '
++      # Join marker and all lines until next marker into a single line
++      /^====MARK====/ b para
++      H
++      $ b para
++      b
++      :para
++      x
++      s/\n//g
++      # Remove the marker
++      s/^====MARK====//
++      # Remove trailing dots and whitespace
++      s/[\. \t]*$//
++      # Print
++      /./p' |
++    # we now have a list, one entry per line, of the stringified
++    # contents of the appropriate section of all members of the
++    # archive which possess that section. Heuristic: eliminate
++    # all those which have a first or second character that is
++    # a '.' (that is, objdump's representation of an unprintable
++    # character.) This should work for all archives with less than
++    # 0x302f exports -- but will fail for DLLs whose name actually
++    # begins with a literal '.' or a single character followed by
++    # a '.'.
++    #
++    # Of those that remain, print the first one.
++    $SED -e '/^\./d;/^.\./d;q'
++}
++
++# func_cygming_gnu_implib_p ARG
++# This predicate returns with zero status (TRUE) if
++# ARG is a GNU/binutils-style import library. Returns
++# with nonzero status (FALSE) otherwise.
++func_cygming_gnu_implib_p ()
++{
++  $opt_debug
++  func_to_tool_file "$1" func_convert_file_msys_to_w32
++  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
++  test -n "$func_cygming_gnu_implib_tmp"
++}
++
++# func_cygming_ms_implib_p ARG
++# This predicate returns with zero status (TRUE) if
++# ARG is an MS-style import library. Returns
++# with nonzero status (FALSE) otherwise.
++func_cygming_ms_implib_p ()
++{
++  $opt_debug
++  func_to_tool_file "$1" func_convert_file_msys_to_w32
++  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
++  test -n "$func_cygming_ms_implib_tmp"
++}
++
++# func_cygming_dll_for_implib_fallback ARG
++# Platform-specific function to extract the
++# name of the DLL associated with the specified
++# import library ARG.
++#
++# This fallback implementation is for use when $DLLTOOL
++# does not support the --identify-strict option.
++# Invoked by eval'ing the libtool variable
++#    $sharedlib_from_linklib_cmd
++# Result is available in the variable
++#    $sharedlib_from_linklib_result
++func_cygming_dll_for_implib_fallback ()
++{
++  $opt_debug
++  if func_cygming_gnu_implib_p "$1" ; then
++    # binutils import library
++    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
++  elif func_cygming_ms_implib_p "$1" ; then
++    # ms-generated import library
++    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
++  else
++    # unknown
++    sharedlib_from_linklib_result=""
++  fi
++}
+ 
+ 
+ # func_extract_an_archive dir oldlib
+@@ -2917,7 +3801,7 @@
+ 	    darwin_file=
+ 	    darwin_files=
+ 	    for darwin_file in $darwin_filelist; do
+-	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
++	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ 	      $LIPO -create -output "$darwin_file" $darwin_files
+ 	    done # $darwin_filelist
+ 	    $RM -rf unfat-$$
+@@ -2932,7 +3816,7 @@
+         func_extract_an_archive "$my_xdir" "$my_xabs"
+ 	;;
+       esac
+-      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
++      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+     done
+ 
+     func_extract_archives_result="$my_oldobjs"
+@@ -3014,7 +3898,110 @@
+ _LTECHO_EOF'
+ }
+     ECHO=\"$qECHO\"
+-  fi\
++  fi
++
++# Very basic option parsing. These options are (a) specific to
++# the libtool wrapper, (b) are identical between the wrapper
++# /script/ and the wrapper /executable/ which is used only on
++# windows platforms, and (c) all begin with the string "--lt-"
++# (application programs are unlikely to have options which match
++# this pattern).
++#
++# There are only two supported options: --lt-debug and
++# --lt-dump-script. There is, deliberately, no --lt-help.
++#
++# The first argument to this parsing function should be the
++# script's $0 value, followed by "$@".
++lt_option_debug=
++func_parse_lt_options ()
++{
++  lt_script_arg0=\$0
++  shift
++  for lt_opt
++  do
++    case \"\$lt_opt\" in
++    --lt-debug) lt_option_debug=1 ;;
++    --lt-dump-script)
++        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
++        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
++        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
++        cat \"\$lt_dump_D/\$lt_dump_F\"
++        exit 0
++      ;;
++    --lt-*)
++        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
++        exit 1
++      ;;
++    esac
++  done
++
++  # Print the debug banner immediately:
++  if test -n \"\$lt_option_debug\"; then
++    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
++  fi
++}
++
++# Used when --lt-debug. Prints its arguments to stdout
++# (redirection is the responsibility of the caller)
++func_lt_dump_args ()
++{
++  lt_dump_args_N=1;
++  for lt_arg
++  do
++    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
++    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
++  done
++}
++
++# Core function for launching the target application
++func_exec_program_core ()
++{
++"
++  case $host in
++  # Backslashes separate directories on plain windows
++  *-*-mingw | *-*-os2* | *-cegcc*)
++    $ECHO "\
++      if test -n \"\$lt_option_debug\"; then
++        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
++        func_lt_dump_args \${1+\"\$@\"} 1>&2
++      fi
++      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
++"
++    ;;
++
++  *)
++    $ECHO "\
++      if test -n \"\$lt_option_debug\"; then
++        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
++        func_lt_dump_args \${1+\"\$@\"} 1>&2
++      fi
++      exec \"\$progdir/\$program\" \${1+\"\$@\"}
++"
++    ;;
++  esac
++  $ECHO "\
++      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
++      exit 1
++}
++
++# A function to encapsulate launching the target application
++# Strips options in the --lt-* namespace from \$@ and
++# launches target application with the remaining arguments.
++func_exec_program ()
++{
++  for lt_wr_arg
++  do
++    case \$lt_wr_arg in
++    --lt-*) ;;
++    *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
++    esac
++    shift
++  done
++  func_exec_program_core \${1+\"\$@\"}
++}
++
++  # Parse options
++  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+ 
+   # Find the directory that this script lives in.
+   thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+@@ -3078,7 +4065,7 @@
+ 
+     # relink executable if necessary
+     if test -n \"\$relink_command\"; then
+-      if relink_command_output=\`eval \"\$relink_command\" 2>&1\`; then :
++      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+       else
+ 	$ECHO \"\$relink_command_output\" >&2
+ 	$RM \"\$progdir/\$file\"
+@@ -3102,6 +4089,18 @@
+ 
+   if test -f \"\$progdir/\$program\"; then"
+ 
++	# fixup the dll searchpath if we need to.
++	#
++	# Fix the DLL searchpath if we need to.  Do this before prepending
++	# to shlibpath, because on Windows, both are PATH and uninstalled
++	# libraries must come first.
++	if test -n "$dllsearchpath"; then
++	  $ECHO "\
++    # Add the dll search path components to the executable PATH
++    PATH=$dllsearchpath:\$PATH
++"
++	fi
++
+ 	# Export our shlibpath_var if we have one.
+ 	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ 	  $ECHO "\
+@@ -3116,35 +4115,10 @@
+ "
+ 	fi
+ 
+-	# fixup the dll searchpath if we need to.
+-	if test -n "$dllsearchpath"; then
+-	  $ECHO "\
+-    # Add the dll search path components to the executable PATH
+-    PATH=$dllsearchpath:\$PATH
+-"
+-	fi
+-
+ 	$ECHO "\
+     if test \"\$libtool_execute_magic\" != \"$magic\"; then
+       # Run the actual program with our arguments.
+-"
+-	case $host in
+-	# Backslashes separate directories on plain windows
+-	*-*-mingw | *-*-os2* | *-cegcc*)
+-	  $ECHO "\
+-      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+-"
+-	  ;;
+-
+-	*)
+-	  $ECHO "\
+-      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+-"
+-	  ;;
+-	esac
+-	$ECHO "\
+-      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+-      exit 1
++      func_exec_program \${1+\"\$@\"}
+     fi
+   else
+     # The program doesn't exist.
+@@ -3158,166 +4132,6 @@
+ }
+ 
+ 
+-# func_to_host_path arg
+-#
+-# Convert paths to host format when used with build tools.
+-# Intended for use with "native" mingw (where libtool itself
+-# is running under the msys shell), or in the following cross-
+-# build environments:
+-#    $build          $host
+-#    mingw (msys)    mingw  [e.g. native]
+-#    cygwin          mingw
+-#    *nix + wine     mingw
+-# where wine is equipped with the `winepath' executable.
+-# In the native mingw case, the (msys) shell automatically
+-# converts paths for any non-msys applications it launches,
+-# but that facility isn't available from inside the cwrapper.
+-# Similar accommodations are necessary for $host mingw and
+-# $build cygwin.  Calling this function does no harm for other
+-# $host/$build combinations not listed above.
+-#
+-# ARG is the path (on $build) that should be converted to
+-# the proper representation for $host. The result is stored
+-# in $func_to_host_path_result.
+-func_to_host_path ()
+-{
+-  func_to_host_path_result="$1"
+-  if test -n "$1"; then
+-    case $host in
+-      *mingw* )
+-        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+-        case $build in
+-          *mingw* ) # actually, msys
+-            # awkward: cmd appends spaces to result
+-            func_to_host_path_result=`( cmd //c echo "$1" ) 2>/dev/null |
+-              $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+-            ;;
+-          *cygwin* )
+-            func_to_host_path_result=`cygpath -w "$1" |
+-	      $SED -e "$lt_sed_naive_backslashify"`
+-            ;;
+-          * )
+-            # Unfortunately, winepath does not exit with a non-zero
+-            # error code, so we are forced to check the contents of
+-            # stdout. On the other hand, if the command is not
+-            # found, the shell will set an exit code of 127 and print
+-            # *an error message* to stdout. So we must check for both
+-            # error code of zero AND non-empty stdout, which explains
+-            # the odd construction:
+-            func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+-            if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
+-              func_to_host_path_result=`$ECHO "$func_to_host_path_tmp1" |
+-                $SED -e "$lt_sed_naive_backslashify"`
+-            else
+-              # Allow warning below.
+-              func_to_host_path_result=
+-            fi
+-            ;;
+-        esac
+-        if test -z "$func_to_host_path_result" ; then
+-          func_error "Could not determine host path corresponding to"
+-          func_error "  \`$1'"
+-          func_error "Continuing, but uninstalled executables may not work."
+-          # Fallback:
+-          func_to_host_path_result="$1"
+-        fi
+-        ;;
+-    esac
+-  fi
+-}
+-# end: func_to_host_path
+-
+-# func_to_host_pathlist arg
+-#
+-# Convert pathlists to host format when used with build tools.
+-# See func_to_host_path(), above. This function supports the
+-# following $build/$host combinations (but does no harm for
+-# combinations not listed here):
+-#    $build          $host
+-#    mingw (msys)    mingw  [e.g. native]
+-#    cygwin          mingw
+-#    *nix + wine     mingw
+-#
+-# Path separators are also converted from $build format to
+-# $host format. If ARG begins or ends with a path separator
+-# character, it is preserved (but converted to $host format)
+-# on output.
+-#
+-# ARG is a pathlist (on $build) that should be converted to
+-# the proper representation on $host. The result is stored
+-# in $func_to_host_pathlist_result.
+-func_to_host_pathlist ()
+-{
+-  func_to_host_pathlist_result="$1"
+-  if test -n "$1"; then
+-    case $host in
+-      *mingw* )
+-        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+-        # Remove leading and trailing path separator characters from
+-        # ARG. msys behavior is inconsistent here, cygpath turns them
+-        # into '.;' and ';.', and winepath ignores them completely.
+-	func_stripname : : "$1"
+-        func_to_host_pathlist_tmp1=$func_stripname_result
+-        case $build in
+-          *mingw* ) # Actually, msys.
+-            # Awkward: cmd appends spaces to result.
+-            func_to_host_pathlist_result=`
+-	      ( cmd //c echo "$func_to_host_pathlist_tmp1" ) 2>/dev/null |
+-	      $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+-            ;;
+-          *cygwin* )
+-            func_to_host_pathlist_result=`cygpath -w -p "$func_to_host_pathlist_tmp1" |
+-              $SED -e "$lt_sed_naive_backslashify"`
+-            ;;
+-          * )
+-            # unfortunately, winepath doesn't convert pathlists
+-            func_to_host_pathlist_result=""
+-            func_to_host_pathlist_oldIFS=$IFS
+-            IFS=:
+-            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
+-              IFS=$func_to_host_pathlist_oldIFS
+-              if test -n "$func_to_host_pathlist_f" ; then
+-                func_to_host_path "$func_to_host_pathlist_f"
+-                if test -n "$func_to_host_path_result" ; then
+-                  if test -z "$func_to_host_pathlist_result" ; then
+-                    func_to_host_pathlist_result="$func_to_host_path_result"
+-                  else
+-                    func_append func_to_host_pathlist_result ";$func_to_host_path_result"
+-                  fi
+-                fi
+-              fi
+-            done
+-            IFS=$func_to_host_pathlist_oldIFS
+-            ;;
+-        esac
+-        if test -z "$func_to_host_pathlist_result"; then
+-          func_error "Could not determine the host path(s) corresponding to"
+-          func_error "  \`$1'"
+-          func_error "Continuing, but uninstalled executables may not work."
+-          # Fallback. This may break if $1 contains DOS-style drive
+-          # specifications. The fix is not to complicate the expression
+-          # below, but for the user to provide a working wine installation
+-          # with winepath so that path translation in the cross-to-mingw
+-          # case works properly.
+-          lt_replace_pathsep_nix_to_dos="s|:|;|g"
+-          func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
+-            $SED -e "$lt_replace_pathsep_nix_to_dos"`
+-        fi
+-        # Now, add the leading and trailing path separators back
+-        case "$1" in
+-          :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+-            ;;
+-        esac
+-        case "$1" in
+-          *: ) func_append func_to_host_pathlist_result ";"
+-            ;;
+-        esac
+-        ;;
+-    esac
+-  fi
+-}
+-# end: func_to_host_pathlist
+-
+ # func_emit_cwrapperexe_src
+ # emit the source code for a wrapper executable on stdout
+ # Must ONLY be called from within func_mode_link because
+@@ -3334,10 +4148,6 @@
+ 
+    This wrapper executable should never be moved out of the build directory.
+    If it is, it will not operate correctly.
+-
+-   Currently, it simply execs the wrapper *script* "$SHELL $output",
+-   but could eventually absorb all of the scripts functionality and
+-   exec $objdir/$outputname directly.
+ */
+ EOF
+ 	    cat <<"EOF"
+@@ -3462,22 +4272,13 @@
+   if (stale) { free ((void *) stale); stale = 0; } \
+ } while (0)
+ 
+-#undef LTWRAPPER_DEBUGPRINTF
+-#if defined LT_DEBUGWRAPPER
+-# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
+-static void
+-ltwrapper_debugprintf (const char *fmt, ...)
+-{
+-    va_list args;
+-    va_start (args, fmt);
+-    (void) vfprintf (stderr, fmt, args);
+-    va_end (args);
+-}
++#if defined(LT_DEBUGWRAPPER)
++static int lt_debug = 1;
+ #else
+-# define LTWRAPPER_DEBUGPRINTF(args)
++static int lt_debug = 0;
+ #endif
+ 
+-const char *program_name = NULL;
++const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+ 
+ void *xmalloc (size_t num);
+ char *xstrdup (const char *string);
+@@ -3487,7 +4288,10 @@
+ int make_executable (const char *path);
+ int check_executable (const char *path);
+ char *strendzap (char *str, const char *pat);
+-void lt_fatal (const char *message, ...);
++void lt_debugprintf (const char *file, int line, const char *fmt, ...);
++void lt_fatal (const char *file, int line, const char *message, ...);
++static const char *nonnull (const char *s);
++static const char *nonempty (const char *s);
+ void lt_setenv (const char *name, const char *value);
+ char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+ void lt_update_exe_path (const char *name, const char *value);
+@@ -3497,14 +4301,14 @@
+ EOF
+ 
+ 	    cat <<EOF
+-const char * MAGIC_EXE = "$magic_exe";
++volatile const char * MAGIC_EXE = "$magic_exe";
+ const char * LIB_PATH_VARNAME = "$shlibpath_var";
+ EOF
+ 
+ 	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+-              func_to_host_pathlist "$temp_rpath"
++              func_to_host_path "$temp_rpath"
+ 	      cat <<EOF
+-const char * LIB_PATH_VALUE   = "$func_to_host_pathlist_result";
++const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+ EOF
+ 	    else
+ 	      cat <<"EOF"
+@@ -3513,10 +4317,10 @@
+ 	    fi
+ 
+ 	    if test -n "$dllsearchpath"; then
+-              func_to_host_pathlist "$dllsearchpath:"
++              func_to_host_path "$dllsearchpath:"
+ 	      cat <<EOF
+ const char * EXE_PATH_VARNAME = "PATH";
+-const char * EXE_PATH_VALUE   = "$func_to_host_pathlist_result";
++const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+ EOF
+ 	    else
+ 	      cat <<"EOF"
+@@ -3539,12 +4343,10 @@
+ 	    cat <<"EOF"
+ 
+ #define LTWRAPPER_OPTION_PREFIX         "--lt-"
+-#define LTWRAPPER_OPTION_PREFIX_LENGTH  5
+ 
+-static const size_t opt_prefix_len         = LTWRAPPER_OPTION_PREFIX_LENGTH;
+ static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+-
+ static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
++static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+ 
+ int
+ main (int argc, char *argv[])
+@@ -3561,10 +4363,13 @@
+   int i;
+ 
+   program_name = (char *) xstrdup (base_name (argv[0]));
+-  LTWRAPPER_DEBUGPRINTF (("(main) argv[0]      : %s\n", argv[0]));
+-  LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
++  newargz = XMALLOC (char *, argc + 1);
+ 
+-  /* very simple arg parsing; don't want to rely on getopt */
++  /* very simple arg parsing; don't want to rely on getopt
++   * also, copy all non cwrapper options to newargz, except
++   * argz[0], which is handled differently
++   */
++  newargc=0;
+   for (i = 1; i < argc; i++)
+     {
+       if (strcmp (argv[i], dumpscript_opt) == 0)
+@@ -3581,21 +4386,54 @@
+ 	  lt_dump_script (stdout);
+ 	  return 0;
+ 	}
++      if (strcmp (argv[i], debug_opt) == 0)
++	{
++          lt_debug = 1;
++          continue;
++	}
++      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
++        {
++          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
++             namespace, but it is not one of the ones we know about and
++             have already dealt with, above (inluding dump-script), then
++             report an error. Otherwise, targets might begin to believe
++             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
++             namespace. The first time any user complains about this, we'll
++             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
++             or a configure.ac-settable value.
++           */
++          lt_fatal (__FILE__, __LINE__,
++		    "unrecognized %s option: '%s'",
++                    ltwrapper_option_prefix, argv[i]);
++        }
++      /* otherwise ... */
++      newargz[++newargc] = xstrdup (argv[i]);
+     }
++  newargz[++newargc] = NULL;
++
++EOF
++	    cat <<EOF
++  /* The GNU banner must be the first non-error debug message */
++  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
++EOF
++	    cat <<"EOF"
++  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
++  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+ 
+-  newargz = XMALLOC (char *, argc + 1);
+   tmp_pathspec = find_executable (argv[0]);
+   if (tmp_pathspec == NULL)
+-    lt_fatal ("Couldn't find %s", argv[0]);
+-  LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
+-			  tmp_pathspec));
++    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
++  lt_debugprintf (__FILE__, __LINE__,
++                  "(main) found exe (before symlink chase) at: %s\n",
++		  tmp_pathspec);
+ 
+   actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+-  LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
+-			  actual_cwrapper_path));
++  lt_debugprintf (__FILE__, __LINE__,
++                  "(main) found exe (after symlink chase) at: %s\n",
++		  actual_cwrapper_path);
+   XFREE (tmp_pathspec);
+ 
+-  actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
++  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+   strendzap (actual_cwrapper_path, actual_cwrapper_name);
+ 
+   /* wrapper name transforms */
+@@ -3613,8 +4451,9 @@
+   target_name = tmp_pathspec;
+   tmp_pathspec = 0;
+ 
+-  LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+-			  target_name));
++  lt_debugprintf (__FILE__, __LINE__,
++		  "(main) libtool target name: %s\n",
++		  target_name);
+ EOF
+ 
+ 	    cat <<EOF
+@@ -3664,35 +4503,19 @@
+ 
+   lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+   lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+-  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
++  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
++     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
++     because on Windows, both *_VARNAMEs are PATH but uninstalled
++     libraries must come first. */
+   lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
++  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+ 
+-  newargc=0;
+-  for (i = 1; i < argc; i++)
+-    {
+-      if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
+-        {
+-          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+-             namespace, but it is not one of the ones we know about and
+-             have already dealt with, above (inluding dump-script), then
+-             report an error. Otherwise, targets might begin to believe
+-             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+-             namespace. The first time any user complains about this, we'll
+-             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+-             or a configure.ac-settable value.
+-           */
+-          lt_fatal ("Unrecognized option in %s namespace: '%s'",
+-                    ltwrapper_option_prefix, argv[i]);
+-        }
+-      /* otherwise ... */
+-      newargz[++newargc] = xstrdup (argv[i]);
+-    }
+-  newargz[++newargc] = NULL;
+-
+-  LTWRAPPER_DEBUGPRINTF     (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
++  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
++		  nonnull (lt_argv_zero));
+   for (i = 0; i < newargc; i++)
+     {
+-      LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
++      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
++		      i, nonnull (newargz[i]));
+     }
+ 
+ EOF
+@@ -3706,7 +4529,9 @@
+   if (rval == -1)
+     {
+       /* failed to start process */
+-      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
++      lt_debugprintf (__FILE__, __LINE__,
++		      "(main) failed to launch target \"%s\": %s\n",
++		      lt_argv_zero, nonnull (strerror (errno)));
+       return 127;
+     }
+   return rval;
+@@ -3728,7 +4553,7 @@
+ {
+   void *p = (void *) malloc (num);
+   if (!p)
+-    lt_fatal ("Memory exhausted");
++    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+ 
+   return p;
+ }
+@@ -3762,8 +4587,8 @@
+ {
+   struct stat st;
+ 
+-  LTWRAPPER_DEBUGPRINTF (("(check_executable)  : %s\n",
+-			  path ? (*path ? path : "EMPTY!") : "NULL!"));
++  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
++                  nonempty (path));
+   if ((!path) || (!*path))
+     return 0;
+ 
+@@ -3780,8 +4605,8 @@
+   int rval = 0;
+   struct stat st;
+ 
+-  LTWRAPPER_DEBUGPRINTF (("(make_executable)   : %s\n",
+-			  path ? (*path ? path : "EMPTY!") : "NULL!"));
++  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
++                  nonempty (path));
+   if ((!path) || (!*path))
+     return 0;
+ 
+@@ -3807,8 +4632,8 @@
+   int tmp_len;
+   char *concat_name;
+ 
+-  LTWRAPPER_DEBUGPRINTF (("(find_executable)   : %s\n",
+-			  wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
++  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
++                  nonempty (wrapper));
+ 
+   if ((wrapper == NULL) || (*wrapper == '\0'))
+     return NULL;
+@@ -3861,7 +4686,8 @@
+ 		{
+ 		  /* empty path: current directory */
+ 		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+-		    lt_fatal ("getcwd failed");
++		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
++                              nonnull (strerror (errno)));
+ 		  tmp_len = strlen (tmp);
+ 		  concat_name =
+ 		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+@@ -3886,7 +4712,8 @@
+     }
+   /* Relative path | not found in path: prepend cwd */
+   if (getcwd (tmp, LT_PATHMAX) == NULL)
+-    lt_fatal ("getcwd failed");
++    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
++              nonnull (strerror (errno)));
+   tmp_len = strlen (tmp);
+   concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+   memcpy (concat_name, tmp, tmp_len);
+@@ -3912,8 +4739,9 @@
+   int has_symlinks = 0;
+   while (strlen (tmp_pathspec) && !has_symlinks)
+     {
+-      LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
+-			      tmp_pathspec));
++      lt_debugprintf (__FILE__, __LINE__,
++		      "checking path component for symlinks: %s\n",
++		      tmp_pathspec);
+       if (lstat (tmp_pathspec, &s) == 0)
+ 	{
+ 	  if (S_ISLNK (s.st_mode) != 0)
+@@ -3935,8 +4763,9 @@
+ 	}
+       else
+ 	{
+-	  char *errstr = strerror (errno);
+-	  lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
++	  lt_fatal (__FILE__, __LINE__,
++		    "error accessing file \"%s\": %s",
++		    tmp_pathspec, nonnull (strerror (errno)));
+ 	}
+     }
+   XFREE (tmp_pathspec);
+@@ -3949,7 +4778,8 @@
+   tmp_pathspec = realpath (pathspec, buf);
+   if (tmp_pathspec == 0)
+     {
+-      lt_fatal ("Could not follow symlinks for %s", pathspec);
++      lt_fatal (__FILE__, __LINE__,
++		"could not follow symlinks for %s", pathspec);
+     }
+   return xstrdup (tmp_pathspec);
+ #endif
+@@ -3975,11 +4805,25 @@
+   return str;
+ }
+ 
++void
++lt_debugprintf (const char *file, int line, const char *fmt, ...)
++{
++  va_list args;
++  if (lt_debug)
++    {
++      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
++      va_start (args, fmt);
++      (void) vfprintf (stderr, fmt, args);
++      va_end (args);
++    }
++}
++
+ static void
+-lt_error_core (int exit_status, const char *mode,
++lt_error_core (int exit_status, const char *file,
++	       int line, const char *mode,
+ 	       const char *message, va_list ap)
+ {
+-  fprintf (stderr, "%s: %s: ", program_name, mode);
++  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+   vfprintf (stderr, message, ap);
+   fprintf (stderr, ".\n");
+ 
+@@ -3988,20 +4832,32 @@
+ }
+ 
+ void
+-lt_fatal (const char *message, ...)
++lt_fatal (const char *file, int line, const char *message, ...)
+ {
+   va_list ap;
+   va_start (ap, message);
+-  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
++  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+   va_end (ap);
+ }
+ 
++static const char *
++nonnull (const char *s)
++{
++  return s ? s : "(null)";
++}
++
++static const char *
++nonempty (const char *s)
++{
++  return (s && !*s) ? "(empty)" : nonnull (s);
++}
++
+ void
+ lt_setenv (const char *name, const char *value)
+ {
+-  LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+-                          (name ? name : "<NULL>"),
+-                          (value ? value : "<NULL>")));
++  lt_debugprintf (__FILE__, __LINE__,
++		  "(lt_setenv) setting '%s' to '%s'\n",
++                  nonnull (name), nonnull (value));
+   {
+ #ifdef HAVE_SETENV
+     /* always make a copy, for consistency with !HAVE_SETENV */
+@@ -4049,9 +4905,9 @@
+ void
+ lt_update_exe_path (const char *name, const char *value)
+ {
+-  LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+-                          (name ? name : "<NULL>"),
+-                          (value ? value : "<NULL>")));
++  lt_debugprintf (__FILE__, __LINE__,
++		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
++                  nonnull (name), nonnull (value));
+ 
+   if (name && *name && value && *value)
+     {
+@@ -4070,9 +4926,9 @@
+ void
+ lt_update_lib_path (const char *name, const char *value)
+ {
+-  LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+-                          (name ? name : "<NULL>"),
+-                          (value ? value : "<NULL>")));
++  lt_debugprintf (__FILE__, __LINE__,
++		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
++                  nonnull (name), nonnull (value));
+ 
+   if (name && *name && value && *value)
+     {
+@@ -4222,7 +5078,7 @@
+ func_win32_import_lib_p ()
+ {
+     $opt_debug
+-    case `eval "$file_magic_cmd \"\$1\" 2>/dev/null" | $SED -e 10q` in
++    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+     *import*) : ;;
+     *) false ;;
+     esac
+@@ -4401,9 +5257,9 @@
+ 	    ;;
+ 	  *)
+ 	    if test "$prev" = dlfiles; then
+-	      dlfiles="$dlfiles $arg"
++	      func_append dlfiles " $arg"
+ 	    else
+-	      dlprefiles="$dlprefiles $arg"
++	      func_append dlprefiles " $arg"
+ 	    fi
+ 	    prev=
+ 	    continue
+@@ -4427,7 +5283,7 @@
+ 	    *-*-darwin*)
+ 	      case "$deplibs " in
+ 		*" $qarg.ltframework "*) ;;
+-		*) deplibs="$deplibs $qarg.ltframework" # this is fixed later
++		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+ 		   ;;
+ 	      esac
+ 	      ;;
+@@ -4446,7 +5302,7 @@
+ 	    moreargs=
+ 	    for fil in `cat "$save_arg"`
+ 	    do
+-#	      moreargs="$moreargs $fil"
++#	      func_append moreargs " $fil"
+ 	      arg=$fil
+ 	      # A libtool-controlled object.
+ 
+@@ -4475,7 +5331,7 @@
+ 
+ 		  if test "$prev" = dlfiles; then
+ 		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+-		      dlfiles="$dlfiles $pic_object"
++		      func_append dlfiles " $pic_object"
+ 		      prev=
+ 		      continue
+ 		    else
+@@ -4487,7 +5343,7 @@
+ 		  # CHECK ME:  I think I busted this.  -Ossama
+ 		  if test "$prev" = dlprefiles; then
+ 		    # Preload the old-style object.
+-		    dlprefiles="$dlprefiles $pic_object"
++		    func_append dlprefiles " $pic_object"
+ 		    prev=
+ 		  fi
+ 
+@@ -4557,12 +5413,12 @@
+ 	  if test "$prev" = rpath; then
+ 	    case "$rpath " in
+ 	    *" $arg "*) ;;
+-	    *) rpath="$rpath $arg" ;;
++	    *) func_append rpath " $arg" ;;
+ 	    esac
+ 	  else
+ 	    case "$xrpath " in
+ 	    *" $arg "*) ;;
+-	    *) xrpath="$xrpath $arg" ;;
++	    *) func_append xrpath " $arg" ;;
+ 	    esac
+ 	  fi
+ 	  prev=
+@@ -4574,28 +5430,28 @@
+ 	  continue
+ 	  ;;
+ 	weak)
+-	  weak_libs="$weak_libs $arg"
++	  func_append weak_libs " $arg"
+ 	  prev=
+ 	  continue
+ 	  ;;
+ 	xcclinker)
+-	  linker_flags="$linker_flags $qarg"
+-	  compiler_flags="$compiler_flags $qarg"
++	  func_append linker_flags " $qarg"
++	  func_append compiler_flags " $qarg"
+ 	  prev=
+ 	  func_append compile_command " $qarg"
+ 	  func_append finalize_command " $qarg"
+ 	  continue
+ 	  ;;
+ 	xcompiler)
+-	  compiler_flags="$compiler_flags $qarg"
++	  func_append compiler_flags " $qarg"
+ 	  prev=
+ 	  func_append compile_command " $qarg"
+ 	  func_append finalize_command " $qarg"
+ 	  continue
+ 	  ;;
+ 	xlinker)
+-	  linker_flags="$linker_flags $qarg"
+-	  compiler_flags="$compiler_flags $wl$qarg"
++	  func_append linker_flags " $qarg"
++	  func_append compiler_flags " $wl$qarg"
+ 	  prev=
+ 	  func_append compile_command " $wl$qarg"
+ 	  func_append finalize_command " $wl$qarg"
+@@ -4686,15 +5542,16 @@
+ 	;;
+ 
+       -L*)
+-	func_stripname '-L' '' "$arg"
+-	dir=$func_stripname_result
+-	if test -z "$dir"; then
++	func_stripname "-L" '' "$arg"
++	if test -z "$func_stripname_result"; then
+ 	  if test "$#" -gt 0; then
+ 	    func_fatal_error "require no space between \`-L' and \`$1'"
+ 	  else
+ 	    func_fatal_error "need path for \`-L' option"
+ 	  fi
+ 	fi
++	func_resolve_sysroot "$func_stripname_result"
++	dir=$func_resolve_sysroot_result
+ 	# We need an absolute path.
+ 	case $dir in
+ 	[\\/]* | [A-Za-z]:[\\/]*) ;;
+@@ -4706,10 +5563,16 @@
+ 	  ;;
+ 	esac
+ 	case "$deplibs " in
+-	*" -L$dir "*) ;;
++	*" -L$dir "* | *" $arg "*)
++	  # Will only happen for absolute or sysroot arguments
++	  ;;
+ 	*)
+-	  deplibs="$deplibs -L$dir"
+-	  lib_search_path="$lib_search_path $dir"
++	  # Preserve sysroot, but never include relative directories
++	  case $dir in
++	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
++	    *) func_append deplibs " -L$dir" ;;
++	  esac
++	  func_append lib_search_path " $dir"
+ 	  ;;
+ 	esac
+ 	case $host in
+@@ -4718,12 +5581,12 @@
+ 	  case :$dllsearchpath: in
+ 	  *":$dir:"*) ;;
+ 	  ::) dllsearchpath=$dir;;
+-	  *) dllsearchpath="$dllsearchpath:$dir";;
++	  *) func_append dllsearchpath ":$dir";;
+ 	  esac
+ 	  case :$dllsearchpath: in
+ 	  *":$testbindir:"*) ;;
+ 	  ::) dllsearchpath=$testbindir;;
+-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
++	  *) func_append dllsearchpath ":$testbindir";;
+ 	  esac
+ 	  ;;
+ 	esac
+@@ -4747,7 +5610,7 @@
+ 	    ;;
+ 	  *-*-rhapsody* | *-*-darwin1.[012])
+ 	    # Rhapsody C and math libraries are in the System framework
+-	    deplibs="$deplibs System.ltframework"
++	    func_append deplibs " System.ltframework"
+ 	    continue
+ 	    ;;
+ 	  *-*-sco3.2v5* | *-*-sco5v6*)
+@@ -4758,9 +5621,6 @@
+ 	    # Compiler inserts libc in the correct place for threads to work
+ 	    test "X$arg" = "X-lc" && continue
+ 	    ;;
+-	  *-*-linux*)
+-	    test "X$arg" = "X-lc" && continue
+-	    ;;
+ 	  esac
+ 	elif test "X$arg" = "X-lc_r"; then
+ 	 case $host in
+@@ -4770,7 +5630,7 @@
+ 	   ;;
+ 	 esac
+ 	fi
+-	deplibs="$deplibs $arg"
++	func_append deplibs " $arg"
+ 	continue
+ 	;;
+ 
+@@ -4782,8 +5642,8 @@
+       # Tru64 UNIX uses -model [arg] to determine the layout of C++
+       # classes, name mangling, and exception handling.
+       # Darwin uses the -arch flag to determine output architecture.
+-      -model|-arch|-isysroot)
+-	compiler_flags="$compiler_flags $arg"
++      -model|-arch|-isysroot|--sysroot)
++	func_append compiler_flags " $arg"
+ 	func_append compile_command " $arg"
+ 	func_append finalize_command " $arg"
+ 	prev=xcompiler
+@@ -4791,12 +5651,12 @@
+ 	;;
+ 
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+-	compiler_flags="$compiler_flags $arg"
++	func_append compiler_flags " $arg"
+ 	func_append compile_command " $arg"
+ 	func_append finalize_command " $arg"
+ 	case "$new_inherited_linker_flags " in
+ 	    *" $arg "*) ;;
+-	    * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
++	    * ) func_append new_inherited_linker_flags " $arg" ;;
+ 	esac
+ 	continue
+ 	;;
+@@ -4863,13 +5723,17 @@
+ 	# We need an absolute path.
+ 	case $dir in
+ 	[\\/]* | [A-Za-z]:[\\/]*) ;;
++	=*)
++	  func_stripname '=' '' "$dir"
++	  dir=$lt_sysroot$func_stripname_result
++	  ;;
+ 	*)
+ 	  func_fatal_error "only absolute run-paths are allowed"
+ 	  ;;
+ 	esac
+ 	case "$xrpath " in
+ 	*" $dir "*) ;;
+-	*) xrpath="$xrpath $dir" ;;
++	*) func_append xrpath " $dir" ;;
+ 	esac
+ 	continue
+ 	;;
+@@ -4922,8 +5786,8 @@
+ 	for flag in $args; do
+ 	  IFS="$save_ifs"
+           func_quote_for_eval "$flag"
+-	  arg="$arg $func_quote_for_eval_result"
+-	  compiler_flags="$compiler_flags $func_quote_for_eval_result"
++	  func_append arg " $func_quote_for_eval_result"
++	  func_append compiler_flags " $func_quote_for_eval_result"
+ 	done
+ 	IFS="$save_ifs"
+ 	func_stripname ' ' '' "$arg"
+@@ -4938,9 +5802,9 @@
+ 	for flag in $args; do
+ 	  IFS="$save_ifs"
+           func_quote_for_eval "$flag"
+-	  arg="$arg $wl$func_quote_for_eval_result"
+-	  compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
+-	  linker_flags="$linker_flags $func_quote_for_eval_result"
++	  func_append arg " $wl$func_quote_for_eval_result"
++	  func_append compiler_flags " $wl$func_quote_for_eval_result"
++	  func_append linker_flags " $func_quote_for_eval_result"
+ 	done
+ 	IFS="$save_ifs"
+ 	func_stripname ' ' '' "$arg"
+@@ -4968,24 +5832,27 @@
+ 	arg="$func_quote_for_eval_result"
+ 	;;
+ 
+-      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+-      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+-      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+-      # +DA*, +DD* enable 64-bit mode on the HP compiler
+-      # -q* pass through compiler args for the IBM compiler
+-      # -m*, -t[45]*, -txscale* pass through architecture-specific
+-      # compiler args for GCC
+-      # -F/path gives path to uninstalled frameworks, gcc on darwin
+-      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+-      # @file GCC response files
+-      # -tp=* Portland pgcc target processor selection
++      # Flags to be passed through unchanged, with rationale:
++      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
++      # -r[0-9][0-9]*        specify processor for the SGI compiler
++      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
++      # +DA*, +DD*           enable 64-bit mode for the HP compiler
++      # -q*                  compiler args for the IBM compiler
++      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
++      # -F/path              path to uninstalled frameworks, gcc on darwin
++      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
++      # @file                GCC response files
++      # -tp=*                Portland pgcc target processor selection
++      # --sysroot=*          for sysroot support
++      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+-      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*)
++      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
++      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+         func_quote_for_eval "$arg"
+ 	arg="$func_quote_for_eval_result"
+         func_append compile_command " $arg"
+         func_append finalize_command " $arg"
+-        compiler_flags="$compiler_flags $arg"
++        func_append compiler_flags " $arg"
+         continue
+         ;;
+ 
+@@ -4997,7 +5864,7 @@
+ 
+       *.$objext)
+ 	# A standard object.
+-	objs="$objs $arg"
++	func_append objs " $arg"
+ 	;;
+ 
+       *.lo)
+@@ -5028,7 +5895,7 @@
+ 
+ 	    if test "$prev" = dlfiles; then
+ 	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+-		dlfiles="$dlfiles $pic_object"
++		func_append dlfiles " $pic_object"
+ 		prev=
+ 		continue
+ 	      else
+@@ -5040,7 +5907,7 @@
+ 	    # CHECK ME:  I think I busted this.  -Ossama
+ 	    if test "$prev" = dlprefiles; then
+ 	      # Preload the old-style object.
+-	      dlprefiles="$dlprefiles $pic_object"
++	      func_append dlprefiles " $pic_object"
+ 	      prev=
+ 	    fi
+ 
+@@ -5085,24 +5952,25 @@
+ 
+       *.$libext)
+ 	# An archive.
+-	deplibs="$deplibs $arg"
+-	old_deplibs="$old_deplibs $arg"
++	func_append deplibs " $arg"
++	func_append old_deplibs " $arg"
+ 	continue
+ 	;;
+ 
+       *.la)
+ 	# A libtool-controlled library.
+ 
++	func_resolve_sysroot "$arg"
+ 	if test "$prev" = dlfiles; then
+ 	  # This library was specified with -dlopen.
+-	  dlfiles="$dlfiles $arg"
++	  func_append dlfiles " $func_resolve_sysroot_result"
+ 	  prev=
+ 	elif test "$prev" = dlprefiles; then
+ 	  # The library was specified with -dlpreopen.
+-	  dlprefiles="$dlprefiles $arg"
++	  func_append dlprefiles " $func_resolve_sysroot_result"
+ 	  prev=
+ 	else
+-	  deplibs="$deplibs $arg"
++	  func_append deplibs " $func_resolve_sysroot_result"
+ 	fi
+ 	continue
+ 	;;
+@@ -5127,7 +5995,7 @@
+       func_fatal_help "the \`$prevarg' option requires an argument"
+ 
+     if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+-      eval "arg=\"$export_dynamic_flag_spec\""
++      eval arg=\"$export_dynamic_flag_spec\"
+       func_append compile_command " $arg"
+       func_append finalize_command " $arg"
+     fi
+@@ -5144,11 +6012,13 @@
+     else
+       shlib_search_path=
+     fi
+-    eval "sys_lib_search_path=\"$sys_lib_search_path_spec\""
+-    eval "sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\""
++    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
++    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+ 
+     func_dirname "$output" "/" ""
+     output_objdir="$func_dirname_result$objdir"
++    func_to_tool_file "$output_objdir/"
++    tool_output_objdir=$func_to_tool_file_result
+     # Create the object directory.
+     func_mkdir_p "$output_objdir"
+ 
+@@ -5169,12 +6039,12 @@
+     # Find all interdependent deplibs by searching for libraries
+     # that are linked more than once (e.g. -la -lb -la)
+     for deplib in $deplibs; do
+-      if $opt_duplicate_deps ; then
++      if $opt_preserve_dup_deps ; then
+ 	case "$libs " in
+-	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
++	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ 	esac
+       fi
+-      libs="$libs $deplib"
++      func_append libs " $deplib"
+     done
+ 
+     if test "$linkmode" = lib; then
+@@ -5187,9 +6057,9 @@
+       if $opt_duplicate_compiler_generated_deps; then
+ 	for pre_post_dep in $predeps $postdeps; do
+ 	  case "$pre_post_deps " in
+-	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
++	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ 	  esac
+-	  pre_post_deps="$pre_post_deps $pre_post_dep"
++	  func_append pre_post_deps " $pre_post_dep"
+ 	done
+       fi
+       pre_post_deps=
+@@ -5256,8 +6126,9 @@
+ 	for lib in $dlprefiles; do
+ 	  # Ignore non-libtool-libs
+ 	  dependency_libs=
++	  func_resolve_sysroot "$lib"
+ 	  case $lib in
+-	  *.la)	func_source "$lib" ;;
++	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+ 	  esac
+ 
+ 	  # Collect preopened libtool deplibs, except any this library
+@@ -5267,7 +6138,7 @@
+             deplib_base=$func_basename_result
+ 	    case " $weak_libs " in
+ 	    *" $deplib_base "*) ;;
+-	    *) deplibs="$deplibs $deplib" ;;
++	    *) func_append deplibs " $deplib" ;;
+ 	    esac
+ 	  done
+ 	done
+@@ -5288,11 +6159,11 @@
+ 	    compile_deplibs="$deplib $compile_deplibs"
+ 	    finalize_deplibs="$deplib $finalize_deplibs"
+ 	  else
+-	    compiler_flags="$compiler_flags $deplib"
++	    func_append compiler_flags " $deplib"
+ 	    if test "$linkmode" = lib ; then
+ 		case "$new_inherited_linker_flags " in
+ 		    *" $deplib "*) ;;
+-		    * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
++		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+ 		esac
+ 	    fi
+ 	  fi
+@@ -5377,7 +6248,7 @@
+ 	    if test "$linkmode" = lib ; then
+ 		case "$new_inherited_linker_flags " in
+ 		    *" $deplib "*) ;;
+-		    * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
++		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+ 		esac
+ 	    fi
+ 	  fi
+@@ -5390,7 +6261,8 @@
+ 	    test "$pass" = conv && continue
+ 	    newdependency_libs="$deplib $newdependency_libs"
+ 	    func_stripname '-L' '' "$deplib"
+-	    newlib_search_path="$newlib_search_path $func_stripname_result"
++	    func_resolve_sysroot "$func_stripname_result"
++	    func_append newlib_search_path " $func_resolve_sysroot_result"
+ 	    ;;
+ 	  prog)
+ 	    if test "$pass" = conv; then
+@@ -5404,7 +6276,8 @@
+ 	      finalize_deplibs="$deplib $finalize_deplibs"
+ 	    fi
+ 	    func_stripname '-L' '' "$deplib"
+-	    newlib_search_path="$newlib_search_path $func_stripname_result"
++	    func_resolve_sysroot "$func_stripname_result"
++	    func_append newlib_search_path " $func_resolve_sysroot_result"
+ 	    ;;
+ 	  *)
+ 	    func_warning "\`-L' is ignored for archives/objects"
+@@ -5415,17 +6288,21 @@
+ 	-R*)
+ 	  if test "$pass" = link; then
+ 	    func_stripname '-R' '' "$deplib"
+-	    dir=$func_stripname_result
++	    func_resolve_sysroot "$func_stripname_result"
++	    dir=$func_resolve_sysroot_result
+ 	    # Make sure the xrpath contains only unique directories.
+ 	    case "$xrpath " in
+ 	    *" $dir "*) ;;
+-	    *) xrpath="$xrpath $dir" ;;
++	    *) func_append xrpath " $dir" ;;
+ 	    esac
+ 	  fi
+ 	  deplibs="$deplib $deplibs"
+ 	  continue
+ 	  ;;
+-	*.la) lib="$deplib" ;;
++	*.la)
++	  func_resolve_sysroot "$deplib"
++	  lib=$func_resolve_sysroot_result
++	  ;;
+ 	*.$libext)
+ 	  if test "$pass" = conv; then
+ 	    deplibs="$deplib $deplibs"
+@@ -5488,11 +6365,11 @@
+ 	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ 	      # If there is no dlopen support or we're linking statically,
+ 	      # we need to preload.
+-	      newdlprefiles="$newdlprefiles $deplib"
++	      func_append newdlprefiles " $deplib"
+ 	      compile_deplibs="$deplib $compile_deplibs"
+ 	      finalize_deplibs="$deplib $finalize_deplibs"
+ 	    else
+-	      newdlfiles="$newdlfiles $deplib"
++	      func_append newdlfiles " $deplib"
+ 	    fi
+ 	  fi
+ 	  continue
+@@ -5538,7 +6415,7 @@
+ 	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ 	    case " $new_inherited_linker_flags " in
+ 	      *" $tmp_inherited_linker_flag "*) ;;
+-	      *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
++	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ 	    esac
+ 	  done
+ 	fi
+@@ -5546,8 +6423,8 @@
+ 	if test "$linkmode,$pass" = "lib,link" ||
+ 	   test "$linkmode,$pass" = "prog,scan" ||
+ 	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+-	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+-	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
++	  test -n "$dlopen" && func_append dlfiles " $dlopen"
++	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ 	fi
+ 
+ 	if test "$pass" = conv; then
+@@ -5558,20 +6435,20 @@
+ 	      func_fatal_error "cannot find name of link library for \`$lib'"
+ 	    fi
+ 	    # It is a libtool convenience library, so add in its objects.
+-	    convenience="$convenience $ladir/$objdir/$old_library"
+-	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
++	    func_append convenience " $ladir/$objdir/$old_library"
++	    func_append old_convenience " $ladir/$objdir/$old_library"
+ 	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ 	    func_fatal_error "\`$lib' is not a convenience library"
+ 	  fi
+ 	  tmp_libs=
+ 	  for deplib in $dependency_libs; do
+ 	    deplibs="$deplib $deplibs"
+-	    if $opt_duplicate_deps ; then
++	    if $opt_preserve_dup_deps ; then
+ 	      case "$tmp_libs " in
+-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
++	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ 	      esac
+ 	    fi
+-	    tmp_libs="$tmp_libs $deplib"
++	    func_append tmp_libs " $deplib"
+ 	  done
+ 	  continue
+ 	fi # $pass = conv
+@@ -5579,9 +6456,15 @@
+ 
+ 	# Get the name of the library we link against.
+ 	linklib=
+-	for l in $old_library $library_names; do
+-	  linklib="$l"
+-	done
++	if test -n "$old_library" &&
++	   { test "$prefer_static_libs" = yes ||
++	     test "$prefer_static_libs,$installed" = "built,no"; }; then
++	  linklib=$old_library
++	else
++	  for l in $old_library $library_names; do
++	    linklib="$l"
++	  done
++	fi
+ 	if test -z "$linklib"; then
+ 	  func_fatal_error "cannot find name of link library for \`$lib'"
+ 	fi
+@@ -5598,9 +6481,9 @@
+ 	    # statically, we need to preload.  We also need to preload any
+ 	    # dependent libraries so libltdl's deplib preloader doesn't
+ 	    # bomb out in the load deplibs phase.
+-	    dlprefiles="$dlprefiles $lib $dependency_libs"
++	    func_append dlprefiles " $lib $dependency_libs"
+ 	  else
+-	    newdlfiles="$newdlfiles $lib"
++	    func_append newdlfiles " $lib"
+ 	  fi
+ 	  continue
+ 	fi # $pass = dlopen
+@@ -5622,14 +6505,14 @@
+ 
+ 	# Find the relevant object directory and library name.
+ 	if test "X$installed" = Xyes; then
+-	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
++	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ 	    func_warning "library \`$lib' was moved."
+ 	    dir="$ladir"
+ 	    absdir="$abs_ladir"
+ 	    libdir="$abs_ladir"
+ 	  else
+-	    dir="$libdir"
+-	    absdir="$libdir"
++	    dir="$lt_sysroot$libdir"
++	    absdir="$lt_sysroot$libdir"
+ 	  fi
+ 	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ 	else
+@@ -5637,12 +6520,12 @@
+ 	    dir="$ladir"
+ 	    absdir="$abs_ladir"
+ 	    # Remove this search path later
+-	    notinst_path="$notinst_path $abs_ladir"
++	    func_append notinst_path " $abs_ladir"
+ 	  else
+ 	    dir="$ladir/$objdir"
+ 	    absdir="$abs_ladir/$objdir"
+ 	    # Remove this search path later
+-	    notinst_path="$notinst_path $abs_ladir"
++	    func_append notinst_path " $abs_ladir"
+ 	  fi
+ 	fi # $installed = yes
+ 	func_stripname 'lib' '.la' "$laname"
+@@ -5653,20 +6536,46 @@
+ 	  if test -z "$libdir" && test "$linkmode" = prog; then
+ 	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ 	  fi
+-	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+-	  # are required to link).
+-	  if test -n "$old_library"; then
+-	    newdlprefiles="$newdlprefiles $dir/$old_library"
+-	    # Keep a list of preopened convenience libraries to check
+-	    # that they are being used correctly in the link pass.
+-	    test -z "$libdir" && \
+-		dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+-	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+-	  elif test -n "$dlname"; then
+-	    newdlprefiles="$newdlprefiles $dir/$dlname"
+-	  else
+-	    newdlprefiles="$newdlprefiles $dir/$linklib"
+-	  fi
++	  case "$host" in
++	    # special handling for platforms with PE-DLLs.
++	    *cygwin* | *mingw* | *cegcc* )
++	      # Linker will automatically link against shared library if both
++	      # static and shared are present.  Therefore, ensure we extract
++	      # symbols from the import library if a shared library is present
++	      # (otherwise, the dlopen module name will be incorrect).  We do
++	      # this by putting the import library name into $newdlprefiles.
++	      # We recover the dlopen module name by 'saving' the la file
++	      # name in a special purpose variable, and (later) extracting the
++	      # dlname from the la file.
++	      if test -n "$dlname"; then
++	        func_tr_sh "$dir/$linklib"
++	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
++	        func_append newdlprefiles " $dir/$linklib"
++	      else
++	        func_append newdlprefiles " $dir/$old_library"
++	        # Keep a list of preopened convenience libraries to check
++	        # that they are being used correctly in the link pass.
++	        test -z "$libdir" && \
++	          func_append dlpreconveniencelibs " $dir/$old_library"
++	      fi
++	    ;;
++	    * )
++	      # Prefer using a static library (so that no silly _DYNAMIC symbols
++	      # are required to link).
++	      if test -n "$old_library"; then
++	        func_append newdlprefiles " $dir/$old_library"
++	        # Keep a list of preopened convenience libraries to check
++	        # that they are being used correctly in the link pass.
++	        test -z "$libdir" && \
++	          func_append dlpreconveniencelibs " $dir/$old_library"
++	      # Otherwise, use the dlname, so that lt_dlopen finds it.
++	      elif test -n "$dlname"; then
++	        func_append newdlprefiles " $dir/$dlname"
++	      else
++	        func_append newdlprefiles " $dir/$linklib"
++	      fi
++	    ;;
++	  esac
+ 	fi # $pass = dlpreopen
+ 
+ 	if test -z "$libdir"; then
+@@ -5684,7 +6593,7 @@
+ 
+ 
+ 	if test "$linkmode" = prog && test "$pass" != link; then
+-	  newlib_search_path="$newlib_search_path $ladir"
++	  func_append newlib_search_path " $ladir"
+ 	  deplibs="$lib $deplibs"
+ 
+ 	  linkalldeplibs=no
+@@ -5697,7 +6606,8 @@
+ 	  for deplib in $dependency_libs; do
+ 	    case $deplib in
+ 	    -L*) func_stripname '-L' '' "$deplib"
+-	         newlib_search_path="$newlib_search_path $func_stripname_result"
++	         func_resolve_sysroot "$func_stripname_result"
++	         func_append newlib_search_path " $func_resolve_sysroot_result"
+ 		 ;;
+ 	    esac
+ 	    # Need to link against all dependency_libs?
+@@ -5708,12 +6618,12 @@
+ 	      # or/and link against static libraries
+ 	      newdependency_libs="$deplib $newdependency_libs"
+ 	    fi
+-	    if $opt_duplicate_deps ; then
++	    if $opt_preserve_dup_deps ; then
+ 	      case "$tmp_libs " in
+-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
++	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ 	      esac
+ 	    fi
+-	    tmp_libs="$tmp_libs $deplib"
++	    func_append tmp_libs " $deplib"
+ 	  done # for deplib
+ 	  continue
+ 	fi # $linkmode = prog...
+@@ -5728,7 +6638,7 @@
+ 	      # Make sure the rpath contains only unique directories.
+ 	      case "$temp_rpath:" in
+ 	      *"$absdir:"*) ;;
+-	      *) temp_rpath="$temp_rpath$absdir:" ;;
++	      *) func_append temp_rpath "$absdir:" ;;
+ 	      esac
+ 	    fi
+ 
+@@ -5740,7 +6650,7 @@
+ 	    *)
+ 	      case "$compile_rpath " in
+ 	      *" $absdir "*) ;;
+-	      *) compile_rpath="$compile_rpath $absdir"
++	      *) func_append compile_rpath " $absdir" ;;
+ 	      esac
+ 	      ;;
+ 	    esac
+@@ -5749,7 +6659,7 @@
+ 	    *)
+ 	      case "$finalize_rpath " in
+ 	      *" $libdir "*) ;;
+-	      *) finalize_rpath="$finalize_rpath $libdir"
++	      *) func_append finalize_rpath " $libdir" ;;
+ 	      esac
+ 	      ;;
+ 	    esac
+@@ -5774,12 +6684,12 @@
+ 	  case $host in
+ 	  *cygwin* | *mingw* | *cegcc*)
+ 	      # No point in relinking DLLs because paths are not encoded
+-	      notinst_deplibs="$notinst_deplibs $lib"
++	      func_append notinst_deplibs " $lib"
+ 	      need_relink=no
+ 	    ;;
+ 	  *)
+ 	    if test "$installed" = no; then
+-	      notinst_deplibs="$notinst_deplibs $lib"
++	      func_append notinst_deplibs " $lib"
+ 	      need_relink=yes
+ 	    fi
+ 	    ;;
+@@ -5814,7 +6724,7 @@
+ 	    *)
+ 	      case "$compile_rpath " in
+ 	      *" $absdir "*) ;;
+-	      *) compile_rpath="$compile_rpath $absdir"
++	      *) func_append compile_rpath " $absdir" ;;
+ 	      esac
+ 	      ;;
+ 	    esac
+@@ -5823,7 +6733,7 @@
+ 	    *)
+ 	      case "$finalize_rpath " in
+ 	      *" $libdir "*) ;;
+-	      *) finalize_rpath="$finalize_rpath $libdir"
++	      *) func_append finalize_rpath " $libdir" ;;
+ 	      esac
+ 	      ;;
+ 	    esac
+@@ -5835,7 +6745,7 @@
+ 	    shift
+ 	    realname="$1"
+ 	    shift
+-	    eval "libname=\"$libname_spec\""
++	    libname=`eval "\\$ECHO \"$libname_spec\""`
+ 	    # use dlname if we got it. it's perfectly good, no?
+ 	    if test -n "$dlname"; then
+ 	      soname="$dlname"
+@@ -5848,7 +6758,7 @@
+ 		versuffix="-$major"
+ 		;;
+ 	      esac
+-	      eval "soname=\"$soname_spec\""
++	      eval soname=\"$soname_spec\"
+ 	    else
+ 	      soname="$realname"
+ 	    fi
+@@ -5877,7 +6787,7 @@
+ 	    linklib=$newlib
+ 	  fi # test -n "$old_archive_from_expsyms_cmds"
+ 
+-	  if test "$linkmode" = prog || test "$mode" != relink; then
++	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
+ 	    add_shlibpath=
+ 	    add_dir=
+ 	    add=
+@@ -5933,7 +6843,7 @@
+ 		if test -n "$inst_prefix_dir"; then
+ 		  case $libdir in
+ 		    [\\/]*)
+-		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
++		      func_append add_dir " -L$inst_prefix_dir$libdir"
+ 		      ;;
+ 		  esac
+ 		fi
+@@ -5955,7 +6865,7 @@
+ 	    if test -n "$add_shlibpath"; then
+ 	      case :$compile_shlibpath: in
+ 	      *":$add_shlibpath:"*) ;;
+-	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
++	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ 	      esac
+ 	    fi
+ 	    if test "$linkmode" = prog; then
+@@ -5969,13 +6879,13 @@
+ 		 test "$hardcode_shlibpath_var" = yes; then
+ 		case :$finalize_shlibpath: in
+ 		*":$libdir:"*) ;;
+-		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
++		*) func_append finalize_shlibpath "$libdir:" ;;
+ 		esac
+ 	      fi
+ 	    fi
+ 	  fi
+ 
+-	  if test "$linkmode" = prog || test "$mode" = relink; then
++	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
+ 	    add_shlibpath=
+ 	    add_dir=
+ 	    add=
+@@ -5989,7 +6899,7 @@
+ 	    elif test "$hardcode_shlibpath_var" = yes; then
+ 	      case :$finalize_shlibpath: in
+ 	      *":$libdir:"*) ;;
+-	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
++	      *) func_append finalize_shlibpath "$libdir:" ;;
+ 	      esac
+ 	      add="-l$name"
+ 	    elif test "$hardcode_automatic" = yes; then
+@@ -6001,12 +6911,12 @@
+ 	      fi
+ 	    else
+ 	      # We cannot seem to hardcode it, guess we'll fake it.
+-	      add_dir="-L$libdir"
++	      add_dir="-L$lt_sysroot$libdir"
+ 	      # Try looking first in the location we're being installed to.
+ 	      if test -n "$inst_prefix_dir"; then
+ 		case $libdir in
+ 		  [\\/]*)
+-		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
++		    func_append add_dir " -L$inst_prefix_dir$libdir"
+ 		    ;;
+ 		esac
+ 	      fi
+@@ -6083,27 +6993,33 @@
+ 	           temp_xrpath=$func_stripname_result
+ 		   case " $xrpath " in
+ 		   *" $temp_xrpath "*) ;;
+-		   *) xrpath="$xrpath $temp_xrpath";;
++		   *) func_append xrpath " $temp_xrpath";;
+ 		   esac;;
+-	      *) temp_deplibs="$temp_deplibs $libdir";;
++	      *) func_append temp_deplibs " $libdir";;
+ 	      esac
+ 	    done
+ 	    dependency_libs="$temp_deplibs"
+ 	  fi
+ 
+-	  newlib_search_path="$newlib_search_path $absdir"
++	  func_append newlib_search_path " $absdir"
+ 	  # Link against this library
+ 	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ 	  # ... and its dependency_libs
+ 	  tmp_libs=
+ 	  for deplib in $dependency_libs; do
+ 	    newdependency_libs="$deplib $newdependency_libs"
+-	    if $opt_duplicate_deps ; then
++	    case $deplib in
++              -L*) func_stripname '-L' '' "$deplib"
++                   func_resolve_sysroot "$func_stripname_result";;
++              *) func_resolve_sysroot "$deplib" ;;
++            esac
++	    if $opt_preserve_dup_deps ; then
+ 	      case "$tmp_libs " in
+-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
++	      *" $func_resolve_sysroot_result "*)
++                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ 	      esac
+ 	    fi
+-	    tmp_libs="$tmp_libs $deplib"
++	    func_append tmp_libs " $func_resolve_sysroot_result"
+ 	  done
+ 
+ 	  if test "$link_all_deplibs" != no; then
+@@ -6113,8 +7029,10 @@
+ 	      case $deplib in
+ 	      -L*) path="$deplib" ;;
+ 	      *.la)
++	        func_resolve_sysroot "$deplib"
++	        deplib=$func_resolve_sysroot_result
+ 	        func_dirname "$deplib" "" "."
+-		dir="$func_dirname_result"
++		dir=$func_dirname_result
+ 		# We need an absolute path.
+ 		case $dir in
+ 		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+@@ -6130,7 +7048,7 @@
+ 		case $host in
+ 		*-*-darwin*)
+ 		  depdepl=
+-		  deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
++		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ 		  if test -n "$deplibrary_names" ; then
+ 		    for tmp in $deplibrary_names ; do
+ 		      depdepl=$tmp
+@@ -6141,8 +7059,8 @@
+                       if test -z "$darwin_install_name"; then
+                           darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                       fi
+-		      compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+-		      linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
++		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
++		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+ 		      path=
+ 		    fi
+ 		  fi
+@@ -6152,7 +7070,7 @@
+ 		  ;;
+ 		esac
+ 		else
+-		  libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
++		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ 		  test -z "$libdir" && \
+ 		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+ 		  test "$absdir" != "$libdir" && \
+@@ -6192,7 +7110,7 @@
+ 	  for dir in $newlib_search_path; do
+ 	    case "$lib_search_path " in
+ 	    *" $dir "*) ;;
+-	    *) lib_search_path="$lib_search_path $dir" ;;
++	    *) func_append lib_search_path " $dir" ;;
+ 	    esac
+ 	  done
+ 	  newlib_search_path=
+@@ -6205,7 +7123,7 @@
+ 	fi
+ 	for var in $vars dependency_libs; do
+ 	  # Add libraries to $var in reverse order
+-	  eval tmp_libs=\$$var
++	  eval tmp_libs=\"\$$var\"
+ 	  new_libs=
+ 	  for deplib in $tmp_libs; do
+ 	    # FIXME: Pedantically, this is the right thing to do, so
+@@ -6250,13 +7168,13 @@
+ 	    -L*)
+ 	      case " $tmp_libs " in
+ 	      *" $deplib "*) ;;
+-	      *) tmp_libs="$tmp_libs $deplib" ;;
++	      *) func_append tmp_libs " $deplib" ;;
+ 	      esac
+ 	      ;;
+-	    *) tmp_libs="$tmp_libs $deplib" ;;
++	    *) func_append tmp_libs " $deplib" ;;
+ 	    esac
+ 	  done
+-	  eval $var=\$tmp_libs
++	  eval $var=\"$tmp_libs\"
+ 	done # for var
+       fi
+       # Last step: remove runtime libs from dependency_libs
+@@ -6269,7 +7187,7 @@
+ 	  ;;
+ 	esac
+ 	if test -n "$i" ; then
+-	  tmp_libs="$tmp_libs $i"
++	  func_append tmp_libs " $i"
+ 	fi
+       done
+       dependency_libs=$tmp_libs
+@@ -6310,7 +7228,7 @@
+       # Now set the variables for building old libraries.
+       build_libtool_libs=no
+       oldlibs="$output"
+-      objs="$objs$old_deplibs"
++      func_append objs "$old_deplibs"
+       ;;
+ 
+     lib)
+@@ -6319,8 +7237,8 @@
+       lib*)
+ 	func_stripname 'lib' '.la' "$outputname"
+ 	name=$func_stripname_result
+-	eval "shared_ext=\"$shrext_cmds\""
+-	eval "libname=\"$libname_spec\""
++	eval shared_ext=\"$shrext_cmds\"
++	eval libname=\"$libname_spec\"
+ 	;;
+       *)
+ 	test "$module" = no && \
+@@ -6330,8 +7248,8 @@
+ 	  # Add the "lib" prefix for modules if required
+ 	  func_stripname '' '.la' "$outputname"
+ 	  name=$func_stripname_result
+-	  eval "shared_ext=\"$shrext_cmds\""
+-	  eval "libname=\"$libname_spec\""
++	  eval shared_ext=\"$shrext_cmds\"
++	  eval libname=\"$libname_spec\"
+ 	else
+ 	  func_stripname '' '.la' "$outputname"
+ 	  libname=$func_stripname_result
+@@ -6346,7 +7264,7 @@
+ 	  echo
+ 	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ 	  $ECHO "*** objects $objs is not portable!"
+-	  libobjs="$libobjs $objs"
++	  func_append libobjs " $objs"
+ 	fi
+       fi
+ 
+@@ -6544,7 +7462,7 @@
+ 	  done
+ 
+ 	  # Make executables depend on our current version.
+-	  verstring="$verstring:${current}.0"
++	  func_append verstring ":${current}.0"
+ 	  ;;
+ 
+ 	qnx)
+@@ -6612,10 +7530,10 @@
+       fi
+ 
+       func_generate_dlsyms "$libname" "$libname" "yes"
+-      libobjs="$libobjs $symfileobj"
++      func_append libobjs " $symfileobj"
+       test "X$libobjs" = "X " && libobjs=
+ 
+-      if test "$mode" != relink; then
++      if test "$opt_mode" != relink; then
+ 	# Remove our outputs, but don't remove object files since they
+ 	# may have been created when compiling PIC objects.
+ 	removelist=
+@@ -6631,7 +7549,7 @@
+ 		   continue
+ 		 fi
+ 	       fi
+-	       removelist="$removelist $p"
++	       func_append removelist " $p"
+ 	       ;;
+ 	    *) ;;
+ 	  esac
+@@ -6642,7 +7560,7 @@
+ 
+       # Now set the variables for building old libraries.
+       if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+-	oldlibs="$oldlibs $output_objdir/$libname.$libext"
++	func_append oldlibs " $output_objdir/$libname.$libext"
+ 
+ 	# Transform .lo files to .o files.
+ 	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+@@ -6659,10 +7577,11 @@
+ 	# If the user specified any rpath flags, then add them.
+ 	temp_xrpath=
+ 	for libdir in $xrpath; do
+-	  temp_xrpath="$temp_xrpath -R$libdir"
++	  func_replace_sysroot "$libdir"
++	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+ 	  case "$finalize_rpath " in
+ 	  *" $libdir "*) ;;
+-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
++	  *) func_append finalize_rpath " $libdir" ;;
+ 	  esac
+ 	done
+ 	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+@@ -6676,7 +7595,7 @@
+       for lib in $old_dlfiles; do
+ 	case " $dlprefiles $dlfiles " in
+ 	*" $lib "*) ;;
+-	*) dlfiles="$dlfiles $lib" ;;
++	*) func_append dlfiles " $lib" ;;
+ 	esac
+       done
+ 
+@@ -6686,7 +7605,7 @@
+       for lib in $old_dlprefiles; do
+ 	case "$dlprefiles " in
+ 	*" $lib "*) ;;
+-	*) dlprefiles="$dlprefiles $lib" ;;
++	*) func_append dlprefiles " $lib" ;;
+ 	esac
+       done
+ 
+@@ -6698,7 +7617,7 @@
+ 	    ;;
+ 	  *-*-rhapsody* | *-*-darwin1.[012])
+ 	    # Rhapsody C library is in the System framework
+-	    deplibs="$deplibs System.ltframework"
++	    func_append deplibs " System.ltframework"
+ 	    ;;
+ 	  *-*-netbsd*)
+ 	    # Don't link with libc until the a.out ld.so is fixed.
+@@ -6715,7 +7634,7 @@
+ 	  *)
+ 	    # Add libc to deplibs on all other systems if necessary.
+ 	    if test "$build_libtool_need_lc" = "yes"; then
+-	      deplibs="$deplibs -lc"
++	      func_append deplibs " -lc"
+ 	    fi
+ 	    ;;
+ 	  esac
+@@ -6764,18 +7683,18 @@
+ 		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ 		  case " $predeps $postdeps " in
+ 		  *" $i "*)
+-		    newdeplibs="$newdeplibs $i"
++		    func_append newdeplibs " $i"
+ 		    i=""
+ 		    ;;
+ 		  esac
+ 		fi
+ 		if test -n "$i" ; then
+-		  eval "libname=\"$libname_spec\""
+-		  eval "deplib_matches=\"$library_names_spec\""
++		  libname=`eval "\\$ECHO \"$libname_spec\""`
++		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ 		  set dummy $deplib_matches; shift
+ 		  deplib_match=$1
+ 		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+-		    newdeplibs="$newdeplibs $i"
++		    func_append newdeplibs " $i"
+ 		  else
+ 		    droppeddeps=yes
+ 		    echo
+@@ -6789,7 +7708,7 @@
+ 		fi
+ 		;;
+ 	      *)
+-		newdeplibs="$newdeplibs $i"
++		func_append newdeplibs " $i"
+ 		;;
+ 	      esac
+ 	    done
+@@ -6807,18 +7726,18 @@
+ 		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ 		    case " $predeps $postdeps " in
+ 		    *" $i "*)
+-		      newdeplibs="$newdeplibs $i"
++		      func_append newdeplibs " $i"
+ 		      i=""
+ 		      ;;
+ 		    esac
+ 		  fi
+ 		  if test -n "$i" ; then
+-		    eval "libname=\"$libname_spec\""
+-		    eval "deplib_matches=\"$library_names_spec\""
++		    libname=`eval "\\$ECHO \"$libname_spec\""`
++		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ 		    set dummy $deplib_matches; shift
+ 		    deplib_match=$1
+ 		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+-		      newdeplibs="$newdeplibs $i"
++		      func_append newdeplibs " $i"
+ 		    else
+ 		      droppeddeps=yes
+ 		      echo
+@@ -6840,7 +7759,7 @@
+ 		fi
+ 		;;
+ 	      *)
+-		newdeplibs="$newdeplibs $i"
++		func_append newdeplibs " $i"
+ 		;;
+ 	      esac
+ 	    done
+@@ -6857,15 +7776,27 @@
+ 	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ 		case " $predeps $postdeps " in
+ 		*" $a_deplib "*)
+-		  newdeplibs="$newdeplibs $a_deplib"
++		  func_append newdeplibs " $a_deplib"
+ 		  a_deplib=""
+ 		  ;;
+ 		esac
+ 	      fi
+ 	      if test -n "$a_deplib" ; then
+-		eval "libname=\"$libname_spec\""
++		libname=`eval "\\$ECHO \"$libname_spec\""`
++		if test -n "$file_magic_glob"; then
++		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
++		else
++		  libnameglob=$libname
++		fi
++		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+ 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+-		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
++		  if test "$want_nocaseglob" = yes; then
++		    shopt -s nocaseglob
++		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
++		    $nocaseglob
++		  else
++		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
++		  fi
+ 		  for potent_lib in $potential_libs; do
+ 		      # Follow soft links.
+ 		      if ls -lLd "$potent_lib" 2>/dev/null |
+@@ -6885,10 +7816,10 @@
+ 			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+ 			esac
+ 		      done
+-		      if eval "$file_magic_cmd \"\$potlib\"" 2>/dev/null |
++		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ 			 $SED -e 10q |
+ 			 $EGREP "$file_magic_regex" > /dev/null; then
+-			newdeplibs="$newdeplibs $a_deplib"
++			func_append newdeplibs " $a_deplib"
+ 			a_deplib=""
+ 			break 2
+ 		      fi
+@@ -6913,7 +7844,7 @@
+ 	      ;;
+ 	    *)
+ 	      # Add a -L argument.
+-	      newdeplibs="$newdeplibs $a_deplib"
++	      func_append newdeplibs " $a_deplib"
+ 	      ;;
+ 	    esac
+ 	  done # Gone through all deplibs.
+@@ -6929,20 +7860,20 @@
+ 	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ 		case " $predeps $postdeps " in
+ 		*" $a_deplib "*)
+-		  newdeplibs="$newdeplibs $a_deplib"
++		  func_append newdeplibs " $a_deplib"
+ 		  a_deplib=""
+ 		  ;;
+ 		esac
+ 	      fi
+ 	      if test -n "$a_deplib" ; then
+-		eval "libname=\"$libname_spec\""
++		libname=`eval "\\$ECHO \"$libname_spec\""`
+ 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ 		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ 		  for potent_lib in $potential_libs; do
+ 		    potlib="$potent_lib" # see symlink-check above in file_magic test
+ 		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ 		       $EGREP "$match_pattern_regex" > /dev/null; then
+-		      newdeplibs="$newdeplibs $a_deplib"
++		      func_append newdeplibs " $a_deplib"
+ 		      a_deplib=""
+ 		      break 2
+ 		    fi
+@@ -6967,7 +7898,7 @@
+ 	      ;;
+ 	    *)
+ 	      # Add a -L argument.
+-	      newdeplibs="$newdeplibs $a_deplib"
++	      func_append newdeplibs " $a_deplib"
+ 	      ;;
+ 	    esac
+ 	  done # Gone through all deplibs.
+@@ -7071,7 +8002,7 @@
+ 	*)
+ 	  case " $deplibs " in
+ 	  *" -L$path/$objdir "*)
+-	    new_libs="$new_libs -L$path/$objdir" ;;
++	    func_append new_libs " -L$path/$objdir" ;;
+ 	  esac
+ 	  ;;
+ 	esac
+@@ -7081,10 +8012,10 @@
+ 	-L*)
+ 	  case " $new_libs " in
+ 	  *" $deplib "*) ;;
+-	  *) new_libs="$new_libs $deplib" ;;
++	  *) func_append new_libs " $deplib" ;;
+ 	  esac
+ 	  ;;
+-	*) new_libs="$new_libs $deplib" ;;
++	*) func_append new_libs " $deplib" ;;
+ 	esac
+       done
+       deplibs="$new_libs"
+@@ -7101,10 +8032,12 @@
+ 	  hardcode_libdirs=
+ 	  dep_rpath=
+ 	  rpath="$finalize_rpath"
+-	  test "$mode" != relink && rpath="$compile_rpath$rpath"
++	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ 	  for libdir in $rpath; do
+ 	    if test -n "$hardcode_libdir_flag_spec"; then
+ 	      if test -n "$hardcode_libdir_separator"; then
++		func_replace_sysroot "$libdir"
++		libdir=$func_replace_sysroot_result
+ 		if test -z "$hardcode_libdirs"; then
+ 		  hardcode_libdirs="$libdir"
+ 		else
+@@ -7113,18 +8046,18 @@
+ 		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ 		    ;;
+ 		  *)
+-		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
++		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ 		    ;;
+ 		  esac
+ 		fi
+ 	      else
+-		eval "flag=\"$hardcode_libdir_flag_spec\""
+-		dep_rpath="$dep_rpath $flag"
++		eval flag=\"$hardcode_libdir_flag_spec\"
++		func_append dep_rpath " $flag"
+ 	      fi
+ 	    elif test -n "$runpath_var"; then
+ 	      case "$perm_rpath " in
+ 	      *" $libdir "*) ;;
+-	      *) perm_rpath="$perm_rpath $libdir" ;;
++	      *) func_apped perm_rpath " $libdir" ;;
+ 	      esac
+ 	    fi
+ 	  done
+@@ -7133,40 +8066,38 @@
+ 	     test -n "$hardcode_libdirs"; then
+ 	    libdir="$hardcode_libdirs"
+ 	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+-	      eval "dep_rpath=\"$hardcode_libdir_flag_spec_ld\""
++	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ 	    else
+-	      eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
++	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ 	    fi
+ 	  fi
+ 	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ 	    # We should set the runpath_var.
+ 	    rpath=
+ 	    for dir in $perm_rpath; do
+-	      rpath="$rpath$dir:"
++	      func_append rpath "$dir:"
+ 	    done
+-	    eval $runpath_var=\$rpath\$$runpath_var
+-	    export $runpath_var
++	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ 	  fi
+ 	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ 	fi
+ 
+ 	shlibpath="$finalize_shlibpath"
+-	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
++	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ 	if test -n "$shlibpath"; then
+-	  eval $shlibpath_var=\$shlibpath\$$shlibpath_var
+-	  export $shlibpath_var
++	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ 	fi
+ 
+ 	# Get the real and link names of the library.
+-	eval "shared_ext=\"$shrext_cmds\""
+-	eval "library_names=\"$library_names_spec\""
++	eval shared_ext=\"$shrext_cmds\"
++	eval library_names=\"$library_names_spec\"
+ 	set dummy $library_names
+ 	shift
+ 	realname="$1"
+ 	shift
+ 
+ 	if test -n "$soname_spec"; then
+-	  eval "soname=\"$soname_spec\""
++	  eval soname=\"$soname_spec\"
+ 	else
+ 	  soname="$realname"
+ 	fi
+@@ -7178,7 +8109,7 @@
+ 	linknames=
+ 	for link
+ 	do
+-	  linknames="$linknames $link"
++	  func_append linknames " $link"
+ 	done
+ 
+ 	# Use standard objects if they are pic
+@@ -7189,7 +8120,7 @@
+ 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ 	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ 	  export_symbols="$output_objdir/$libname.uexp"
+-	  delfiles="$delfiles $export_symbols"
++	  func_append delfiles " $export_symbols"
+ 	fi
+ 
+ 	orig_export_symbols=
+@@ -7220,13 +8151,45 @@
+ 	    $opt_dry_run || $RM $export_symbols
+ 	    cmds=$export_symbols_cmds
+ 	    save_ifs="$IFS"; IFS='~'
+-	    for cmd in $cmds; do
++	    for cmd1 in $cmds; do
+ 	      IFS="$save_ifs"
+-	      eval "cmd=\"$cmd\""
+-	      func_len " $cmd"
+-	      len=$func_len_result
+-	      if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
++	      # Take the normal branch if the nm_file_list_spec branch
++	      # doesn't work or if tool conversion is not needed.
++	      case $nm_file_list_spec~$to_tool_file_cmd in
++		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
++		  try_normal_branch=yes
++		  eval cmd=\"$cmd1\"
++		  func_len " $cmd"
++		  len=$func_len_result
++		  ;;
++		*)
++		  try_normal_branch=no
++		  ;;
++	      esac
++	      if test "$try_normal_branch" = yes \
++		 && { test "$len" -lt "$max_cmd_len" \
++		      || test "$max_cmd_len" -le -1; }
++	      then
++		func_show_eval "$cmd" 'exit $?'
++		skipped_export=false
++	      elif test -n "$nm_file_list_spec"; then
++		func_basename "$output"
++		output_la=$func_basename_result
++		save_libobjs=$libobjs
++		save_output=$output
++		output=${output_objdir}/${output_la}.nm
++		func_to_tool_file "$output"
++		libobjs=$nm_file_list_spec$func_to_tool_file_result
++		func_append delfiles " $output"
++		func_verbose "creating $NM input file list: $output"
++		for obj in $save_libobjs; do
++		  func_to_tool_file "$obj"
++		  $ECHO "$func_to_tool_file_result"
++		done > "$output"
++		eval cmd=\"$cmd1\"
+ 		func_show_eval "$cmd" 'exit $?'
++		output=$save_output
++		libobjs=$save_libobjs
+ 		skipped_export=false
+ 	      else
+ 		# The command line is too long to execute in one step.
+@@ -7248,7 +8211,7 @@
+ 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ 	  tmp_export_symbols="$export_symbols"
+ 	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+-	  $opt_dry_run || $ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"
++	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ 	fi
+ 
+ 	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+@@ -7260,7 +8223,7 @@
+ 	  # global variables. join(1) would be nice here, but unfortunately
+ 	  # isn't a blessed tool.
+ 	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+-	  delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
++	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ 	  export_symbols=$output_objdir/$libname.def
+ 	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ 	fi
+@@ -7270,7 +8233,7 @@
+ 	  case " $convenience " in
+ 	  *" $test_deplib "*) ;;
+ 	  *)
+-	    tmp_deplibs="$tmp_deplibs $test_deplib"
++	    func_append tmp_deplibs " $test_deplib"
+ 	    ;;
+ 	  esac
+ 	done
+@@ -7286,43 +8249,43 @@
+ 	  fi
+ 	  if test -n "$whole_archive_flag_spec"; then
+ 	    save_libobjs=$libobjs
+-	    eval "libobjs=\"\$libobjs $whole_archive_flag_spec\""
++	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ 	    test "X$libobjs" = "X " && libobjs=
+ 	  else
+ 	    gentop="$output_objdir/${outputname}x"
+-	    generated="$generated $gentop"
++	    func_append generated " $gentop"
+ 
+ 	    func_extract_archives $gentop $convenience
+-	    libobjs="$libobjs $func_extract_archives_result"
++	    func_append libobjs " $func_extract_archives_result"
+ 	    test "X$libobjs" = "X " && libobjs=
+ 	  fi
+ 	fi
+ 
+ 	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+-	  eval "flag=\"$thread_safe_flag_spec\""
+-	  linker_flags="$linker_flags $flag"
++	  eval flag=\"$thread_safe_flag_spec\"
++	  func_append linker_flags " $flag"
+ 	fi
+ 
+ 	# Make a backup of the uninstalled library when relinking
+-	if test "$mode" = relink; then
+-	  $opt_dry_run || (cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U) || exit $?
++	if test "$opt_mode" = relink; then
++	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ 	fi
+ 
+ 	# Do each of the archive commands.
+ 	if test "$module" = yes && test -n "$module_cmds" ; then
+ 	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+-	    eval "test_cmds=\"$module_expsym_cmds\""
++	    eval test_cmds=\"$module_expsym_cmds\"
+ 	    cmds=$module_expsym_cmds
+ 	  else
+-	    eval "test_cmds=\"$module_cmds\""
++	    eval test_cmds=\"$module_cmds\"
+ 	    cmds=$module_cmds
+ 	  fi
+ 	else
+ 	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+-	    eval "test_cmds=\"$archive_expsym_cmds\""
++	    eval test_cmds=\"$archive_expsym_cmds\"
+ 	    cmds=$archive_expsym_cmds
+ 	  else
+-	    eval "test_cmds=\"$archive_cmds\""
++	    eval test_cmds=\"$archive_cmds\"
+ 	    cmds=$archive_cmds
+ 	  fi
+ 	fi
+@@ -7366,10 +8329,13 @@
+ 	    echo 'INPUT (' > $output
+ 	    for obj in $save_libobjs
+ 	    do
+-	      $ECHO "$obj" >> $output
++	      func_to_tool_file "$obj"
++	      $ECHO "$func_to_tool_file_result" >> $output
+ 	    done
+ 	    echo ')' >> $output
+-	    delfiles="$delfiles $output"
++	    func_append delfiles " $output"
++	    func_to_tool_file "$output"
++	    output=$func_to_tool_file_result
+ 	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ 	    output=${output_objdir}/${output_la}.lnk
+ 	    func_verbose "creating linker input file list: $output"
+@@ -7383,15 +8349,17 @@
+ 	    fi
+ 	    for obj
+ 	    do
+-	      $ECHO "$obj" >> $output
++	      func_to_tool_file "$obj"
++	      $ECHO "$func_to_tool_file_result" >> $output
+ 	    done
+-	    delfiles="$delfiles $output"
+-	    output=$firstobj\"$file_list_spec$output\"
++	    func_append delfiles " $output"
++	    func_to_tool_file "$output"
++	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ 	  else
+ 	    if test -n "$save_libobjs"; then
+ 	      func_verbose "creating reloadable object files..."
+ 	      output=$output_objdir/$output_la-${k}.$objext
+-	      eval "test_cmds=\"$reload_cmds\""
++	      eval test_cmds=\"$reload_cmds\"
+ 	      func_len " $test_cmds"
+ 	      len0=$func_len_result
+ 	      len=$len0
+@@ -7411,12 +8379,12 @@
+ 		  if test "$k" -eq 1 ; then
+ 		    # The first file doesn't have a previous command to add.
+ 		    reload_objs=$objlist
+-		    eval "concat_cmds=\"$reload_cmds\""
++		    eval concat_cmds=\"$reload_cmds\"
+ 		  else
+ 		    # All subsequent reloadable object files will link in
+ 		    # the last one created.
+ 		    reload_objs="$objlist $last_robj"
+-		    eval "concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\""
++		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ 		  fi
+ 		  last_robj=$output_objdir/$output_la-${k}.$objext
+ 		  func_arith $k + 1
+@@ -7433,11 +8401,11 @@
+ 	      # files will link in the last one created.
+ 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ 	      reload_objs="$objlist $last_robj"
+-	      eval "concat_cmds=\"\${concat_cmds}$reload_cmds\""
++	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+ 	      if test -n "$last_robj"; then
+-	        eval "concat_cmds=\"\${concat_cmds}~\$RM $last_robj\""
++	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ 	      fi
+-	      delfiles="$delfiles $output"
++	      func_append delfiles " $output"
+ 
+ 	    else
+ 	      output=
+@@ -7450,9 +8418,9 @@
+ 	      libobjs=$output
+ 	      # Append the command to create the export file.
+ 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+-	      eval "concat_cmds=\"\$concat_cmds$export_symbols_cmds\""
++	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ 	      if test -n "$last_robj"; then
+-		eval "concat_cmds=\"\$concat_cmds~\$RM $last_robj\""
++		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ 	      fi
+ 	    fi
+ 
+@@ -7471,7 +8439,7 @@
+ 		lt_exit=$?
+ 
+ 		# Restore the uninstalled library and exit
+-		if test "$mode" = relink; then
++		if test "$opt_mode" = relink; then
+ 		  ( cd "$output_objdir" && \
+ 		    $RM "${realname}T" && \
+ 		    $MV "${realname}U" "$realname" )
+@@ -7492,7 +8460,7 @@
+ 	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ 	      tmp_export_symbols="$export_symbols"
+ 	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+-	      $opt_dry_run || $ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"
++	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ 	    fi
+ 
+ 	    if test -n "$orig_export_symbols"; then
+@@ -7504,7 +8472,7 @@
+ 	      # global variables. join(1) would be nice here, but unfortunately
+ 	      # isn't a blessed tool.
+ 	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+-	      delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
++	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ 	      export_symbols=$output_objdir/$libname.def
+ 	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ 	    fi
+@@ -7515,7 +8483,7 @@
+ 	  output=$save_output
+ 
+ 	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+-	    eval "libobjs=\"\$libobjs $whole_archive_flag_spec\""
++	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ 	    test "X$libobjs" = "X " && libobjs=
+ 	  fi
+ 	  # Expand the library linking commands again to reset the
+@@ -7539,23 +8507,23 @@
+ 
+ 	if test -n "$delfiles"; then
+ 	  # Append the command to remove temporary files to $cmds.
+-	  eval "cmds=\"\$cmds~\$RM $delfiles\""
++	  eval cmds=\"\$cmds~\$RM $delfiles\"
+ 	fi
+ 
+ 	# Add any objects from preloaded convenience libraries
+ 	if test -n "$dlprefiles"; then
+ 	  gentop="$output_objdir/${outputname}x"
+-	  generated="$generated $gentop"
++	  func_append generated " $gentop"
+ 
+ 	  func_extract_archives $gentop $dlprefiles
+-	  libobjs="$libobjs $func_extract_archives_result"
++	  func_append libobjs " $func_extract_archives_result"
+ 	  test "X$libobjs" = "X " && libobjs=
+ 	fi
+ 
+ 	save_ifs="$IFS"; IFS='~'
+ 	for cmd in $cmds; do
+ 	  IFS="$save_ifs"
+-	  eval "cmd=\"$cmd\""
++	  eval cmd=\"$cmd\"
+ 	  $opt_silent || {
+ 	    func_quote_for_expand "$cmd"
+ 	    eval "func_echo $func_quote_for_expand_result"
+@@ -7564,7 +8532,7 @@
+ 	    lt_exit=$?
+ 
+ 	    # Restore the uninstalled library and exit
+-	    if test "$mode" = relink; then
++	    if test "$opt_mode" = relink; then
+ 	      ( cd "$output_objdir" && \
+ 	        $RM "${realname}T" && \
+ 		$MV "${realname}U" "$realname" )
+@@ -7576,8 +8544,8 @@
+ 	IFS="$save_ifs"
+ 
+ 	# Restore the uninstalled library and exit
+-	if test "$mode" = relink; then
+-	  $opt_dry_run || (cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname) || exit $?
++	if test "$opt_mode" = relink; then
++	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+ 
+ 	  if test -n "$convenience"; then
+ 	    if test -z "$whole_archive_flag_spec"; then
+@@ -7656,17 +8624,20 @@
+ 
+       if test -n "$convenience"; then
+ 	if test -n "$whole_archive_flag_spec"; then
+-	  eval "tmp_whole_archive_flags=\"$whole_archive_flag_spec\""
++	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ 	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ 	else
+ 	  gentop="$output_objdir/${obj}x"
+-	  generated="$generated $gentop"
++	  func_append generated " $gentop"
+ 
+ 	  func_extract_archives $gentop $convenience
+ 	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+ 	fi
+       fi
+ 
++      # If we're not building shared, we need to use non_pic_objs
++      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
++
+       # Create the old-style object.
+       reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+ 
+@@ -7690,7 +8661,7 @@
+ 	# Create an invalid libtool object if no PIC, so that we don't
+ 	# accidentally link it into a program.
+ 	# $show "echo timestamp > $libobj"
+-	# $opt_dry_run || echo timestamp > $libobj || exit $?
++	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ 	exit $EXIT_SUCCESS
+       fi
+ 
+@@ -7740,8 +8711,8 @@
+ 	if test "$tagname" = CXX ; then
+ 	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 	    10.[0123])
+-	      compile_command="$compile_command ${wl}-bind_at_load"
+-	      finalize_command="$finalize_command ${wl}-bind_at_load"
++	      func_append compile_command " ${wl}-bind_at_load"
++	      func_append finalize_command " ${wl}-bind_at_load"
+ 	    ;;
+ 	  esac
+ 	fi
+@@ -7761,7 +8732,7 @@
+ 	*)
+ 	  case " $compile_deplibs " in
+ 	  *" -L$path/$objdir "*)
+-	    new_libs="$new_libs -L$path/$objdir" ;;
++	    func_append new_libs " -L$path/$objdir" ;;
+ 	  esac
+ 	  ;;
+ 	esac
+@@ -7771,17 +8742,17 @@
+ 	-L*)
+ 	  case " $new_libs " in
+ 	  *" $deplib "*) ;;
+-	  *) new_libs="$new_libs $deplib" ;;
++	  *) func_append new_libs " $deplib" ;;
+ 	  esac
+ 	  ;;
+-	*) new_libs="$new_libs $deplib" ;;
++	*) func_append new_libs " $deplib" ;;
+ 	esac
+       done
+       compile_deplibs="$new_libs"
+ 
+ 
+-      compile_command="$compile_command $compile_deplibs"
+-      finalize_command="$finalize_command $finalize_deplibs"
++      func_append compile_command " $compile_deplibs"
++      func_append finalize_command " $finalize_deplibs"
+ 
+       if test -n "$rpath$xrpath"; then
+ 	# If the user specified any rpath flags, then add them.
+@@ -7789,7 +8760,7 @@
+ 	  # This is the magic to use -rpath.
+ 	  case "$finalize_rpath " in
+ 	  *" $libdir "*) ;;
+-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
++	  *) func_append finalize_rpath " $libdir" ;;
+ 	  esac
+ 	done
+       fi
+@@ -7808,18 +8779,18 @@
+ 	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ 		;;
+ 	      *)
+-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
++		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ 		;;
+ 	      esac
+ 	    fi
+ 	  else
+-	    eval "flag=\"$hardcode_libdir_flag_spec\""
+-	    rpath="$rpath $flag"
++	    eval flag=\"$hardcode_libdir_flag_spec\"
++	    func_append rpath " $flag"
+ 	  fi
+ 	elif test -n "$runpath_var"; then
+ 	  case "$perm_rpath " in
+ 	  *" $libdir "*) ;;
+-	  *) perm_rpath="$perm_rpath $libdir" ;;
++	  *) func_append perm_rpath " $libdir" ;;
+ 	  esac
+ 	fi
+ 	case $host in
+@@ -7828,12 +8799,12 @@
+ 	  case :$dllsearchpath: in
+ 	  *":$libdir:"*) ;;
+ 	  ::) dllsearchpath=$libdir;;
+-	  *) dllsearchpath="$dllsearchpath:$libdir";;
++	  *) func_append dllsearchpath ":$libdir";;
+ 	  esac
+ 	  case :$dllsearchpath: in
+ 	  *":$testbindir:"*) ;;
+ 	  ::) dllsearchpath=$testbindir;;
+-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
++	  *) func_append dllsearchpath ":$testbindir";;
+ 	  esac
+ 	  ;;
+ 	esac
+@@ -7842,7 +8813,7 @@
+       if test -n "$hardcode_libdir_separator" &&
+ 	 test -n "$hardcode_libdirs"; then
+ 	libdir="$hardcode_libdirs"
+-	eval "rpath=\" $hardcode_libdir_flag_spec\""
++	eval rpath=\" $hardcode_libdir_flag_spec\"
+       fi
+       compile_rpath="$rpath"
+ 
+@@ -7859,18 +8830,18 @@
+ 	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ 		;;
+ 	      *)
+-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
++		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ 		;;
+ 	      esac
+ 	    fi
+ 	  else
+-	    eval "flag=\"$hardcode_libdir_flag_spec\""
+-	    rpath="$rpath $flag"
++	    eval flag=\"$hardcode_libdir_flag_spec\"
++	    func_append rpath " $flag"
+ 	  fi
+ 	elif test -n "$runpath_var"; then
+ 	  case "$finalize_perm_rpath " in
+ 	  *" $libdir "*) ;;
+-	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
++	  *) func_append finalize_perm_rpath " $libdir" ;;
+ 	  esac
+ 	fi
+       done
+@@ -7878,7 +8849,7 @@
+       if test -n "$hardcode_libdir_separator" &&
+ 	 test -n "$hardcode_libdirs"; then
+ 	libdir="$hardcode_libdirs"
+-	eval "rpath=\" $hardcode_libdir_flag_spec\""
++	eval rpath=\" $hardcode_libdir_flag_spec\"
+       fi
+       finalize_rpath="$rpath"
+ 
+@@ -7921,6 +8892,12 @@
+ 	exit_status=0
+ 	func_show_eval "$link_command" 'exit_status=$?'
+ 
++	if test -n "$postlink_cmds"; then
++	  func_to_tool_file "$output"
++	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
++	  func_execute_cmds "$postlink_cmds" 'exit $?'
++	fi
++
+ 	# Delete the generated files.
+ 	if test -f "$output_objdir/${outputname}S.${objext}"; then
+ 	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+@@ -7943,7 +8920,7 @@
+ 	  # We should set the runpath_var.
+ 	  rpath=
+ 	  for dir in $perm_rpath; do
+-	    rpath="$rpath$dir:"
++	    func_append rpath "$dir:"
+ 	  done
+ 	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ 	fi
+@@ -7951,7 +8928,7 @@
+ 	  # We should set the runpath_var.
+ 	  rpath=
+ 	  for dir in $finalize_perm_rpath; do
+-	    rpath="$rpath$dir:"
++	    func_append rpath "$dir:"
+ 	  done
+ 	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ 	fi
+@@ -7966,6 +8943,13 @@
+ 	$opt_dry_run || $RM $output
+ 	# Link the executable and exit
+ 	func_show_eval "$link_command" 'exit $?'
++
++	if test -n "$postlink_cmds"; then
++	  func_to_tool_file "$output"
++	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
++	  func_execute_cmds "$postlink_cmds" 'exit $?'
++	fi
++
+ 	exit $EXIT_SUCCESS
+       fi
+ 
+@@ -7999,6 +8983,12 @@
+ 
+       func_show_eval "$link_command" 'exit $?'
+ 
++      if test -n "$postlink_cmds"; then
++	func_to_tool_file "$output_objdir/$outputname"
++	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
++	func_execute_cmds "$postlink_cmds" 'exit $?'
++      fi
++
+       # Now create the wrapper script.
+       func_verbose "creating $output"
+ 
+@@ -8096,7 +9086,7 @@
+ 	else
+ 	  oldobjs="$old_deplibs $non_pic_objects"
+ 	  if test "$preload" = yes && test -f "$symfileobj"; then
+-	    oldobjs="$oldobjs $symfileobj"
++	    func_append oldobjs " $symfileobj"
+ 	  fi
+ 	fi
+ 	addlibs="$old_convenience"
+@@ -8104,10 +9094,10 @@
+ 
+       if test -n "$addlibs"; then
+ 	gentop="$output_objdir/${outputname}x"
+-	generated="$generated $gentop"
++	func_append generated " $gentop"
+ 
+ 	func_extract_archives $gentop $addlibs
+-	oldobjs="$oldobjs $func_extract_archives_result"
++	func_append oldobjs " $func_extract_archives_result"
+       fi
+ 
+       # Do each command in the archive commands.
+@@ -8118,10 +9108,10 @@
+ 	# Add any objects from preloaded convenience libraries
+ 	if test -n "$dlprefiles"; then
+ 	  gentop="$output_objdir/${outputname}x"
+-	  generated="$generated $gentop"
++	  func_append generated " $gentop"
+ 
+ 	  func_extract_archives $gentop $dlprefiles
+-	  oldobjs="$oldobjs $func_extract_archives_result"
++	  func_append oldobjs " $func_extract_archives_result"
+ 	fi
+ 
+ 	# POSIX demands no paths to be encoded in archives.  We have
+@@ -8139,7 +9129,7 @@
+ 	else
+ 	  echo "copying selected object files to avoid basename conflicts..."
+ 	  gentop="$output_objdir/${outputname}x"
+-	  generated="$generated $gentop"
++	  func_append generated " $gentop"
+ 	  func_mkdir_p "$gentop"
+ 	  save_oldobjs=$oldobjs
+ 	  oldobjs=
+@@ -8163,18 +9153,28 @@
+ 		esac
+ 	      done
+ 	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+-	      oldobjs="$oldobjs $gentop/$newobj"
++	      func_append oldobjs " $gentop/$newobj"
+ 	      ;;
+-	    *) oldobjs="$oldobjs $obj" ;;
++	    *) func_append oldobjs " $obj" ;;
+ 	    esac
+ 	  done
+ 	fi
+-	eval "cmds=\"$old_archive_cmds\""
++	eval cmds=\"$old_archive_cmds\"
+ 
+ 	func_len " $cmds"
+ 	len=$func_len_result
+ 	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ 	  cmds=$old_archive_cmds
++	elif test -n "$archiver_list_spec"; then
++	  func_verbose "using command file archive linking..."
++	  for obj in $oldobjs
++	  do
++	    func_to_tool_file "$obj"
++	    $ECHO "$func_to_tool_file_result"
++	  done > $output_objdir/$libname.libcmd
++	  func_to_tool_file "$output_objdir/$libname.libcmd"
++	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
++	  cmds=$old_archive_cmds
+ 	else
+ 	  # the command line is too long to link in one step, link in parts
+ 	  func_verbose "using piecewise archive linking..."
+@@ -8189,7 +9189,7 @@
+ 	  do
+ 	    last_oldobj=$obj
+ 	  done
+-	  eval "test_cmds=\"$old_archive_cmds\""
++	  eval test_cmds=\"$old_archive_cmds\"
+ 	  func_len " $test_cmds"
+ 	  len0=$func_len_result
+ 	  len=$len0
+@@ -8208,7 +9208,7 @@
+ 		RANLIB=$save_RANLIB
+ 	      fi
+ 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+-	      eval "concat_cmds=\"\${concat_cmds}$old_archive_cmds\""
++	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ 	      objlist=
+ 	      len=$len0
+ 	    fi
+@@ -8216,9 +9216,9 @@
+ 	  RANLIB=$save_RANLIB
+ 	  oldobjs=$objlist
+ 	  if test "X$oldobjs" = "X" ; then
+-	    eval "cmds=\"\$concat_cmds\""
++	    eval cmds=\"\$concat_cmds\"
+ 	  else
+-	    eval "cmds=\"\$concat_cmds~\$old_archive_cmds\""
++	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ 	  fi
+ 	fi
+       fi
+@@ -8268,12 +9268,23 @@
+ 	      *.la)
+ 		func_basename "$deplib"
+ 		name="$func_basename_result"
+-		libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
++		func_resolve_sysroot "$deplib"
++		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ 		test -z "$libdir" && \
+ 		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+-		newdependency_libs="$newdependency_libs $libdir/$name"
++		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
++		;;
++	      -L*)
++		func_stripname -L '' "$deplib"
++		func_replace_sysroot "$func_stripname_result"
++		func_append newdependency_libs " -L$func_replace_sysroot_result"
+ 		;;
+-	      *) newdependency_libs="$newdependency_libs $deplib" ;;
++	      -R*)
++		func_stripname -R '' "$deplib"
++		func_replace_sysroot "$func_stripname_result"
++		func_append newdependency_libs " -R$func_replace_sysroot_result"
++		;;
++	      *) func_append newdependency_libs " $deplib" ;;
+ 	      esac
+ 	    done
+ 	    dependency_libs="$newdependency_libs"
+@@ -8284,12 +9295,14 @@
+ 	      *.la)
+ 	        func_basename "$lib"
+ 		name="$func_basename_result"
+-		libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
++		func_resolve_sysroot "$lib"
++		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
++
+ 		test -z "$libdir" && \
+ 		  func_fatal_error "\`$lib' is not a valid libtool archive"
+-		newdlfiles="$newdlfiles $libdir/$name"
++		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ 		;;
+-	      *) newdlfiles="$newdlfiles $lib" ;;
++	      *) func_append newdlfiles " $lib" ;;
+ 	      esac
+ 	    done
+ 	    dlfiles="$newdlfiles"
+@@ -8303,10 +9316,11 @@
+ 		# the library:
+ 		func_basename "$lib"
+ 		name="$func_basename_result"
+-		libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
++		func_resolve_sysroot "$lib"
++		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ 		test -z "$libdir" && \
+ 		  func_fatal_error "\`$lib' is not a valid libtool archive"
+-		newdlprefiles="$newdlprefiles $libdir/$name"
++		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ 		;;
+ 	      esac
+ 	    done
+@@ -8318,7 +9332,7 @@
+ 		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ 		*) abs=`pwd`"/$lib" ;;
+ 	      esac
+-	      newdlfiles="$newdlfiles $abs"
++	      func_append newdlfiles " $abs"
+ 	    done
+ 	    dlfiles="$newdlfiles"
+ 	    newdlprefiles=
+@@ -8327,7 +9341,7 @@
+ 		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ 		*) abs=`pwd`"/$lib" ;;
+ 	      esac
+-	      newdlprefiles="$newdlprefiles $abs"
++	      func_append newdlprefiles " $abs"
+ 	    done
+ 	    dlprefiles="$newdlprefiles"
+ 	  fi
+@@ -8412,7 +9426,7 @@
+     exit $EXIT_SUCCESS
+ }
+ 
+-{ test "$mode" = link || test "$mode" = relink; } &&
++{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+     func_mode_link ${1+"$@"}
+ 
+ 
+@@ -8432,9 +9446,9 @@
+     for arg
+     do
+       case $arg in
+-      -f) RM="$RM $arg"; rmforce=yes ;;
+-      -*) RM="$RM $arg" ;;
+-      *) files="$files $arg" ;;
++      -f) func_append RM " $arg"; rmforce=yes ;;
++      -*) func_append RM " $arg" ;;
++      *) func_append files " $arg" ;;
+       esac
+     done
+ 
+@@ -8443,24 +9457,23 @@
+ 
+     rmdirs=
+ 
+-    origobjdir="$objdir"
+     for file in $files; do
+       func_dirname "$file" "" "."
+       dir="$func_dirname_result"
+       if test "X$dir" = X.; then
+-	objdir="$origobjdir"
++	odir="$objdir"
+       else
+-	objdir="$dir/$origobjdir"
++	odir="$dir/$objdir"
+       fi
+       func_basename "$file"
+       name="$func_basename_result"
+-      test "$mode" = uninstall && objdir="$dir"
++      test "$opt_mode" = uninstall && odir="$dir"
+ 
+-      # Remember objdir for removal later, being careful to avoid duplicates
+-      if test "$mode" = clean; then
++      # Remember odir for removal later, being careful to avoid duplicates
++      if test "$opt_mode" = clean; then
+ 	case " $rmdirs " in
+-	  *" $objdir "*) ;;
+-	  *) rmdirs="$rmdirs $objdir" ;;
++	  *" $odir "*) ;;
++	  *) func_append rmdirs " $odir" ;;
+ 	esac
+       fi
+ 
+@@ -8486,18 +9499,17 @@
+ 
+ 	  # Delete the libtool libraries and symlinks.
+ 	  for n in $library_names; do
+-	    rmfiles="$rmfiles $objdir/$n"
++	    func_append rmfiles " $odir/$n"
+ 	  done
+-	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
++	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+ 
+-	  case "$mode" in
++	  case "$opt_mode" in
+ 	  clean)
+-	    case "  $library_names " in
+-	    # "  " in the beginning catches empty $dlname
++	    case " $library_names " in
+ 	    *" $dlname "*) ;;
+-	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
++	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ 	    esac
+-	    test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
++	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ 	    ;;
+ 	  uninstall)
+ 	    if test -n "$library_names"; then
+@@ -8525,19 +9537,19 @@
+ 	  # Add PIC object to the list of files to remove.
+ 	  if test -n "$pic_object" &&
+ 	     test "$pic_object" != none; then
+-	    rmfiles="$rmfiles $dir/$pic_object"
++	    func_append rmfiles " $dir/$pic_object"
+ 	  fi
+ 
+ 	  # Add non-PIC object to the list of files to remove.
+ 	  if test -n "$non_pic_object" &&
+ 	     test "$non_pic_object" != none; then
+-	    rmfiles="$rmfiles $dir/$non_pic_object"
++	    func_append rmfiles " $dir/$non_pic_object"
+ 	  fi
+ 	fi
+ 	;;
+ 
+       *)
+-	if test "$mode" = clean ; then
++	if test "$opt_mode" = clean ; then
+ 	  noexename=$name
+ 	  case $file in
+ 	  *.exe)
+@@ -8547,7 +9559,7 @@
+ 	    noexename=$func_stripname_result
+ 	    # $file with .exe has already been added to rmfiles,
+ 	    # add $file without .exe
+-	    rmfiles="$rmfiles $file"
++	    func_append rmfiles " $file"
+ 	    ;;
+ 	  esac
+ 	  # Do a test to see if this is a libtool program.
+@@ -8556,7 +9568,7 @@
+ 	      func_ltwrapper_scriptname "$file"
+ 	      relink_command=
+ 	      func_source $func_ltwrapper_scriptname_result
+-	      rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
++	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+ 	    else
+ 	      relink_command=
+ 	      func_source $dir/$noexename
+@@ -8564,12 +9576,12 @@
+ 
+ 	    # note $name still contains .exe if it was in $file originally
+ 	    # as does the version of $file that was added into $rmfiles
+-	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
++	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ 	    if test "$fast_install" = yes && test -n "$relink_command"; then
+-	      rmfiles="$rmfiles $objdir/lt-$name"
++	      func_append rmfiles " $odir/lt-$name"
+ 	    fi
+ 	    if test "X$noexename" != "X$name" ; then
+-	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
++	      func_append rmfiles " $odir/lt-${noexename}.c"
+ 	    fi
+ 	  fi
+ 	fi
+@@ -8577,7 +9589,6 @@
+       esac
+       func_show_eval "$RM $rmfiles" 'exit_status=1'
+     done
+-    objdir="$origobjdir"
+ 
+     # Try to remove the ${objdir}s in the directories where we deleted files
+     for dir in $rmdirs; do
+@@ -8589,16 +9600,16 @@
+     exit $exit_status
+ }
+ 
+-{ test "$mode" = uninstall || test "$mode" = clean; } &&
++{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+     func_mode_uninstall ${1+"$@"}
+ 
+-test -z "$mode" && {
++test -z "$opt_mode" && {
+   help="$generic_help"
+   func_fatal_help "you must specify a MODE"
+ }
+ 
+ test -z "$exec_cmd" && \
+-  func_fatal_help "invalid operation mode \`$mode'"
++  func_fatal_help "invalid operation mode \`$opt_mode'"
+ 
+ if test -n "$exec_cmd"; then
+   eval exec "$exec_cmd"
+Index: binutils-2.24/ltoptions.m4
+===================================================================
+--- binutils-2.24.orig/ltoptions.m4	2013-11-04 07:33:40.000000000 -0800
++++ binutils-2.24/ltoptions.m4	2013-12-15 11:10:23.867118697 -0800
+@@ -8,7 +8,7 @@
+ # unlimited permission to copy and/or distribute it, with or without
+ # modifications, as long as this notice is preserved.
+ 
+-# serial 6 ltoptions.m4
++# serial 7 ltoptions.m4
+ 
+ # This is to help aclocal find these macros, as it can't see m4_define.
+ AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+Index: binutils-2.24/ltversion.m4
+===================================================================
+--- binutils-2.24.orig/ltversion.m4	2013-11-04 07:33:40.000000000 -0800
++++ binutils-2.24/ltversion.m4	2013-12-15 11:10:23.867118697 -0800
+@@ -7,17 +7,17 @@
+ # unlimited permission to copy and/or distribute it, with or without
+ # modifications, as long as this notice is preserved.
+ 
+-# Generated from ltversion.in.
++# @configure_input@
+ 
+-# serial 3134 ltversion.m4
++# serial 3293 ltversion.m4
+ # This file is part of GNU Libtool
+ 
+-m4_define([LT_PACKAGE_VERSION], [2.2.7a])
+-m4_define([LT_PACKAGE_REVISION], [1.3134])
++m4_define([LT_PACKAGE_VERSION], [2.4])
++m4_define([LT_PACKAGE_REVISION], [1.3293])
+ 
+ AC_DEFUN([LTVERSION_VERSION],
+-[macro_version='2.2.7a'
+-macro_revision='1.3134'
++[macro_version='2.4'
++macro_revision='1.3293'
+ _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+ _LT_DECL(, macro_revision, 0)
+ ])
+Index: binutils-2.24/lt~obsolete.m4
+===================================================================
+--- binutils-2.24.orig/lt~obsolete.m4	2013-11-04 07:33:40.000000000 -0800
++++ binutils-2.24/lt~obsolete.m4	2013-12-15 11:10:23.867118697 -0800
+@@ -7,7 +7,7 @@
+ # unlimited permission to copy and/or distribute it, with or without
+ # modifications, as long as this notice is preserved.
+ 
+-# serial 4 lt~obsolete.m4
++# serial 5 lt~obsolete.m4
+ 
+ # These exist entirely to fool aclocal when bootstrapping libtool.
+ #
+Index: binutils-2.24/configure
+===================================================================
+--- binutils-2.24.orig/configure	2013-12-15 11:09:51.000000000 -0800
++++ binutils-2.24/configure	2013-12-15 11:10:23.870452030 -0800
+@@ -7921,7 +7921,7 @@
+     # For an installed makeinfo, we require it to be from texinfo 4.7 or
+     # higher, else we use the "missing" dummy.
+     if ${MAKEINFO} --version \
+-       | egrep 'texinfo[^0-9]*(4\.([7-9]|[1-9][0-9])|[5-9]|[1-9][0-9])' >/dev/null 2>&1; then
++       | egrep 'texinfo[^0-9]*([1-3][0-9]|4.[4-9]|4.[1-9][0-9]+|[5-9])' >/dev/null 2>&1; then
+       :
+     else
+       MAKEINFO="$MISSING makeinfo"
+Index: binutils-2.24/bfd/configure
+===================================================================
+--- binutils-2.24.orig/bfd/configure	2013-12-02 01:30:30.000000000 -0800
++++ binutils-2.24/bfd/configure	2013-12-15 11:10:23.870452030 -0800
+@@ -668,6 +668,9 @@
+ LIPO
+ NMEDIT
+ DSYMUTIL
++MANIFEST_TOOL
++ac_ct_AR
++DLLTOOL
+ OBJDUMP
+ LN_S
+ NM
+@@ -780,6 +783,7 @@
+ with_pic
+ enable_fast_install
+ with_gnu_ld
++with_libtool_sysroot
+ enable_libtool_lock
+ enable_plugins
+ enable_largefile
+@@ -1456,6 +1460,8 @@
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
++  --with-libtool-sysroot=DIR Search for dependent libraries within DIR
++                        (or the compiler's sysroot if not specified).
+   --with-mmap             try using mmap for BFD input files if available
+   --with-separate-debug-dir=DIR
+                           Look for global separate debug info in DIR
+@@ -5386,8 +5392,8 @@
+ 
+ 
+ 
+-macro_version='2.2.7a'
+-macro_revision='1.3134'
++macro_version='2.4'
++macro_revision='1.3293'
+ 
+ 
+ 
+@@ -5427,7 +5433,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+ $as_echo_n "checking how to print strings... " >&6; }
+ # Test print first, because it will be a builtin if present.
+-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+    test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+   ECHO='print -r --'
+ elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+@@ -6113,8 +6119,8 @@
+ # Try some XSI features
+ xsi_shell=no
+ ( _lt_dummy="a/b/c"
+-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+-      = c,a/b,, \
++  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
++      = c,a/b,b/c, \
+     && eval 'test $(( 1 + 1 )) -eq 2 \
+     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+   && xsi_shell=yes
+@@ -6163,6 +6169,80 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
++$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
++if test "${lt_cv_to_host_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
++        ;;
++    esac
++    ;;
++  *-*-cygwin* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_noop
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
++        ;;
++    esac
++    ;;
++  * ) # unhandled hosts (and "normal" native builds)
++    lt_cv_to_host_file_cmd=func_convert_file_noop
++    ;;
++esac
++
++fi
++
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
++$as_echo "$lt_cv_to_host_file_cmd" >&6; }
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
++$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
++if test "${lt_cv_to_tool_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  #assume ordinary cross tools, or native build.
++lt_cv_to_tool_file_cmd=func_convert_file_noop
++case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
++        ;;
++    esac
++    ;;
++esac
++
++fi
++
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
++$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
++
++
++
++
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+ $as_echo_n "checking for $LD option to reload object files... " >&6; }
+ if test "${lt_cv_ld_reload_flag+set}" = set; then :
+@@ -6179,6 +6259,11 @@
+ esac
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ case $host_os in
++  cygwin* | mingw* | pw32* | cegcc*)
++    if test "$GCC" != yes; then
++      reload_cmds=false
++    fi
++    ;;
+   darwin*)
+     if test "$GCC" = yes; then
+       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+@@ -6347,7 +6432,8 @@
+     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+     lt_cv_file_magic_cmd='func_win32_libid'
+   else
+-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++    # Keep this pattern in sync with the one in func_win32_libid.
++    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+     lt_cv_file_magic_cmd='$OBJDUMP -f'
+   fi
+   ;;
+@@ -6501,6 +6587,21 @@
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+ $as_echo "$lt_cv_deplibs_check_method" >&6; }
++
++file_magic_glob=
++want_nocaseglob=no
++if test "$build" = "$host"; then
++  case $host_os in
++  mingw* | pw32*)
++    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
++      want_nocaseglob=yes
++    else
++      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
++    fi
++    ;;
++  esac
++fi
++
+ file_magic_cmd=$lt_cv_file_magic_cmd
+ deplibs_check_method=$lt_cv_deplibs_check_method
+ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+@@ -6516,9 +6617,162 @@
+ 
+ 
+ 
++
++
++
++
++
++
++
++
++
++
+ if test -n "$ac_tool_prefix"; then
+-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+-set dummy ${ac_tool_prefix}ar; ac_word=$2
++  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
++set dummy ${ac_tool_prefix}dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$DLLTOOL"; then
++  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++DLLTOOL=$ac_cv_prog_DLLTOOL
++if test -n "$DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
++$as_echo "$DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_DLLTOOL"; then
++  ac_ct_DLLTOOL=$DLLTOOL
++  # Extract the first word of "dlltool", so it can be a program name with args.
++set dummy dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_DLLTOOL"; then
++  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
++if test -n "$ac_ct_DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
++$as_echo "$ac_ct_DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_DLLTOOL" = x; then
++    DLLTOOL="false"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    DLLTOOL=$ac_ct_DLLTOOL
++  fi
++else
++  DLLTOOL="$ac_cv_prog_DLLTOOL"
++fi
++
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
++$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
++if test "${lt_cv_sharedlib_from_linklib_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_sharedlib_from_linklib_cmd='unknown'
++
++case $host_os in
++cygwin* | mingw* | pw32* | cegcc*)
++  # two different shell functions defined in ltmain.sh
++  # decide which to use based on capabilities of $DLLTOOL
++  case `$DLLTOOL --help 2>&1` in
++  *--identify-strict*)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
++    ;;
++  *)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
++    ;;
++  esac
++  ;;
++*)
++  # fallback: assume linklib IS sharedlib
++  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
++  ;;
++esac
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
++$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
++
++
++
++
++
++
++
++if test -n "$ac_tool_prefix"; then
++  for ac_prog in ar
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_AR+set}" = set; then :
+@@ -6534,7 +6788,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_AR="${ac_tool_prefix}ar"
++    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6554,11 +6808,15 @@
+ fi
+ 
+ 
++    test -n "$AR" && break
++  done
+ fi
+-if test -z "$ac_cv_prog_AR"; then
++if test -z "$AR"; then
+   ac_ct_AR=$AR
+-  # Extract the first word of "ar", so it can be a program name with args.
+-set dummy ar; ac_word=$2
++  for ac_prog in ar
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+@@ -6574,7 +6832,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_ac_ct_AR="ar"
++    ac_cv_prog_ac_ct_AR="$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6593,6 +6851,10 @@
+ $as_echo "no" >&6; }
+ fi
+ 
++
++  test -n "$ac_ct_AR" && break
++done
++
+   if test "x$ac_ct_AR" = x; then
+     AR="false"
+   else
+@@ -6604,16 +6866,72 @@
+ esac
+     AR=$ac_ct_AR
+   fi
+-else
+-  AR="$ac_cv_prog_AR"
+ fi
+ 
+-test -z "$AR" && AR=ar
+-test -z "$AR_FLAGS" && AR_FLAGS=cru
++: ${AR=ar}
++: ${AR_FLAGS=cru}
++
++
++
++
++
++
++
++
++
++
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
++$as_echo_n "checking for archiver @FILE support... " >&6; }
++if test "${lt_cv_ar_at_file+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_ar_at_file=no
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
+ 
++int
++main ()
++{
+ 
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  echo conftest.$ac_objext > conftest.lst
++      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
++      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++      if test "$ac_status" -eq 0; then
++	# Ensure the archiver fails upon bogus file names.
++	rm -f conftest.$ac_objext libconftest.a
++	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++	if test "$ac_status" -ne 0; then
++          lt_cv_ar_at_file=@
++        fi
++      fi
++      rm -f conftest.* libconftest.a
+ 
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
++$as_echo "$lt_cv_ar_at_file" >&6; }
++
++if test "x$lt_cv_ar_at_file" = xno; then
++  archiver_list_spec=
++else
++  archiver_list_spec=$lt_cv_ar_at_file
++fi
+ 
+ 
+ 
+@@ -6955,8 +7273,8 @@
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ 
+ # Transform an extracted symbol line into symbol name and symbol address
+-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+ 
+ # Handle CRLF in mingw tool chain
+ opt_cr=
+@@ -6992,6 +7310,7 @@
+   else
+     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+   fi
++  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+ 
+   # Check to see that the pipe works correctly.
+   pipe_works=no
+@@ -7033,6 +7352,18 @@
+       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ 	  cat <<_LT_EOF > conftest.$ac_ext
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT_DLSYM_CONST
++#else
++# define LT_DLSYM_CONST const
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -7044,7 +7375,7 @@
+ 	  cat <<_LT_EOF >> conftest.$ac_ext
+ 
+ /* The mapping between symbol names and symbols.  */
+-const struct {
++LT_DLSYM_CONST struct {
+   const char *name;
+   void       *address;
+ }
+@@ -7070,8 +7401,8 @@
+ _LT_EOF
+ 	  # Now try linking the two files.
+ 	  mv conftest.$ac_objext conftstm.$ac_objext
+-	  lt_save_LIBS="$LIBS"
+-	  lt_save_CFLAGS="$CFLAGS"
++	  lt_globsym_save_LIBS=$LIBS
++	  lt_globsym_save_CFLAGS=$CFLAGS
+ 	  LIBS="conftstm.$ac_objext"
+ 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+@@ -7081,8 +7412,8 @@
+   test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ 	    pipe_works=yes
+ 	  fi
+-	  LIBS="$lt_save_LIBS"
+-	  CFLAGS="$lt_save_CFLAGS"
++	  LIBS=$lt_globsym_save_LIBS
++	  CFLAGS=$lt_globsym_save_CFLAGS
+ 	else
+ 	  echo "cannot find nm_test_func in $nlist" >&5
+ 	fi
+@@ -7119,6 +7450,20 @@
+ $as_echo "ok" >&6; }
+ fi
+ 
++# Response file support.
++if test "$lt_cv_nm_interface" = "MS dumpbin"; then
++  nm_file_list_spec='@'
++elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
++  nm_file_list_spec='@'
++fi
++
++
++
++
++
++
++
++
+ 
+ 
+ 
+@@ -7138,6 +7483,41 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
++$as_echo_n "checking for sysroot... " >&6; }
++
++# Check whether --with-libtool-sysroot was given.
++if test "${with_libtool_sysroot+set}" = set; then :
++  withval=$with_libtool_sysroot;
++else
++  with_libtool_sysroot=no
++fi
++
++
++lt_sysroot=
++case ${with_libtool_sysroot} in #(
++ yes)
++   if test "$GCC" = yes; then
++     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
++   fi
++   ;; #(
++ /*)
++   lt_sysroot=`echo "$with_libtool_sysroot" | sed -e "$sed_quote_subst"`
++   ;; #(
++ no|'')
++   ;; #(
++ *)
++   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_libtool_sysroot}" >&5
++$as_echo "${with_libtool_sysroot}" >&6; }
++   as_fn_error "The sysroot must be an absolute path." "$LINENO" 5
++   ;;
++esac
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
++$as_echo "${lt_sysroot:-no}" >&6; }
++
++
++
+ 
+ 
+ # Check whether --enable-libtool-lock was given.
+@@ -7346,6 +7726,123 @@
+ 
+ need_locks="$enable_libtool_lock"
+ 
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
++set dummy ${ac_tool_prefix}mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$MANIFEST_TOOL"; then
++  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
++if test -n "$MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
++$as_echo "$MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
++  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
++  # Extract the first word of "mt", so it can be a program name with args.
++set dummy mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_MANIFEST_TOOL"; then
++  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
++if test -n "$ac_ct_MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
++$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_MANIFEST_TOOL" = x; then
++    MANIFEST_TOOL=":"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
++  fi
++else
++  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
++fi
++
++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
++$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
++if test "${lt_cv_path_mainfest_tool+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_path_mainfest_tool=no
++  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
++  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
++  cat conftest.err >&5
++  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
++    lt_cv_path_mainfest_tool=yes
++  fi
++  rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
++$as_echo "$lt_cv_path_mainfest_tool" >&6; }
++if test "x$lt_cv_path_mainfest_tool" != xyes; then
++  MANIFEST_TOOL=:
++fi
++
++
++
++
++
+ 
+   case $host_os in
+     rhapsody* | darwin*)
+@@ -7909,6 +8406,8 @@
+       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+       echo "$AR cru libconftest.a conftest.o" >&5
+       $AR cru libconftest.a conftest.o 2>&5
++      echo "$RANLIB libconftest.a" >&5
++      $RANLIB libconftest.a 2>&5
+       cat > conftest.c << _LT_EOF
+ int main() { return 0;}
+ _LT_EOF
+@@ -8073,7 +8572,8 @@
+ LIBTOOL_DEPS="$ltmain"
+ 
+ # Always use our own libtool.
+-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++LIBTOOL='$(SHELL) $(top_builddir)'
++LIBTOOL="$LIBTOOL/${host_alias}-libtool"
+ 
+ 
+ 
+@@ -8162,7 +8662,7 @@
+ esac
+ 
+ # Global variables:
+-ofile=libtool
++ofile=${host_alias}-libtool
+ can_build_shared=yes
+ 
+ # All known linkers require a `.a' archive for static linking (except MSVC,
+@@ -8460,8 +8960,6 @@
+ lt_prog_compiler_pic=
+ lt_prog_compiler_static=
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 
+   if test "$GCC" = yes; then
+     lt_prog_compiler_wl='-Wl,'
+@@ -8627,6 +9125,12 @@
+ 	lt_prog_compiler_pic='--shared'
+ 	lt_prog_compiler_static='--static'
+ 	;;
++      nagfor*)
++	# NAG Fortran compiler
++	lt_prog_compiler_wl='-Wl,-Wl,,'
++	lt_prog_compiler_pic='-PIC'
++	lt_prog_compiler_static='-Bstatic'
++	;;
+       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+         # Portland Group compilers (*not* the Pentium gcc compiler,
+ 	# which looks to be a dead project)
+@@ -8689,7 +9193,7 @@
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-Bstatic'
+       case $cc_basename in
+-      f77* | f90* | f95*)
++      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ 	lt_prog_compiler_wl='-Qoption ld ';;
+       *)
+ 	lt_prog_compiler_wl='-Wl,';;
+@@ -8746,13 +9250,17 @@
+     lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+     ;;
+ esac
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+-$as_echo "$lt_prog_compiler_pic" >&6; }
+-
+-
+-
+-
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
++$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
++if test "${lt_cv_prog_compiler_pic+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
++$as_echo "$lt_cv_prog_compiler_pic" >&6; }
++lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -8813,6 +9321,11 @@
+ 
+ 
+ 
++
++
++
++
++
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -9163,7 +9676,8 @@
+       allow_undefined_flag=unsupported
+       always_export_symbols=no
+       enable_shared_with_static_runtimes=yes
+-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
++      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ 
+       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+         archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+@@ -9211,7 +9725,7 @@
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -9262,12 +9776,12 @@
+ 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ 	  hardcode_libdir_flag_spec=
+ 	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+-	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
++	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ 	  if test "x$supports_anon_versioning" = xyes; then
+ 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ 	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ 	      echo "local: *; };" >> $output_objdir/$libname.ver~
+-	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
++	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ 	  fi
+ 	  ;;
+ 	esac
+@@ -9281,8 +9795,8 @@
+ 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ 	wlarc=
+       else
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       fi
+       ;;
+ 
+@@ -9300,8 +9814,8 @@
+ 
+ _LT_EOF
+       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9347,8 +9861,8 @@
+ 
+     *)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9478,7 +9992,13 @@
+ 	allow_undefined_flag='-berok'
+         # Determine the default libpath from the value encoded in an
+         # empty executable.
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++        if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9491,22 +10011,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+@@ -9518,7 +10045,13 @@
+ 	else
+ 	 # Determine the default libpath from the value encoded in an
+ 	 # empty executable.
+-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	 if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9531,22 +10064,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+ 	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	  # Warning - without using the other run time loading flags,
+@@ -9591,20 +10131,63 @@
+       # Microsoft Visual C++.
+       # hardcode_libdir_flag_spec is actually meaningless, as there is
+       # no search path for DLLs.
+-      hardcode_libdir_flag_spec=' '
+-      allow_undefined_flag=unsupported
+-      # Tell ltmain to make .lib files, not .a files.
+-      libext=lib
+-      # Tell ltmain to make .dll files, not .so files.
+-      shrext_cmds=".dll"
+-      # FIXME: Setting linknames here is a bad hack.
+-      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+-      # The linker will automatically build a .lib file if we build a DLL.
+-      old_archive_from_new_cmds='true'
+-      # FIXME: Should let the user specify the lib program.
+-      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+-      fix_srcfile_path='`cygpath -w "$srcfile"`'
+-      enable_shared_with_static_runtimes=yes
++      case $cc_basename in
++      cl*)
++	# Native MSVC
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	always_export_symbols=yes
++	file_list_spec='@'
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	  else
++	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	  fi~
++	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	  linknames='
++	# The linker will not automatically build a static lib if we build a DLL.
++	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
++	enable_shared_with_static_runtimes=yes
++	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++	# Don't use ranlib
++	old_postinstall_cmds='chmod 644 $oldlib'
++	postlink_cmds='lt_outputfile="@OUTPUT@"~
++	  lt_tool_outputfile="@TOOL_OUTPUT@"~
++	  case $lt_outputfile in
++	    *.exe|*.EXE) ;;
++	    *)
++	      lt_outputfile="$lt_outputfile.exe"
++	      lt_tool_outputfile="$lt_tool_outputfile.exe"
++	      ;;
++	  esac~
++	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	    $RM "$lt_outputfile.manifest";
++	  fi'
++	;;
++      *)
++	# Assume MSVC wrapper
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
++	# The linker will automatically build a .lib file if we build a DLL.
++	old_archive_from_new_cmds='true'
++	# FIXME: Should let the user specify the lib program.
++	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
++	enable_shared_with_static_runtimes=yes
++	;;
++      esac
+       ;;
+ 
+     darwin* | rhapsody*)
+@@ -9665,7 +10248,7 @@
+ 
+     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+     freebsd* | dragonfly*)
+-      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec='-R$libdir'
+       hardcode_direct=yes
+       hardcode_shlibpath_var=no
+@@ -9673,7 +10256,7 @@
+ 
+     hpux9*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       else
+ 	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       fi
+@@ -9689,7 +10272,7 @@
+ 
+     hpux10*)
+       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+-	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       else
+ 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+       fi
+@@ -9713,10 +10296,10 @@
+ 	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	ia64*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	esac
+       else
+@@ -9795,23 +10378,36 @@
+ 
+     irix5* | irix6* | nonstopux*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	# Try to use the -exported_symbol ld option, if it does not
+ 	# work, assume that -exports_file does not work either and
+ 	# implicitly export all symbols.
+-        save_LDFLAGS="$LDFLAGS"
+-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	# This should be the same for all languages, so no per-tag cache variable.
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
++$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
++if test "${lt_cv_irix_exported_symbol+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  save_LDFLAGS="$LDFLAGS"
++	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
++	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-int foo(void) {}
++int foo (void) { return 0; }
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+-  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+-
++  lt_cv_irix_exported_symbol=yes
++else
++  lt_cv_irix_exported_symbol=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-        LDFLAGS="$save_LDFLAGS"
++           LDFLAGS="$save_LDFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
++$as_echo "$lt_cv_irix_exported_symbol" >&6; }
++	if test "$lt_cv_irix_exported_symbol" = yes; then
++          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
++	fi
+       else
+ 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+@@ -9896,7 +10492,7 @@
+     osf4* | osf5*)	# as osf3* with the addition of -msym flag
+       if test "$GCC" = yes; then
+ 	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+-	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+       else
+ 	allow_undefined_flag=' -expect_unresolved \*'
+@@ -9915,9 +10511,9 @@
+       no_undefined_flag=' -z defs'
+       if test "$GCC" = yes; then
+ 	wlarc='${wl}'
+-	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
++	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+       else
+ 	case `$CC -V 2>&1` in
+ 	*"Compilers 5.0"*)
+@@ -10493,8 +11089,9 @@
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -10527,13 +11124,71 @@
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -10625,7 +11280,7 @@
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -11465,10 +12120,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -11571,10 +12226,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -15079,7 +15734,7 @@
+ if test "$enable_shared" = "yes"; then
+   x=`sed -n -e 's/^[ 	]*PICFLAG[ 	]*=[ 	]*//p' < ../libiberty/Makefile | sed -n '$p'`
+   if test -n "$x"; then
+-    SHARED_LIBADD="-L`pwd`/../libiberty/pic -liberty"
++    SHARED_LIBADD="`pwd`/../libiberty/pic/libiberty.a"
+   fi
+ 
+ # More hacks to build DLLs on Windows.
+@@ -16694,13 +17349,20 @@
+ lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+ lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+ lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+ reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+ reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+ OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+ deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+ file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
++file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
++want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
++DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
++sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+ AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+ AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
++archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+ STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+ RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+ old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+@@ -16715,14 +17377,17 @@
+ lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
++nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
++lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+ objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+ MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
++lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+ lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+ need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
++MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+ DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+ NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+ LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+@@ -16755,12 +17420,12 @@
+ hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+ inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+ link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+ always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+ export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+ exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+ include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+ prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
++postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+ file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+ variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+ need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+@@ -16815,8 +17480,13 @@
+ OBJDUMP \
+ deplibs_check_method \
+ file_magic_cmd \
++file_magic_glob \
++want_nocaseglob \
++DLLTOOL \
++sharedlib_from_linklib_cmd \
+ AR \
+ AR_FLAGS \
++archiver_list_spec \
+ STRIP \
+ RANLIB \
+ CC \
+@@ -16826,12 +17496,14 @@
+ lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
++nm_file_list_spec \
+ lt_prog_compiler_no_builtin_flag \
+-lt_prog_compiler_wl \
+ lt_prog_compiler_pic \
++lt_prog_compiler_wl \
+ lt_prog_compiler_static \
+ lt_cv_prog_compiler_c_o \
+ need_locks \
++MANIFEST_TOOL \
+ DSYMUTIL \
+ NMEDIT \
+ LIPO \
+@@ -16847,7 +17519,6 @@
+ hardcode_libdir_flag_spec \
+ hardcode_libdir_flag_spec_ld \
+ hardcode_libdir_separator \
+-fix_srcfile_path \
+ exclude_expsyms \
+ include_expsyms \
+ file_list_spec \
+@@ -16883,6 +17554,7 @@
+ module_expsym_cmds \
+ export_symbols_cmds \
+ prelink_cmds \
++postlink_cmds \
+ postinstall_cmds \
+ postuninstall_cmds \
+ finish_cmds \
+@@ -17662,7 +18334,8 @@
+ # NOTE: Changes made to this file will be lost: look at ltmain.sh.
+ #
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ #   This file is part of GNU Libtool.
+@@ -17765,19 +18438,42 @@
+ # turn newlines into spaces.
+ NL2SP=$lt_lt_NL2SP
+ 
++# convert \$build file names to \$host format.
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++
++# convert \$build files to toolchain format.
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++
+ # An object symbol dumper.
+ OBJDUMP=$lt_OBJDUMP
+ 
+ # Method to check whether dependent libraries are shared objects.
+ deplibs_check_method=$lt_deplibs_check_method
+ 
+-# Command to use when deplibs_check_method == "file_magic".
++# Command to use when deplibs_check_method = "file_magic".
+ file_magic_cmd=$lt_file_magic_cmd
+ 
++# How to find potential files when deplibs_check_method = "file_magic".
++file_magic_glob=$lt_file_magic_glob
++
++# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
++want_nocaseglob=$lt_want_nocaseglob
++
++# DLL creation program.
++DLLTOOL=$lt_DLLTOOL
++
++# Command to associate shared and link libraries.
++sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
++
+ # The archiver.
+ AR=$lt_AR
++
++# Flags to create an archive.
+ AR_FLAGS=$lt_AR_FLAGS
+ 
++# How to feed a file listing to the archiver.
++archiver_list_spec=$lt_archiver_list_spec
++
+ # A symbol stripping program.
+ STRIP=$lt_STRIP
+ 
+@@ -17807,6 +18503,12 @@
+ # Transform the output of nm in a C name address pair when lib prefix is needed.
+ global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+ 
++# Specify filename containing input files for \$NM.
++nm_file_list_spec=$lt_nm_file_list_spec
++
++# The root where to search for dependent libraries,and in which our libraries should be installed.
++lt_sysroot=$lt_sysroot
++
+ # The name of the directory that contains temporary libtool files.
+ objdir=$objdir
+ 
+@@ -17816,6 +18518,9 @@
+ # Must we lock files when doing compilation?
+ need_locks=$lt_need_locks
+ 
++# Manifest tool.
++MANIFEST_TOOL=$lt_MANIFEST_TOOL
++
+ # Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+ DSYMUTIL=$lt_DSYMUTIL
+ 
+@@ -17930,12 +18635,12 @@
+ # Compiler flag to turn off builtin functions.
+ no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+ 
+-# How to pass a linker flag through the compiler.
+-wl=$lt_lt_prog_compiler_wl
+-
+ # Additional compiler flags for building library objects.
+ pic_flag=$lt_lt_prog_compiler_pic
+ 
++# How to pass a linker flag through the compiler.
++wl=$lt_lt_prog_compiler_wl
++
+ # Compiler flag to prevent dynamic linking.
+ link_static_flag=$lt_lt_prog_compiler_static
+ 
+@@ -18022,9 +18727,6 @@
+ # Whether libtool must link a program against all its dependency libraries.
+ link_all_deplibs=$link_all_deplibs
+ 
+-# Fix the shell variable \$srcfile for the compiler.
+-fix_srcfile_path=$lt_fix_srcfile_path
+-
+ # Set to "yes" if exported symbols are required.
+ always_export_symbols=$always_export_symbols
+ 
+@@ -18040,6 +18742,9 @@
+ # Commands necessary for linking programs (against libraries) with templates.
+ prelink_cmds=$lt_prelink_cmds
+ 
++# Commands necessary for finishing linking programs.
++postlink_cmds=$lt_postlink_cmds
++
+ # Specify filename containing input files.
+ file_list_spec=$lt_file_list_spec
+ 
+@@ -18072,210 +18777,169 @@
+   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+   # text mode, it properly converts lines to CR/LF.  This bash problem
+   # is reportedly fixed, but why not run on old versions too?
+-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  case $xsi_shell in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_dirname_and_basename file append nondir_replacement
+-# perform func_basename and func_dirname in a single function
+-# call:
+-#   dirname:  Compute the dirname of FILE.  If nonempty,
+-#             add APPEND to the result, otherwise set result
+-#             to NONDIR_REPLACEMENT.
+-#             value returned in "$func_dirname_result"
+-#   basename: Compute filename of FILE.
+-#             value retuned in "$func_basename_result"
+-# Implementation must be kept synchronized with func_dirname
+-# and func_basename. For efficiency, we do not delegate to
+-# those functions but instead duplicate the functionality here.
+-func_dirname_and_basename ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-func_stripname ()
+-{
+-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+-  # positional parameters, so assign one to ordinary parameter first.
+-  func_stripname_result=${3}
+-  func_stripname_result=${func_stripname_result#"${1}"}
+-  func_stripname_result=${func_stripname_result%"${2}"}
+-}
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=${1%%=*}
+-  func_opt_split_arg=${1#*=}
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  case ${1} in
+-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+-    *)    func_lo2o_result=${1} ;;
+-  esac
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=${1%.*}.lo
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=$(( $* ))
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=${#1}
+-}
+-
+-_LT_EOF
+-    ;;
+-  *) # Bourne compatible functions.
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+-}
+-
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-# func_strip_suffix prefix name
+-func_stripname ()
+-{
+-  case ${2} in
+-    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+-    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+-  esac
+-}
+-
+-# sed scripts:
+-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+-my_sed_long_arg='1s/^-[^=]*=//'
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+-  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=`expr "$@"`
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+-}
+-
+-_LT_EOF
+-esac
+-
+-case $lt_shell_append in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1+=\$2"
+-}
+-_LT_EOF
+-    ;;
+-  *)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1=\$$1\$2"
+-}
+-
+-_LT_EOF
+-    ;;
+-  esac
++  sed '$q' "$ltmain" >> "$cfgfile" \
++     || (rm -f "$cfgfile"; exit 1)
+ 
++  if test x"$xsi_shell" = xyes; then
++  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
++func_dirname ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_basename ()$/,/^} # func_basename /c\
++func_basename ()\
++{\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
++func_dirname_and_basename ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
++func_stripname ()\
++{\
++\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
++\    # positional parameters, so assign one to ordinary parameter first.\
++\    func_stripname_result=${3}\
++\    func_stripname_result=${func_stripname_result#"${1}"}\
++\    func_stripname_result=${func_stripname_result%"${2}"}\
++} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
++func_split_long_opt ()\
++{\
++\    func_split_long_opt_name=${1%%=*}\
++\    func_split_long_opt_arg=${1#*=}\
++} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
++func_split_short_opt ()\
++{\
++\    func_split_short_opt_arg=${1#??}\
++\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
++} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
++func_lo2o ()\
++{\
++\    case ${1} in\
++\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
++\      *)    func_lo2o_result=${1} ;;\
++\    esac\
++} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_xform ()$/,/^} # func_xform /c\
++func_xform ()\
++{\
++    func_xform_result=${1%.*}.lo\
++} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_arith ()$/,/^} # func_arith /c\
++func_arith ()\
++{\
++    func_arith_result=$(( $* ))\
++} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_len ()$/,/^} # func_len /c\
++func_len ()\
++{\
++    func_len_result=${#1}\
++} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++fi
++
++if test x"$lt_shell_append" = xyes; then
++  sed -e '/^func_append ()$/,/^} # func_append /c\
++func_append ()\
++{\
++    eval "${1}+=\\${2}"\
++} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
++func_append_quoted ()\
++{\
++\    func_quote_for_eval "${2}"\
++\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
++} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  # Save a `func_append' function call where possible by direct use of '+='
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++else
++  # Save a `func_append' function call even when '+=' is not available
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++fi
++
++if test x"$_lt_function_replace_fail" = x":"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
++$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
++fi
+ 
+-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+ 
+-  mv -f "$cfgfile" "$ofile" ||
++   mv -f "$cfgfile" "$ofile" ||
+     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+   chmod +x "$ofile"
+ 
+Index: binutils-2.24/opcodes/configure
+===================================================================
+--- binutils-2.24.orig/opcodes/configure	2013-11-04 07:33:40.000000000 -0800
++++ binutils-2.24/opcodes/configure	2013-12-15 11:10:23.873785364 -0800
+@@ -648,6 +648,9 @@
+ LIPO
+ NMEDIT
+ DSYMUTIL
++MANIFEST_TOOL
++ac_ct_AR
++DLLTOOL
+ OBJDUMP
+ LN_S
+ NM
+@@ -760,6 +763,7 @@
+ with_pic
+ enable_fast_install
+ with_gnu_ld
++with_libtool_sysroot
+ enable_libtool_lock
+ enable_targets
+ enable_werror
+@@ -1418,6 +1422,8 @@
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
++  --with-libtool-sysroot=DIR Search for dependent libraries within DIR
++                        (or the compiler's sysroot if not specified).
+ 
+ Some influential environment variables:
+   CC          C compiler command
+@@ -5113,8 +5119,8 @@
+ 
+ 
+ 
+-macro_version='2.2.7a'
+-macro_revision='1.3134'
++macro_version='2.4'
++macro_revision='1.3293'
+ 
+ 
+ 
+@@ -5154,7 +5160,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+ $as_echo_n "checking how to print strings... " >&6; }
+ # Test print first, because it will be a builtin if present.
+-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+    test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+   ECHO='print -r --'
+ elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+@@ -5840,8 +5846,8 @@
+ # Try some XSI features
+ xsi_shell=no
+ ( _lt_dummy="a/b/c"
+-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+-      = c,a/b,, \
++  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
++      = c,a/b,b/c, \
+     && eval 'test $(( 1 + 1 )) -eq 2 \
+     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+   && xsi_shell=yes
+@@ -5890,6 +5896,80 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
++$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
++if test "${lt_cv_to_host_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
++        ;;
++    esac
++    ;;
++  *-*-cygwin* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_noop
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
++        ;;
++    esac
++    ;;
++  * ) # unhandled hosts (and "normal" native builds)
++    lt_cv_to_host_file_cmd=func_convert_file_noop
++    ;;
++esac
++
++fi
++
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
++$as_echo "$lt_cv_to_host_file_cmd" >&6; }
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
++$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
++if test "${lt_cv_to_tool_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  #assume ordinary cross tools, or native build.
++lt_cv_to_tool_file_cmd=func_convert_file_noop
++case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
++        ;;
++    esac
++    ;;
++esac
++
++fi
++
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
++$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
++
++
++
++
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+ $as_echo_n "checking for $LD option to reload object files... " >&6; }
+ if test "${lt_cv_ld_reload_flag+set}" = set; then :
+@@ -5906,6 +5986,11 @@
+ esac
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ case $host_os in
++  cygwin* | mingw* | pw32* | cegcc*)
++    if test "$GCC" != yes; then
++      reload_cmds=false
++    fi
++    ;;
+   darwin*)
+     if test "$GCC" = yes; then
+       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+@@ -6074,7 +6159,8 @@
+     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+     lt_cv_file_magic_cmd='func_win32_libid'
+   else
+-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++    # Keep this pattern in sync with the one in func_win32_libid.
++    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+     lt_cv_file_magic_cmd='$OBJDUMP -f'
+   fi
+   ;;
+@@ -6228,6 +6314,21 @@
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+ $as_echo "$lt_cv_deplibs_check_method" >&6; }
++
++file_magic_glob=
++want_nocaseglob=no
++if test "$build" = "$host"; then
++  case $host_os in
++  mingw* | pw32*)
++    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
++      want_nocaseglob=yes
++    else
++      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
++    fi
++    ;;
++  esac
++fi
++
+ file_magic_cmd=$lt_cv_file_magic_cmd
+ deplibs_check_method=$lt_cv_deplibs_check_method
+ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+@@ -6243,9 +6344,162 @@
+ 
+ 
+ 
++
++
++
++
++
++
++
++
++
++
+ if test -n "$ac_tool_prefix"; then
+-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+-set dummy ${ac_tool_prefix}ar; ac_word=$2
++  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
++set dummy ${ac_tool_prefix}dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$DLLTOOL"; then
++  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++DLLTOOL=$ac_cv_prog_DLLTOOL
++if test -n "$DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
++$as_echo "$DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_DLLTOOL"; then
++  ac_ct_DLLTOOL=$DLLTOOL
++  # Extract the first word of "dlltool", so it can be a program name with args.
++set dummy dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_DLLTOOL"; then
++  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
++if test -n "$ac_ct_DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
++$as_echo "$ac_ct_DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_DLLTOOL" = x; then
++    DLLTOOL="false"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    DLLTOOL=$ac_ct_DLLTOOL
++  fi
++else
++  DLLTOOL="$ac_cv_prog_DLLTOOL"
++fi
++
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
++$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
++if test "${lt_cv_sharedlib_from_linklib_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_sharedlib_from_linklib_cmd='unknown'
++
++case $host_os in
++cygwin* | mingw* | pw32* | cegcc*)
++  # two different shell functions defined in ltmain.sh
++  # decide which to use based on capabilities of $DLLTOOL
++  case `$DLLTOOL --help 2>&1` in
++  *--identify-strict*)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
++    ;;
++  *)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
++    ;;
++  esac
++  ;;
++*)
++  # fallback: assume linklib IS sharedlib
++  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
++  ;;
++esac
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
++$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
++
++
++
++
++
++
++
++if test -n "$ac_tool_prefix"; then
++  for ac_prog in ar
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_AR+set}" = set; then :
+@@ -6261,7 +6515,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_AR="${ac_tool_prefix}ar"
++    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6281,11 +6535,15 @@
+ fi
+ 
+ 
++    test -n "$AR" && break
++  done
+ fi
+-if test -z "$ac_cv_prog_AR"; then
++if test -z "$AR"; then
+   ac_ct_AR=$AR
+-  # Extract the first word of "ar", so it can be a program name with args.
+-set dummy ar; ac_word=$2
++  for ac_prog in ar
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+@@ -6301,7 +6559,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_ac_ct_AR="ar"
++    ac_cv_prog_ac_ct_AR="$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6320,6 +6578,10 @@
+ $as_echo "no" >&6; }
+ fi
+ 
++
++  test -n "$ac_ct_AR" && break
++done
++
+   if test "x$ac_ct_AR" = x; then
+     AR="false"
+   else
+@@ -6331,12 +6593,11 @@
+ esac
+     AR=$ac_ct_AR
+   fi
+-else
+-  AR="$ac_cv_prog_AR"
+ fi
+ 
+-test -z "$AR" && AR=ar
+-test -z "$AR_FLAGS" && AR_FLAGS=cru
++: ${AR=ar}
++: ${AR_FLAGS=cru}
++
+ 
+ 
+ 
+@@ -6347,6 +6608,63 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
++$as_echo_n "checking for archiver @FILE support... " >&6; }
++if test "${lt_cv_ar_at_file+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_ar_at_file=no
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  echo conftest.$ac_objext > conftest.lst
++      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
++      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++      if test "$ac_status" -eq 0; then
++	# Ensure the archiver fails upon bogus file names.
++	rm -f conftest.$ac_objext libconftest.a
++	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++	if test "$ac_status" -ne 0; then
++          lt_cv_ar_at_file=@
++        fi
++      fi
++      rm -f conftest.* libconftest.a
++
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
++$as_echo "$lt_cv_ar_at_file" >&6; }
++
++if test "x$lt_cv_ar_at_file" = xno; then
++  archiver_list_spec=
++else
++  archiver_list_spec=$lt_cv_ar_at_file
++fi
++
++
++
++
++
++
+ 
+ if test -n "$ac_tool_prefix"; then
+   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+@@ -6682,8 +7000,8 @@
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ 
+ # Transform an extracted symbol line into symbol name and symbol address
+-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+ 
+ # Handle CRLF in mingw tool chain
+ opt_cr=
+@@ -6719,6 +7037,7 @@
+   else
+     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+   fi
++  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+ 
+   # Check to see that the pipe works correctly.
+   pipe_works=no
+@@ -6760,6 +7079,18 @@
+       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ 	  cat <<_LT_EOF > conftest.$ac_ext
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT_DLSYM_CONST
++#else
++# define LT_DLSYM_CONST const
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -6771,7 +7102,7 @@
+ 	  cat <<_LT_EOF >> conftest.$ac_ext
+ 
+ /* The mapping between symbol names and symbols.  */
+-const struct {
++LT_DLSYM_CONST struct {
+   const char *name;
+   void       *address;
+ }
+@@ -6797,8 +7128,8 @@
+ _LT_EOF
+ 	  # Now try linking the two files.
+ 	  mv conftest.$ac_objext conftstm.$ac_objext
+-	  lt_save_LIBS="$LIBS"
+-	  lt_save_CFLAGS="$CFLAGS"
++	  lt_globsym_save_LIBS=$LIBS
++	  lt_globsym_save_CFLAGS=$CFLAGS
+ 	  LIBS="conftstm.$ac_objext"
+ 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+@@ -6808,8 +7139,8 @@
+   test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ 	    pipe_works=yes
+ 	  fi
+-	  LIBS="$lt_save_LIBS"
+-	  CFLAGS="$lt_save_CFLAGS"
++	  LIBS=$lt_globsym_save_LIBS
++	  CFLAGS=$lt_globsym_save_CFLAGS
+ 	else
+ 	  echo "cannot find nm_test_func in $nlist" >&5
+ 	fi
+@@ -6846,6 +7177,14 @@
+ $as_echo "ok" >&6; }
+ fi
+ 
++# Response file support.
++if test "$lt_cv_nm_interface" = "MS dumpbin"; then
++  nm_file_list_spec='@'
++elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
++  nm_file_list_spec='@'
++fi
++
++
+ 
+ 
+ 
+@@ -6867,6 +7206,47 @@
+ 
+ 
+ 
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
++$as_echo_n "checking for sysroot... " >&6; }
++
++# Check whether --with-libtool-sysroot was given.
++if test "${with_libtool_sysroot+set}" = set; then :
++  withval=$with_libtool_sysroot;
++else
++  with_libtool_sysroot=no
++fi
++
++
++lt_sysroot=
++case ${with_libtool_sysroot} in #(
++ yes)
++   if test "$GCC" = yes; then
++     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
++   fi
++   ;; #(
++ /*)
++   lt_sysroot=`echo "$with_libtool_sysroot" | sed -e "$sed_quote_subst"`
++   ;; #(
++ no|'')
++   ;; #(
++ *)
++   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_libtool_sysroot}" >&5
++$as_echo "${with_libtool_sysroot}" >&6; }
++   as_fn_error "The sysroot must be an absolute path." "$LINENO" 5
++   ;;
++esac
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
++$as_echo "${lt_sysroot:-no}" >&6; }
++
++
++
++
++
+ # Check whether --enable-libtool-lock was given.
+ if test "${enable_libtool_lock+set}" = set; then :
+   enableval=$enable_libtool_lock;
+@@ -7073,6 +7453,123 @@
+ 
+ need_locks="$enable_libtool_lock"
+ 
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
++set dummy ${ac_tool_prefix}mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$MANIFEST_TOOL"; then
++  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
++if test -n "$MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
++$as_echo "$MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
++  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
++  # Extract the first word of "mt", so it can be a program name with args.
++set dummy mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_MANIFEST_TOOL"; then
++  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
++if test -n "$ac_ct_MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
++$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_MANIFEST_TOOL" = x; then
++    MANIFEST_TOOL=":"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
++  fi
++else
++  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
++fi
++
++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
++$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
++if test "${lt_cv_path_mainfest_tool+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_path_mainfest_tool=no
++  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
++  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
++  cat conftest.err >&5
++  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
++    lt_cv_path_mainfest_tool=yes
++  fi
++  rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
++$as_echo "$lt_cv_path_mainfest_tool" >&6; }
++if test "x$lt_cv_path_mainfest_tool" != xyes; then
++  MANIFEST_TOOL=:
++fi
++
++
++
++
++
+ 
+   case $host_os in
+     rhapsody* | darwin*)
+@@ -7636,6 +8133,8 @@
+       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+       echo "$AR cru libconftest.a conftest.o" >&5
+       $AR cru libconftest.a conftest.o 2>&5
++      echo "$RANLIB libconftest.a" >&5
++      $RANLIB libconftest.a 2>&5
+       cat > conftest.c << _LT_EOF
+ int main() { return 0;}
+ _LT_EOF
+@@ -7801,7 +8300,8 @@
+ LIBTOOL_DEPS="$ltmain"
+ 
+ # Always use our own libtool.
+-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++LIBTOOL='$(SHELL) $(top_builddir)'
++LIBTOOL="$LIBTOOL/${host_alias}-libtool"
+ 
+ 
+ 
+@@ -7890,7 +8390,7 @@
+ esac
+ 
+ # Global variables:
+-ofile=libtool
++ofile=${host_alias}-libtool
+ can_build_shared=yes
+ 
+ # All known linkers require a `.a' archive for static linking (except MSVC,
+@@ -8188,8 +8688,6 @@
+ lt_prog_compiler_pic=
+ lt_prog_compiler_static=
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 
+   if test "$GCC" = yes; then
+     lt_prog_compiler_wl='-Wl,'
+@@ -8355,6 +8853,12 @@
+ 	lt_prog_compiler_pic='--shared'
+ 	lt_prog_compiler_static='--static'
+ 	;;
++      nagfor*)
++	# NAG Fortran compiler
++	lt_prog_compiler_wl='-Wl,-Wl,,'
++	lt_prog_compiler_pic='-PIC'
++	lt_prog_compiler_static='-Bstatic'
++	;;
+       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+         # Portland Group compilers (*not* the Pentium gcc compiler,
+ 	# which looks to be a dead project)
+@@ -8417,7 +8921,7 @@
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-Bstatic'
+       case $cc_basename in
+-      f77* | f90* | f95*)
++      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ 	lt_prog_compiler_wl='-Qoption ld ';;
+       *)
+ 	lt_prog_compiler_wl='-Wl,';;
+@@ -8474,13 +8978,17 @@
+     lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+     ;;
+ esac
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+-$as_echo "$lt_prog_compiler_pic" >&6; }
+-
+-
+-
+-
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
++$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
++if test "${lt_cv_prog_compiler_pic+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
++$as_echo "$lt_cv_prog_compiler_pic" >&6; }
++lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -8541,6 +9049,11 @@
+ 
+ 
+ 
++
++
++
++
++
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -8891,7 +9404,8 @@
+       allow_undefined_flag=unsupported
+       always_export_symbols=no
+       enable_shared_with_static_runtimes=yes
+-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
++      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ 
+       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+         archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+@@ -8939,7 +9453,7 @@
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -8990,12 +9504,12 @@
+ 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ 	  hardcode_libdir_flag_spec=
+ 	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+-	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
++	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ 	  if test "x$supports_anon_versioning" = xyes; then
+ 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ 	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ 	      echo "local: *; };" >> $output_objdir/$libname.ver~
+-	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
++	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ 	  fi
+ 	  ;;
+ 	esac
+@@ -9009,8 +9523,8 @@
+ 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ 	wlarc=
+       else
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       fi
+       ;;
+ 
+@@ -9028,8 +9542,8 @@
+ 
+ _LT_EOF
+       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9075,8 +9589,8 @@
+ 
+     *)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9206,7 +9720,13 @@
+ 	allow_undefined_flag='-berok'
+         # Determine the default libpath from the value encoded in an
+         # empty executable.
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++        if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9219,22 +9739,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+@@ -9246,7 +9773,13 @@
+ 	else
+ 	 # Determine the default libpath from the value encoded in an
+ 	 # empty executable.
+-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	 if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9259,22 +9792,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+ 	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	  # Warning - without using the other run time loading flags,
+@@ -9319,20 +9859,63 @@
+       # Microsoft Visual C++.
+       # hardcode_libdir_flag_spec is actually meaningless, as there is
+       # no search path for DLLs.
+-      hardcode_libdir_flag_spec=' '
+-      allow_undefined_flag=unsupported
+-      # Tell ltmain to make .lib files, not .a files.
+-      libext=lib
+-      # Tell ltmain to make .dll files, not .so files.
+-      shrext_cmds=".dll"
+-      # FIXME: Setting linknames here is a bad hack.
+-      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+-      # The linker will automatically build a .lib file if we build a DLL.
+-      old_archive_from_new_cmds='true'
+-      # FIXME: Should let the user specify the lib program.
+-      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+-      fix_srcfile_path='`cygpath -w "$srcfile"`'
+-      enable_shared_with_static_runtimes=yes
++      case $cc_basename in
++      cl*)
++	# Native MSVC
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	always_export_symbols=yes
++	file_list_spec='@'
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	  else
++	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	  fi~
++	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	  linknames='
++	# The linker will not automatically build a static lib if we build a DLL.
++	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
++	enable_shared_with_static_runtimes=yes
++	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++	# Don't use ranlib
++	old_postinstall_cmds='chmod 644 $oldlib'
++	postlink_cmds='lt_outputfile="@OUTPUT@"~
++	  lt_tool_outputfile="@TOOL_OUTPUT@"~
++	  case $lt_outputfile in
++	    *.exe|*.EXE) ;;
++	    *)
++	      lt_outputfile="$lt_outputfile.exe"
++	      lt_tool_outputfile="$lt_tool_outputfile.exe"
++	      ;;
++	  esac~
++	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	    $RM "$lt_outputfile.manifest";
++	  fi'
++	;;
++      *)
++	# Assume MSVC wrapper
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
++	# The linker will automatically build a .lib file if we build a DLL.
++	old_archive_from_new_cmds='true'
++	# FIXME: Should let the user specify the lib program.
++	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
++	enable_shared_with_static_runtimes=yes
++	;;
++      esac
+       ;;
+ 
+     darwin* | rhapsody*)
+@@ -9393,7 +9976,7 @@
+ 
+     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+     freebsd* | dragonfly*)
+-      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec='-R$libdir'
+       hardcode_direct=yes
+       hardcode_shlibpath_var=no
+@@ -9401,7 +9984,7 @@
+ 
+     hpux9*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       else
+ 	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       fi
+@@ -9417,7 +10000,7 @@
+ 
+     hpux10*)
+       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+-	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       else
+ 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+       fi
+@@ -9441,10 +10024,10 @@
+ 	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	ia64*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	esac
+       else
+@@ -9523,23 +10106,36 @@
+ 
+     irix5* | irix6* | nonstopux*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	# Try to use the -exported_symbol ld option, if it does not
+ 	# work, assume that -exports_file does not work either and
+ 	# implicitly export all symbols.
+-        save_LDFLAGS="$LDFLAGS"
+-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	# This should be the same for all languages, so no per-tag cache variable.
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
++$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
++if test "${lt_cv_irix_exported_symbol+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  save_LDFLAGS="$LDFLAGS"
++	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
++	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-int foo(void) {}
++int foo (void) { return 0; }
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+-  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+-
++  lt_cv_irix_exported_symbol=yes
++else
++  lt_cv_irix_exported_symbol=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-        LDFLAGS="$save_LDFLAGS"
++           LDFLAGS="$save_LDFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
++$as_echo "$lt_cv_irix_exported_symbol" >&6; }
++	if test "$lt_cv_irix_exported_symbol" = yes; then
++          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
++	fi
+       else
+ 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+@@ -9624,7 +10220,7 @@
+     osf4* | osf5*)	# as osf3* with the addition of -msym flag
+       if test "$GCC" = yes; then
+ 	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+-	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+       else
+ 	allow_undefined_flag=' -expect_unresolved \*'
+@@ -9643,9 +10239,9 @@
+       no_undefined_flag=' -z defs'
+       if test "$GCC" = yes; then
+ 	wlarc='${wl}'
+-	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
++	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+       else
+ 	case `$CC -V 2>&1` in
+ 	*"Compilers 5.0"*)
+@@ -10221,8 +10817,9 @@
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -10255,13 +10852,71 @@
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -10353,7 +11008,7 @@
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -11193,10 +11848,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -11299,10 +11954,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -12415,7 +13070,7 @@
+ # since libbfd may not pull in the entirety of libiberty.
+   x=`sed -n -e 's/^[ 	]*PICFLAG[ 	]*=[ 	]*//p' < ../libiberty/Makefile | sed -n '$p'`
+   if test -n "$x"; then
+-    SHARED_LIBADD="-L`pwd`/../libiberty/pic -liberty"
++    SHARED_LIBADD="`pwd`/../libiberty/pic/libiberty.a"
+   fi
+ 
+   case "${host}" in
+@@ -13387,13 +14042,20 @@
+ lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+ lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+ lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+ reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+ reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+ OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+ deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+ file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
++file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
++want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
++DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
++sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+ AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+ AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
++archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+ STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+ RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+ old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+@@ -13408,14 +14070,17 @@
+ lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
++nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
++lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+ objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+ MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
++lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+ lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+ need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
++MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+ DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+ NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+ LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+@@ -13448,12 +14113,12 @@
+ hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+ inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+ link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+ always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+ export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+ exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+ include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+ prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
++postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+ file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+ variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+ need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+@@ -13508,8 +14173,13 @@
+ OBJDUMP \
+ deplibs_check_method \
+ file_magic_cmd \
++file_magic_glob \
++want_nocaseglob \
++DLLTOOL \
++sharedlib_from_linklib_cmd \
+ AR \
+ AR_FLAGS \
++archiver_list_spec \
+ STRIP \
+ RANLIB \
+ CC \
+@@ -13519,12 +14189,14 @@
+ lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
++nm_file_list_spec \
+ lt_prog_compiler_no_builtin_flag \
+-lt_prog_compiler_wl \
+ lt_prog_compiler_pic \
++lt_prog_compiler_wl \
+ lt_prog_compiler_static \
+ lt_cv_prog_compiler_c_o \
+ need_locks \
++MANIFEST_TOOL \
+ DSYMUTIL \
+ NMEDIT \
+ LIPO \
+@@ -13540,7 +14212,6 @@
+ hardcode_libdir_flag_spec \
+ hardcode_libdir_flag_spec_ld \
+ hardcode_libdir_separator \
+-fix_srcfile_path \
+ exclude_expsyms \
+ include_expsyms \
+ file_list_spec \
+@@ -13576,6 +14247,7 @@
+ module_expsym_cmds \
+ export_symbols_cmds \
+ prelink_cmds \
++postlink_cmds \
+ postinstall_cmds \
+ postuninstall_cmds \
+ finish_cmds \
+@@ -14332,7 +15004,8 @@
+ # NOTE: Changes made to this file will be lost: look at ltmain.sh.
+ #
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ #   This file is part of GNU Libtool.
+@@ -14435,19 +15108,42 @@
+ # turn newlines into spaces.
+ NL2SP=$lt_lt_NL2SP
+ 
++# convert \$build file names to \$host format.
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++
++# convert \$build files to toolchain format.
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++
+ # An object symbol dumper.
+ OBJDUMP=$lt_OBJDUMP
+ 
+ # Method to check whether dependent libraries are shared objects.
+ deplibs_check_method=$lt_deplibs_check_method
+ 
+-# Command to use when deplibs_check_method == "file_magic".
++# Command to use when deplibs_check_method = "file_magic".
+ file_magic_cmd=$lt_file_magic_cmd
+ 
++# How to find potential files when deplibs_check_method = "file_magic".
++file_magic_glob=$lt_file_magic_glob
++
++# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
++want_nocaseglob=$lt_want_nocaseglob
++
++# DLL creation program.
++DLLTOOL=$lt_DLLTOOL
++
++# Command to associate shared and link libraries.
++sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
++
+ # The archiver.
+ AR=$lt_AR
++
++# Flags to create an archive.
+ AR_FLAGS=$lt_AR_FLAGS
+ 
++# How to feed a file listing to the archiver.
++archiver_list_spec=$lt_archiver_list_spec
++
+ # A symbol stripping program.
+ STRIP=$lt_STRIP
+ 
+@@ -14477,6 +15173,12 @@
+ # Transform the output of nm in a C name address pair when lib prefix is needed.
+ global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+ 
++# Specify filename containing input files for \$NM.
++nm_file_list_spec=$lt_nm_file_list_spec
++
++# The root where to search for dependent libraries,and in which our libraries should be installed.
++lt_sysroot=$lt_sysroot
++
+ # The name of the directory that contains temporary libtool files.
+ objdir=$objdir
+ 
+@@ -14486,6 +15188,9 @@
+ # Must we lock files when doing compilation?
+ need_locks=$lt_need_locks
+ 
++# Manifest tool.
++MANIFEST_TOOL=$lt_MANIFEST_TOOL
++
+ # Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+ DSYMUTIL=$lt_DSYMUTIL
+ 
+@@ -14600,12 +15305,12 @@
+ # Compiler flag to turn off builtin functions.
+ no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+ 
+-# How to pass a linker flag through the compiler.
+-wl=$lt_lt_prog_compiler_wl
+-
+ # Additional compiler flags for building library objects.
+ pic_flag=$lt_lt_prog_compiler_pic
+ 
++# How to pass a linker flag through the compiler.
++wl=$lt_lt_prog_compiler_wl
++
+ # Compiler flag to prevent dynamic linking.
+ link_static_flag=$lt_lt_prog_compiler_static
+ 
+@@ -14692,9 +15397,6 @@
+ # Whether libtool must link a program against all its dependency libraries.
+ link_all_deplibs=$link_all_deplibs
+ 
+-# Fix the shell variable \$srcfile for the compiler.
+-fix_srcfile_path=$lt_fix_srcfile_path
+-
+ # Set to "yes" if exported symbols are required.
+ always_export_symbols=$always_export_symbols
+ 
+@@ -14710,6 +15412,9 @@
+ # Commands necessary for linking programs (against libraries) with templates.
+ prelink_cmds=$lt_prelink_cmds
+ 
++# Commands necessary for finishing linking programs.
++postlink_cmds=$lt_postlink_cmds
++
+ # Specify filename containing input files.
+ file_list_spec=$lt_file_list_spec
+ 
+@@ -14742,210 +15447,169 @@
+   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+   # text mode, it properly converts lines to CR/LF.  This bash problem
+   # is reportedly fixed, but why not run on old versions too?
+-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  case $xsi_shell in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_dirname_and_basename file append nondir_replacement
+-# perform func_basename and func_dirname in a single function
+-# call:
+-#   dirname:  Compute the dirname of FILE.  If nonempty,
+-#             add APPEND to the result, otherwise set result
+-#             to NONDIR_REPLACEMENT.
+-#             value returned in "$func_dirname_result"
+-#   basename: Compute filename of FILE.
+-#             value retuned in "$func_basename_result"
+-# Implementation must be kept synchronized with func_dirname
+-# and func_basename. For efficiency, we do not delegate to
+-# those functions but instead duplicate the functionality here.
+-func_dirname_and_basename ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-func_stripname ()
+-{
+-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+-  # positional parameters, so assign one to ordinary parameter first.
+-  func_stripname_result=${3}
+-  func_stripname_result=${func_stripname_result#"${1}"}
+-  func_stripname_result=${func_stripname_result%"${2}"}
+-}
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=${1%%=*}
+-  func_opt_split_arg=${1#*=}
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  case ${1} in
+-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+-    *)    func_lo2o_result=${1} ;;
+-  esac
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=${1%.*}.lo
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=$(( $* ))
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=${#1}
+-}
+-
+-_LT_EOF
+-    ;;
+-  *) # Bourne compatible functions.
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+-}
+-
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-# func_strip_suffix prefix name
+-func_stripname ()
+-{
+-  case ${2} in
+-    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+-    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+-  esac
+-}
+-
+-# sed scripts:
+-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+-my_sed_long_arg='1s/^-[^=]*=//'
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+-  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=`expr "$@"`
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+-}
+-
+-_LT_EOF
+-esac
+-
+-case $lt_shell_append in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1+=\$2"
+-}
+-_LT_EOF
+-    ;;
+-  *)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1=\$$1\$2"
+-}
+-
+-_LT_EOF
+-    ;;
+-  esac
++  sed '$q' "$ltmain" >> "$cfgfile" \
++     || (rm -f "$cfgfile"; exit 1)
+ 
++  if test x"$xsi_shell" = xyes; then
++  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
++func_dirname ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_basename ()$/,/^} # func_basename /c\
++func_basename ()\
++{\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
++func_dirname_and_basename ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
++func_stripname ()\
++{\
++\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
++\    # positional parameters, so assign one to ordinary parameter first.\
++\    func_stripname_result=${3}\
++\    func_stripname_result=${func_stripname_result#"${1}"}\
++\    func_stripname_result=${func_stripname_result%"${2}"}\
++} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
++func_split_long_opt ()\
++{\
++\    func_split_long_opt_name=${1%%=*}\
++\    func_split_long_opt_arg=${1#*=}\
++} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
++func_split_short_opt ()\
++{\
++\    func_split_short_opt_arg=${1#??}\
++\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
++} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
++func_lo2o ()\
++{\
++\    case ${1} in\
++\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
++\      *)    func_lo2o_result=${1} ;;\
++\    esac\
++} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_xform ()$/,/^} # func_xform /c\
++func_xform ()\
++{\
++    func_xform_result=${1%.*}.lo\
++} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_arith ()$/,/^} # func_arith /c\
++func_arith ()\
++{\
++    func_arith_result=$(( $* ))\
++} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_len ()$/,/^} # func_len /c\
++func_len ()\
++{\
++    func_len_result=${#1}\
++} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++fi
++
++if test x"$lt_shell_append" = xyes; then
++  sed -e '/^func_append ()$/,/^} # func_append /c\
++func_append ()\
++{\
++    eval "${1}+=\\${2}"\
++} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
++func_append_quoted ()\
++{\
++\    func_quote_for_eval "${2}"\
++\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
++} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  # Save a `func_append' function call where possible by direct use of '+='
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++else
++  # Save a `func_append' function call even when '+=' is not available
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++fi
++
++if test x"$_lt_function_replace_fail" = x":"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
++$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
++fi
+ 
+-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+ 
+-  mv -f "$cfgfile" "$ofile" ||
++   mv -f "$cfgfile" "$ofile" ||
+     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+   chmod +x "$ofile"
+ 
+Index: binutils-2.24/binutils/configure
+===================================================================
+--- binutils-2.24.orig/binutils/configure	2013-11-04 07:33:37.000000000 -0800
++++ binutils-2.24/binutils/configure	2013-12-15 11:10:23.877118697 -0800
+@@ -655,8 +655,11 @@
+ LIPO
+ NMEDIT
+ DSYMUTIL
++MANIFEST_TOOL
+ RANLIB
++ac_ct_AR
+ AR
++DLLTOOL
+ OBJDUMP
+ LN_S
+ NM
+@@ -769,6 +772,7 @@
+ with_pic
+ enable_fast_install
+ with_gnu_ld
++with_libtool_sysroot
+ enable_libtool_lock
+ enable_targets
+ enable_deterministic_archives
+@@ -1434,6 +1438,8 @@
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
++  --with-libtool-sysroot=DIR Search for dependent libraries within DIR
++                        (or the compiler's sysroot if not specified).
+   --with-zlib             include zlib support (auto/yes/no) default=auto
+   --with-gnu-ld           assume the C compiler uses GNU ld default=no
+   --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
+@@ -5152,8 +5158,8 @@
+ 
+ 
+ 
+-macro_version='2.2.7a'
+-macro_revision='1.3134'
++macro_version='2.4'
++macro_revision='1.3293'
+ 
+ 
+ 
+@@ -5193,7 +5199,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+ $as_echo_n "checking how to print strings... " >&6; }
+ # Test print first, because it will be a builtin if present.
+-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+    test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+   ECHO='print -r --'
+ elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+@@ -5879,8 +5885,8 @@
+ # Try some XSI features
+ xsi_shell=no
+ ( _lt_dummy="a/b/c"
+-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+-      = c,a/b,, \
++  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
++      = c,a/b,b/c, \
+     && eval 'test $(( 1 + 1 )) -eq 2 \
+     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+   && xsi_shell=yes
+@@ -5929,6 +5935,80 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
++$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
++if test "${lt_cv_to_host_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
++        ;;
++    esac
++    ;;
++  *-*-cygwin* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_noop
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
++        ;;
++    esac
++    ;;
++  * ) # unhandled hosts (and "normal" native builds)
++    lt_cv_to_host_file_cmd=func_convert_file_noop
++    ;;
++esac
++
++fi
++
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
++$as_echo "$lt_cv_to_host_file_cmd" >&6; }
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
++$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
++if test "${lt_cv_to_tool_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  #assume ordinary cross tools, or native build.
++lt_cv_to_tool_file_cmd=func_convert_file_noop
++case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
++        ;;
++    esac
++    ;;
++esac
++
++fi
++
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
++$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
++
++
++
++
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+ $as_echo_n "checking for $LD option to reload object files... " >&6; }
+ if test "${lt_cv_ld_reload_flag+set}" = set; then :
+@@ -5945,6 +6025,11 @@
+ esac
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ case $host_os in
++  cygwin* | mingw* | pw32* | cegcc*)
++    if test "$GCC" != yes; then
++      reload_cmds=false
++    fi
++    ;;
+   darwin*)
+     if test "$GCC" = yes; then
+       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+@@ -6113,7 +6198,8 @@
+     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+     lt_cv_file_magic_cmd='func_win32_libid'
+   else
+-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++    # Keep this pattern in sync with the one in func_win32_libid.
++    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+     lt_cv_file_magic_cmd='$OBJDUMP -f'
+   fi
+   ;;
+@@ -6267,6 +6353,21 @@
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+ $as_echo "$lt_cv_deplibs_check_method" >&6; }
++
++file_magic_glob=
++want_nocaseglob=no
++if test "$build" = "$host"; then
++  case $host_os in
++  mingw* | pw32*)
++    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
++      want_nocaseglob=yes
++    else
++      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
++    fi
++    ;;
++  esac
++fi
++
+ file_magic_cmd=$lt_cv_file_magic_cmd
+ deplibs_check_method=$lt_cv_deplibs_check_method
+ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+@@ -6282,9 +6383,162 @@
+ 
+ 
+ 
++
++
++
++
++
++
++
++
++
++
+ if test -n "$ac_tool_prefix"; then
+-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+-set dummy ${ac_tool_prefix}ar; ac_word=$2
++  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
++set dummy ${ac_tool_prefix}dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$DLLTOOL"; then
++  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++DLLTOOL=$ac_cv_prog_DLLTOOL
++if test -n "$DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
++$as_echo "$DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_DLLTOOL"; then
++  ac_ct_DLLTOOL=$DLLTOOL
++  # Extract the first word of "dlltool", so it can be a program name with args.
++set dummy dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_DLLTOOL"; then
++  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
++if test -n "$ac_ct_DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
++$as_echo "$ac_ct_DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_DLLTOOL" = x; then
++    DLLTOOL="false"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    DLLTOOL=$ac_ct_DLLTOOL
++  fi
++else
++  DLLTOOL="$ac_cv_prog_DLLTOOL"
++fi
++
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
++$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
++if test "${lt_cv_sharedlib_from_linklib_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_sharedlib_from_linklib_cmd='unknown'
++
++case $host_os in
++cygwin* | mingw* | pw32* | cegcc*)
++  # two different shell functions defined in ltmain.sh
++  # decide which to use based on capabilities of $DLLTOOL
++  case `$DLLTOOL --help 2>&1` in
++  *--identify-strict*)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
++    ;;
++  *)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
++    ;;
++  esac
++  ;;
++*)
++  # fallback: assume linklib IS sharedlib
++  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
++  ;;
++esac
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
++$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
++
++
++
++
++
++
++
++if test -n "$ac_tool_prefix"; then
++  for ac_prog in ar
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_AR+set}" = set; then :
+@@ -6300,7 +6554,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_AR="${ac_tool_prefix}ar"
++    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6320,11 +6574,15 @@
+ fi
+ 
+ 
++    test -n "$AR" && break
++  done
+ fi
+-if test -z "$ac_cv_prog_AR"; then
++if test -z "$AR"; then
+   ac_ct_AR=$AR
+-  # Extract the first word of "ar", so it can be a program name with args.
+-set dummy ar; ac_word=$2
++  for ac_prog in ar
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+@@ -6340,7 +6598,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_ac_ct_AR="ar"
++    ac_cv_prog_ac_ct_AR="$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6359,6 +6617,10 @@
+ $as_echo "no" >&6; }
+ fi
+ 
++
++  test -n "$ac_ct_AR" && break
++done
++
+   if test "x$ac_ct_AR" = x; then
+     AR="false"
+   else
+@@ -6370,12 +6632,10 @@
+ esac
+     AR=$ac_ct_AR
+   fi
+-else
+-  AR="$ac_cv_prog_AR"
+ fi
+ 
+-test -z "$AR" && AR=ar
+-test -z "$AR_FLAGS" && AR_FLAGS=cru
++: ${AR=ar}
++: ${AR_FLAGS=cru}
+ 
+ 
+ 
+@@ -6387,6 +6647,64 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
++$as_echo_n "checking for archiver @FILE support... " >&6; }
++if test "${lt_cv_ar_at_file+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_ar_at_file=no
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  echo conftest.$ac_objext > conftest.lst
++      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
++      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++      if test "$ac_status" -eq 0; then
++	# Ensure the archiver fails upon bogus file names.
++	rm -f conftest.$ac_objext libconftest.a
++	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++	if test "$ac_status" -ne 0; then
++          lt_cv_ar_at_file=@
++        fi
++      fi
++      rm -f conftest.* libconftest.a
++
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
++$as_echo "$lt_cv_ar_at_file" >&6; }
++
++if test "x$lt_cv_ar_at_file" = xno; then
++  archiver_list_spec=
++else
++  archiver_list_spec=$lt_cv_ar_at_file
++fi
++
++
++
++
++
++
++
+ if test -n "$ac_tool_prefix"; then
+   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}strip; ac_word=$2
+@@ -6721,8 +7039,8 @@
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ 
+ # Transform an extracted symbol line into symbol name and symbol address
+-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+ 
+ # Handle CRLF in mingw tool chain
+ opt_cr=
+@@ -6758,6 +7076,7 @@
+   else
+     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+   fi
++  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+ 
+   # Check to see that the pipe works correctly.
+   pipe_works=no
+@@ -6799,6 +7118,18 @@
+       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ 	  cat <<_LT_EOF > conftest.$ac_ext
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT_DLSYM_CONST
++#else
++# define LT_DLSYM_CONST const
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -6810,7 +7141,7 @@
+ 	  cat <<_LT_EOF >> conftest.$ac_ext
+ 
+ /* The mapping between symbol names and symbols.  */
+-const struct {
++LT_DLSYM_CONST struct {
+   const char *name;
+   void       *address;
+ }
+@@ -6836,8 +7167,8 @@
+ _LT_EOF
+ 	  # Now try linking the two files.
+ 	  mv conftest.$ac_objext conftstm.$ac_objext
+-	  lt_save_LIBS="$LIBS"
+-	  lt_save_CFLAGS="$CFLAGS"
++	  lt_globsym_save_LIBS=$LIBS
++	  lt_globsym_save_CFLAGS=$CFLAGS
+ 	  LIBS="conftstm.$ac_objext"
+ 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+@@ -6847,8 +7178,8 @@
+   test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ 	    pipe_works=yes
+ 	  fi
+-	  LIBS="$lt_save_LIBS"
+-	  CFLAGS="$lt_save_CFLAGS"
++	  LIBS=$lt_globsym_save_LIBS
++	  CFLAGS=$lt_globsym_save_CFLAGS
+ 	else
+ 	  echo "cannot find nm_test_func in $nlist" >&5
+ 	fi
+@@ -6885,6 +7216,19 @@
+ $as_echo "ok" >&6; }
+ fi
+ 
++# Response file support.
++if test "$lt_cv_nm_interface" = "MS dumpbin"; then
++  nm_file_list_spec='@'
++elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
++  nm_file_list_spec='@'
++fi
++
++
++
++
++
++
++
+ 
+ 
+ 
+@@ -6905,6 +7249,42 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
++$as_echo_n "checking for sysroot... " >&6; }
++
++# Check whether --with-libtool-sysroot was given.
++if test "${with_libtool_sysroot+set}" = set; then :
++  withval=$with_libtool_sysroot;
++else
++  with_libtool_sysroot=no
++fi
++
++
++lt_sysroot=
++case ${with_libtool_sysroot} in #(
++ yes)
++   if test "$GCC" = yes; then
++     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
++   fi
++   ;; #(
++ /*)
++   lt_sysroot=`echo "$with_libtool_sysroot" | sed -e "$sed_quote_subst"`
++   ;; #(
++ no|'')
++   ;; #(
++ *)
++   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_libtool_sysroot}" >&5
++$as_echo "${with_libtool_sysroot}" >&6; }
++   as_fn_error "The sysroot must be an absolute path." "$LINENO" 5
++   ;;
++esac
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
++$as_echo "${lt_sysroot:-no}" >&6; }
++
++
++
++
+ 
+ # Check whether --enable-libtool-lock was given.
+ if test "${enable_libtool_lock+set}" = set; then :
+@@ -7112,6 +7492,123 @@
+ 
+ need_locks="$enable_libtool_lock"
+ 
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
++set dummy ${ac_tool_prefix}mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$MANIFEST_TOOL"; then
++  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
++if test -n "$MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
++$as_echo "$MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
++  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
++  # Extract the first word of "mt", so it can be a program name with args.
++set dummy mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_MANIFEST_TOOL"; then
++  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
++if test -n "$ac_ct_MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
++$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_MANIFEST_TOOL" = x; then
++    MANIFEST_TOOL=":"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
++  fi
++else
++  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
++fi
++
++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
++$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
++if test "${lt_cv_path_mainfest_tool+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_path_mainfest_tool=no
++  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
++  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
++  cat conftest.err >&5
++  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
++    lt_cv_path_mainfest_tool=yes
++  fi
++  rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
++$as_echo "$lt_cv_path_mainfest_tool" >&6; }
++if test "x$lt_cv_path_mainfest_tool" != xyes; then
++  MANIFEST_TOOL=:
++fi
++
++
++
++
++
+ 
+   case $host_os in
+     rhapsody* | darwin*)
+@@ -7675,6 +8172,8 @@
+       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+       echo "$AR cru libconftest.a conftest.o" >&5
+       $AR cru libconftest.a conftest.o 2>&5
++      echo "$RANLIB libconftest.a" >&5
++      $RANLIB libconftest.a 2>&5
+       cat > conftest.c << _LT_EOF
+ int main() { return 0;}
+ _LT_EOF
+@@ -7870,7 +8369,8 @@
+ LIBTOOL_DEPS="$ltmain"
+ 
+ # Always use our own libtool.
+-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++LIBTOOL='$(SHELL) $(top_builddir)'
++LIBTOOL="$LIBTOOL/${host_alias}-libtool"
+ 
+ 
+ 
+@@ -7959,7 +8459,7 @@
+ esac
+ 
+ # Global variables:
+-ofile=libtool
++ofile=${host_alias}-libtool
+ can_build_shared=yes
+ 
+ # All known linkers require a `.a' archive for static linking (except MSVC,
+@@ -8257,8 +8757,6 @@
+ lt_prog_compiler_pic=
+ lt_prog_compiler_static=
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 
+   if test "$GCC" = yes; then
+     lt_prog_compiler_wl='-Wl,'
+@@ -8424,6 +8922,12 @@
+ 	lt_prog_compiler_pic='--shared'
+ 	lt_prog_compiler_static='--static'
+ 	;;
++      nagfor*)
++	# NAG Fortran compiler
++	lt_prog_compiler_wl='-Wl,-Wl,,'
++	lt_prog_compiler_pic='-PIC'
++	lt_prog_compiler_static='-Bstatic'
++	;;
+       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+         # Portland Group compilers (*not* the Pentium gcc compiler,
+ 	# which looks to be a dead project)
+@@ -8486,7 +8990,7 @@
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-Bstatic'
+       case $cc_basename in
+-      f77* | f90* | f95*)
++      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ 	lt_prog_compiler_wl='-Qoption ld ';;
+       *)
+ 	lt_prog_compiler_wl='-Wl,';;
+@@ -8543,13 +9047,17 @@
+     lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+     ;;
+ esac
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+-$as_echo "$lt_prog_compiler_pic" >&6; }
+-
+-
+-
+-
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
++$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
++if test "${lt_cv_prog_compiler_pic+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
++$as_echo "$lt_cv_prog_compiler_pic" >&6; }
++lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -8610,6 +9118,11 @@
+ 
+ 
+ 
++
++
++
++
++
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -8960,7 +9473,8 @@
+       allow_undefined_flag=unsupported
+       always_export_symbols=no
+       enable_shared_with_static_runtimes=yes
+-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
++      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ 
+       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+         archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+@@ -9008,7 +9522,7 @@
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -9059,12 +9573,12 @@
+ 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ 	  hardcode_libdir_flag_spec=
+ 	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+-	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
++	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ 	  if test "x$supports_anon_versioning" = xyes; then
+ 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ 	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ 	      echo "local: *; };" >> $output_objdir/$libname.ver~
+-	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
++	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ 	  fi
+ 	  ;;
+ 	esac
+@@ -9078,8 +9592,8 @@
+ 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ 	wlarc=
+       else
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       fi
+       ;;
+ 
+@@ -9097,8 +9611,8 @@
+ 
+ _LT_EOF
+       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9144,8 +9658,8 @@
+ 
+     *)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9275,7 +9789,13 @@
+ 	allow_undefined_flag='-berok'
+         # Determine the default libpath from the value encoded in an
+         # empty executable.
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++        if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9288,22 +9808,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+@@ -9315,7 +9842,13 @@
+ 	else
+ 	 # Determine the default libpath from the value encoded in an
+ 	 # empty executable.
+-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	 if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9328,22 +9861,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+ 	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	  # Warning - without using the other run time loading flags,
+@@ -9388,20 +9928,63 @@
+       # Microsoft Visual C++.
+       # hardcode_libdir_flag_spec is actually meaningless, as there is
+       # no search path for DLLs.
+-      hardcode_libdir_flag_spec=' '
+-      allow_undefined_flag=unsupported
+-      # Tell ltmain to make .lib files, not .a files.
+-      libext=lib
+-      # Tell ltmain to make .dll files, not .so files.
+-      shrext_cmds=".dll"
+-      # FIXME: Setting linknames here is a bad hack.
+-      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+-      # The linker will automatically build a .lib file if we build a DLL.
+-      old_archive_from_new_cmds='true'
+-      # FIXME: Should let the user specify the lib program.
+-      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+-      fix_srcfile_path='`cygpath -w "$srcfile"`'
+-      enable_shared_with_static_runtimes=yes
++      case $cc_basename in
++      cl*)
++	# Native MSVC
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	always_export_symbols=yes
++	file_list_spec='@'
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	  else
++	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	  fi~
++	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	  linknames='
++	# The linker will not automatically build a static lib if we build a DLL.
++	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
++	enable_shared_with_static_runtimes=yes
++	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++	# Don't use ranlib
++	old_postinstall_cmds='chmod 644 $oldlib'
++	postlink_cmds='lt_outputfile="@OUTPUT@"~
++	  lt_tool_outputfile="@TOOL_OUTPUT@"~
++	  case $lt_outputfile in
++	    *.exe|*.EXE) ;;
++	    *)
++	      lt_outputfile="$lt_outputfile.exe"
++	      lt_tool_outputfile="$lt_tool_outputfile.exe"
++	      ;;
++	  esac~
++	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	    $RM "$lt_outputfile.manifest";
++	  fi'
++	;;
++      *)
++	# Assume MSVC wrapper
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
++	# The linker will automatically build a .lib file if we build a DLL.
++	old_archive_from_new_cmds='true'
++	# FIXME: Should let the user specify the lib program.
++	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
++	enable_shared_with_static_runtimes=yes
++	;;
++      esac
+       ;;
+ 
+     darwin* | rhapsody*)
+@@ -9462,7 +10045,7 @@
+ 
+     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+     freebsd* | dragonfly*)
+-      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec='-R$libdir'
+       hardcode_direct=yes
+       hardcode_shlibpath_var=no
+@@ -9470,7 +10053,7 @@
+ 
+     hpux9*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       else
+ 	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       fi
+@@ -9486,7 +10069,7 @@
+ 
+     hpux10*)
+       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+-	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       else
+ 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+       fi
+@@ -9510,10 +10093,10 @@
+ 	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	ia64*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	esac
+       else
+@@ -9592,23 +10175,36 @@
+ 
+     irix5* | irix6* | nonstopux*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	# Try to use the -exported_symbol ld option, if it does not
+ 	# work, assume that -exports_file does not work either and
+ 	# implicitly export all symbols.
+-        save_LDFLAGS="$LDFLAGS"
+-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	# This should be the same for all languages, so no per-tag cache variable.
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
++$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
++if test "${lt_cv_irix_exported_symbol+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  save_LDFLAGS="$LDFLAGS"
++	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
++	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-int foo(void) {}
++int foo (void) { return 0; }
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+-  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+-
++  lt_cv_irix_exported_symbol=yes
++else
++  lt_cv_irix_exported_symbol=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-        LDFLAGS="$save_LDFLAGS"
++           LDFLAGS="$save_LDFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
++$as_echo "$lt_cv_irix_exported_symbol" >&6; }
++	if test "$lt_cv_irix_exported_symbol" = yes; then
++          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
++	fi
+       else
+ 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+@@ -9693,7 +10289,7 @@
+     osf4* | osf5*)	# as osf3* with the addition of -msym flag
+       if test "$GCC" = yes; then
+ 	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+-	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+       else
+ 	allow_undefined_flag=' -expect_unresolved \*'
+@@ -9712,9 +10308,9 @@
+       no_undefined_flag=' -z defs'
+       if test "$GCC" = yes; then
+ 	wlarc='${wl}'
+-	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
++	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+       else
+ 	case `$CC -V 2>&1` in
+ 	*"Compilers 5.0"*)
+@@ -10290,8 +10886,9 @@
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -10324,13 +10921,71 @@
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -10422,7 +11077,7 @@
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -11262,10 +11917,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -11368,10 +12023,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -14948,13 +15603,20 @@
+ lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+ lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+ lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+ reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+ reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+ OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+ deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+ file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
++file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
++want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
++DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
++sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+ AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+ AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
++archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+ STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+ RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+ old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+@@ -14969,14 +15631,17 @@
+ lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
++nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
++lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+ objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+ MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
++lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+ lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+ need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
++MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+ DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+ NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+ LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+@@ -15009,12 +15674,12 @@
+ hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+ inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+ link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+ always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+ export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+ exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+ include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+ prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
++postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+ file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+ variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+ need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+@@ -15069,8 +15734,13 @@
+ OBJDUMP \
+ deplibs_check_method \
+ file_magic_cmd \
++file_magic_glob \
++want_nocaseglob \
++DLLTOOL \
++sharedlib_from_linklib_cmd \
+ AR \
+ AR_FLAGS \
++archiver_list_spec \
+ STRIP \
+ RANLIB \
+ CC \
+@@ -15080,12 +15750,14 @@
+ lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
++nm_file_list_spec \
+ lt_prog_compiler_no_builtin_flag \
+-lt_prog_compiler_wl \
+ lt_prog_compiler_pic \
++lt_prog_compiler_wl \
+ lt_prog_compiler_static \
+ lt_cv_prog_compiler_c_o \
+ need_locks \
++MANIFEST_TOOL \
+ DSYMUTIL \
+ NMEDIT \
+ LIPO \
+@@ -15101,7 +15773,6 @@
+ hardcode_libdir_flag_spec \
+ hardcode_libdir_flag_spec_ld \
+ hardcode_libdir_separator \
+-fix_srcfile_path \
+ exclude_expsyms \
+ include_expsyms \
+ file_list_spec \
+@@ -15137,6 +15808,7 @@
+ module_expsym_cmds \
+ export_symbols_cmds \
+ prelink_cmds \
++postlink_cmds \
+ postinstall_cmds \
+ postuninstall_cmds \
+ finish_cmds \
+@@ -15894,7 +16566,8 @@
+ # NOTE: Changes made to this file will be lost: look at ltmain.sh.
+ #
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ #   This file is part of GNU Libtool.
+@@ -15997,19 +16670,42 @@
+ # turn newlines into spaces.
+ NL2SP=$lt_lt_NL2SP
+ 
++# convert \$build file names to \$host format.
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++
++# convert \$build files to toolchain format.
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++
+ # An object symbol dumper.
+ OBJDUMP=$lt_OBJDUMP
+ 
+ # Method to check whether dependent libraries are shared objects.
+ deplibs_check_method=$lt_deplibs_check_method
+ 
+-# Command to use when deplibs_check_method == "file_magic".
++# Command to use when deplibs_check_method = "file_magic".
+ file_magic_cmd=$lt_file_magic_cmd
+ 
++# How to find potential files when deplibs_check_method = "file_magic".
++file_magic_glob=$lt_file_magic_glob
++
++# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
++want_nocaseglob=$lt_want_nocaseglob
++
++# DLL creation program.
++DLLTOOL=$lt_DLLTOOL
++
++# Command to associate shared and link libraries.
++sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
++
+ # The archiver.
+ AR=$lt_AR
++
++# Flags to create an archive.
+ AR_FLAGS=$lt_AR_FLAGS
+ 
++# How to feed a file listing to the archiver.
++archiver_list_spec=$lt_archiver_list_spec
++
+ # A symbol stripping program.
+ STRIP=$lt_STRIP
+ 
+@@ -16039,6 +16735,12 @@
+ # Transform the output of nm in a C name address pair when lib prefix is needed.
+ global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+ 
++# Specify filename containing input files for \$NM.
++nm_file_list_spec=$lt_nm_file_list_spec
++
++# The root where to search for dependent libraries,and in which our libraries should be installed.
++lt_sysroot=$lt_sysroot
++
+ # The name of the directory that contains temporary libtool files.
+ objdir=$objdir
+ 
+@@ -16048,6 +16750,9 @@
+ # Must we lock files when doing compilation?
+ need_locks=$lt_need_locks
+ 
++# Manifest tool.
++MANIFEST_TOOL=$lt_MANIFEST_TOOL
++
+ # Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+ DSYMUTIL=$lt_DSYMUTIL
+ 
+@@ -16162,12 +16867,12 @@
+ # Compiler flag to turn off builtin functions.
+ no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+ 
+-# How to pass a linker flag through the compiler.
+-wl=$lt_lt_prog_compiler_wl
+-
+ # Additional compiler flags for building library objects.
+ pic_flag=$lt_lt_prog_compiler_pic
+ 
++# How to pass a linker flag through the compiler.
++wl=$lt_lt_prog_compiler_wl
++
+ # Compiler flag to prevent dynamic linking.
+ link_static_flag=$lt_lt_prog_compiler_static
+ 
+@@ -16254,9 +16959,6 @@
+ # Whether libtool must link a program against all its dependency libraries.
+ link_all_deplibs=$link_all_deplibs
+ 
+-# Fix the shell variable \$srcfile for the compiler.
+-fix_srcfile_path=$lt_fix_srcfile_path
+-
+ # Set to "yes" if exported symbols are required.
+ always_export_symbols=$always_export_symbols
+ 
+@@ -16272,6 +16974,9 @@
+ # Commands necessary for linking programs (against libraries) with templates.
+ prelink_cmds=$lt_prelink_cmds
+ 
++# Commands necessary for finishing linking programs.
++postlink_cmds=$lt_postlink_cmds
++
+ # Specify filename containing input files.
+ file_list_spec=$lt_file_list_spec
+ 
+@@ -16304,210 +17009,169 @@
+   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+   # text mode, it properly converts lines to CR/LF.  This bash problem
+   # is reportedly fixed, but why not run on old versions too?
+-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  case $xsi_shell in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_dirname_and_basename file append nondir_replacement
+-# perform func_basename and func_dirname in a single function
+-# call:
+-#   dirname:  Compute the dirname of FILE.  If nonempty,
+-#             add APPEND to the result, otherwise set result
+-#             to NONDIR_REPLACEMENT.
+-#             value returned in "$func_dirname_result"
+-#   basename: Compute filename of FILE.
+-#             value retuned in "$func_basename_result"
+-# Implementation must be kept synchronized with func_dirname
+-# and func_basename. For efficiency, we do not delegate to
+-# those functions but instead duplicate the functionality here.
+-func_dirname_and_basename ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-func_stripname ()
+-{
+-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+-  # positional parameters, so assign one to ordinary parameter first.
+-  func_stripname_result=${3}
+-  func_stripname_result=${func_stripname_result#"${1}"}
+-  func_stripname_result=${func_stripname_result%"${2}"}
+-}
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=${1%%=*}
+-  func_opt_split_arg=${1#*=}
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  case ${1} in
+-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+-    *)    func_lo2o_result=${1} ;;
+-  esac
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=${1%.*}.lo
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=$(( $* ))
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=${#1}
+-}
+-
+-_LT_EOF
+-    ;;
+-  *) # Bourne compatible functions.
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+-}
+-
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-# func_strip_suffix prefix name
+-func_stripname ()
+-{
+-  case ${2} in
+-    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+-    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+-  esac
+-}
+-
+-# sed scripts:
+-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+-my_sed_long_arg='1s/^-[^=]*=//'
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+-  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=`expr "$@"`
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+-}
+-
+-_LT_EOF
+-esac
+-
+-case $lt_shell_append in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1+=\$2"
+-}
+-_LT_EOF
+-    ;;
+-  *)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1=\$$1\$2"
+-}
+-
+-_LT_EOF
+-    ;;
+-  esac
++  sed '$q' "$ltmain" >> "$cfgfile" \
++     || (rm -f "$cfgfile"; exit 1)
+ 
++  if test x"$xsi_shell" = xyes; then
++  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
++func_dirname ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_basename ()$/,/^} # func_basename /c\
++func_basename ()\
++{\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
++func_dirname_and_basename ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
++func_stripname ()\
++{\
++\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
++\    # positional parameters, so assign one to ordinary parameter first.\
++\    func_stripname_result=${3}\
++\    func_stripname_result=${func_stripname_result#"${1}"}\
++\    func_stripname_result=${func_stripname_result%"${2}"}\
++} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
++func_split_long_opt ()\
++{\
++\    func_split_long_opt_name=${1%%=*}\
++\    func_split_long_opt_arg=${1#*=}\
++} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
++func_split_short_opt ()\
++{\
++\    func_split_short_opt_arg=${1#??}\
++\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
++} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
++func_lo2o ()\
++{\
++\    case ${1} in\
++\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
++\      *)    func_lo2o_result=${1} ;;\
++\    esac\
++} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_xform ()$/,/^} # func_xform /c\
++func_xform ()\
++{\
++    func_xform_result=${1%.*}.lo\
++} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_arith ()$/,/^} # func_arith /c\
++func_arith ()\
++{\
++    func_arith_result=$(( $* ))\
++} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_len ()$/,/^} # func_len /c\
++func_len ()\
++{\
++    func_len_result=${#1}\
++} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++fi
++
++if test x"$lt_shell_append" = xyes; then
++  sed -e '/^func_append ()$/,/^} # func_append /c\
++func_append ()\
++{\
++    eval "${1}+=\\${2}"\
++} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
++func_append_quoted ()\
++{\
++\    func_quote_for_eval "${2}"\
++\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
++} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  # Save a `func_append' function call where possible by direct use of '+='
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++else
++  # Save a `func_append' function call even when '+=' is not available
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++fi
++
++if test x"$_lt_function_replace_fail" = x":"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
++$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
++fi
+ 
+-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+ 
+-  mv -f "$cfgfile" "$ofile" ||
++   mv -f "$cfgfile" "$ofile" ||
+     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+   chmod +x "$ofile"
+ 
+Index: binutils-2.24/gas/configure
+===================================================================
+--- binutils-2.24.orig/gas/configure	2013-11-04 07:33:37.000000000 -0800
++++ binutils-2.24/gas/configure	2013-12-15 11:10:23.880452030 -0800
+@@ -645,8 +645,11 @@
+ LIPO
+ NMEDIT
+ DSYMUTIL
++MANIFEST_TOOL
+ RANLIB
++ac_ct_AR
+ AR
++DLLTOOL
+ OBJDUMP
+ LN_S
+ NM
+@@ -759,6 +762,7 @@
+ with_pic
+ enable_fast_install
+ with_gnu_ld
++with_libtool_sysroot
+ enable_libtool_lock
+ enable_targets
+ enable_checking
+@@ -1420,6 +1424,8 @@
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
++  --with-libtool-sysroot=DIR Search for dependent libraries within DIR
++                        (or the compiler's sysroot if not specified).
+   --with-zlib             include zlib support (auto/yes/no) default=auto
+ 
+ Some influential environment variables:
+@@ -5135,8 +5141,8 @@
+ 
+ 
+ 
+-macro_version='2.2.7a'
+-macro_revision='1.3134'
++macro_version='2.4'
++macro_revision='1.3293'
+ 
+ 
+ 
+@@ -5176,7 +5182,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+ $as_echo_n "checking how to print strings... " >&6; }
+ # Test print first, because it will be a builtin if present.
+-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+    test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+   ECHO='print -r --'
+ elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+@@ -5862,8 +5868,8 @@
+ # Try some XSI features
+ xsi_shell=no
+ ( _lt_dummy="a/b/c"
+-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+-      = c,a/b,, \
++  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
++      = c,a/b,b/c, \
+     && eval 'test $(( 1 + 1 )) -eq 2 \
+     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+   && xsi_shell=yes
+@@ -5912,6 +5918,80 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
++$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
++if test "${lt_cv_to_host_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
++        ;;
++    esac
++    ;;
++  *-*-cygwin* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_noop
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
++        ;;
++    esac
++    ;;
++  * ) # unhandled hosts (and "normal" native builds)
++    lt_cv_to_host_file_cmd=func_convert_file_noop
++    ;;
++esac
++
++fi
++
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
++$as_echo "$lt_cv_to_host_file_cmd" >&6; }
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
++$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
++if test "${lt_cv_to_tool_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  #assume ordinary cross tools, or native build.
++lt_cv_to_tool_file_cmd=func_convert_file_noop
++case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
++        ;;
++    esac
++    ;;
++esac
++
++fi
++
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
++$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
++
++
++
++
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+ $as_echo_n "checking for $LD option to reload object files... " >&6; }
+ if test "${lt_cv_ld_reload_flag+set}" = set; then :
+@@ -5928,6 +6008,11 @@
+ esac
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ case $host_os in
++  cygwin* | mingw* | pw32* | cegcc*)
++    if test "$GCC" != yes; then
++      reload_cmds=false
++    fi
++    ;;
+   darwin*)
+     if test "$GCC" = yes; then
+       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+@@ -6096,7 +6181,8 @@
+     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+     lt_cv_file_magic_cmd='func_win32_libid'
+   else
+-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++    # Keep this pattern in sync with the one in func_win32_libid.
++    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+     lt_cv_file_magic_cmd='$OBJDUMP -f'
+   fi
+   ;;
+@@ -6250,6 +6336,21 @@
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+ $as_echo "$lt_cv_deplibs_check_method" >&6; }
++
++file_magic_glob=
++want_nocaseglob=no
++if test "$build" = "$host"; then
++  case $host_os in
++  mingw* | pw32*)
++    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
++      want_nocaseglob=yes
++    else
++      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
++    fi
++    ;;
++  esac
++fi
++
+ file_magic_cmd=$lt_cv_file_magic_cmd
+ deplibs_check_method=$lt_cv_deplibs_check_method
+ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+@@ -6265,9 +6366,162 @@
+ 
+ 
+ 
++
++
++
++
++
++
++
++
++
++
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
++set dummy ${ac_tool_prefix}dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$DLLTOOL"; then
++  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++DLLTOOL=$ac_cv_prog_DLLTOOL
++if test -n "$DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
++$as_echo "$DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_DLLTOOL"; then
++  ac_ct_DLLTOOL=$DLLTOOL
++  # Extract the first word of "dlltool", so it can be a program name with args.
++set dummy dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_DLLTOOL"; then
++  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
++if test -n "$ac_ct_DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
++$as_echo "$ac_ct_DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_DLLTOOL" = x; then
++    DLLTOOL="false"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    DLLTOOL=$ac_ct_DLLTOOL
++  fi
++else
++  DLLTOOL="$ac_cv_prog_DLLTOOL"
++fi
++
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
++$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
++if test "${lt_cv_sharedlib_from_linklib_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_sharedlib_from_linklib_cmd='unknown'
++
++case $host_os in
++cygwin* | mingw* | pw32* | cegcc*)
++  # two different shell functions defined in ltmain.sh
++  # decide which to use based on capabilities of $DLLTOOL
++  case `$DLLTOOL --help 2>&1` in
++  *--identify-strict*)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
++    ;;
++  *)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
++    ;;
++  esac
++  ;;
++*)
++  # fallback: assume linklib IS sharedlib
++  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
++  ;;
++esac
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
++$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
++
++
++
++
++
++
++
+ if test -n "$ac_tool_prefix"; then
+-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+-set dummy ${ac_tool_prefix}ar; ac_word=$2
++  for ac_prog in ar
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_AR+set}" = set; then :
+@@ -6283,7 +6537,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_AR="${ac_tool_prefix}ar"
++    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6303,11 +6557,15 @@
+ fi
+ 
+ 
++    test -n "$AR" && break
++  done
+ fi
+-if test -z "$ac_cv_prog_AR"; then
++if test -z "$AR"; then
+   ac_ct_AR=$AR
+-  # Extract the first word of "ar", so it can be a program name with args.
+-set dummy ar; ac_word=$2
++  for ac_prog in ar
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+@@ -6323,7 +6581,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_ac_ct_AR="ar"
++    ac_cv_prog_ac_ct_AR="$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6342,6 +6600,10 @@
+ $as_echo "no" >&6; }
+ fi
+ 
++
++  test -n "$ac_ct_AR" && break
++done
++
+   if test "x$ac_ct_AR" = x; then
+     AR="false"
+   else
+@@ -6353,16 +6615,72 @@
+ esac
+     AR=$ac_ct_AR
+   fi
+-else
+-  AR="$ac_cv_prog_AR"
+ fi
+ 
+-test -z "$AR" && AR=ar
+-test -z "$AR_FLAGS" && AR_FLAGS=cru
++: ${AR=ar}
++: ${AR_FLAGS=cru}
++
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
++$as_echo_n "checking for archiver @FILE support... " >&6; }
++if test "${lt_cv_ar_at_file+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_ar_at_file=no
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
+ 
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  echo conftest.$ac_objext > conftest.lst
++      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
++      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++      if test "$ac_status" -eq 0; then
++	# Ensure the archiver fails upon bogus file names.
++	rm -f conftest.$ac_objext libconftest.a
++	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++	if test "$ac_status" -ne 0; then
++          lt_cv_ar_at_file=@
++        fi
++      fi
++      rm -f conftest.* libconftest.a
+ 
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ 
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
++$as_echo "$lt_cv_ar_at_file" >&6; }
+ 
++if test "x$lt_cv_ar_at_file" = xno; then
++  archiver_list_spec=
++else
++  archiver_list_spec=$lt_cv_ar_at_file
++fi
+ 
+ 
+ 
+@@ -6704,8 +7022,8 @@
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ 
+ # Transform an extracted symbol line into symbol name and symbol address
+-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+ 
+ # Handle CRLF in mingw tool chain
+ opt_cr=
+@@ -6741,6 +7059,7 @@
+   else
+     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+   fi
++  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+ 
+   # Check to see that the pipe works correctly.
+   pipe_works=no
+@@ -6782,6 +7101,18 @@
+       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ 	  cat <<_LT_EOF > conftest.$ac_ext
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT_DLSYM_CONST
++#else
++# define LT_DLSYM_CONST const
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -6793,7 +7124,7 @@
+ 	  cat <<_LT_EOF >> conftest.$ac_ext
+ 
+ /* The mapping between symbol names and symbols.  */
+-const struct {
++LT_DLSYM_CONST struct {
+   const char *name;
+   void       *address;
+ }
+@@ -6819,8 +7150,8 @@
+ _LT_EOF
+ 	  # Now try linking the two files.
+ 	  mv conftest.$ac_objext conftstm.$ac_objext
+-	  lt_save_LIBS="$LIBS"
+-	  lt_save_CFLAGS="$CFLAGS"
++	  lt_globsym_save_LIBS=$LIBS
++	  lt_globsym_save_CFLAGS=$CFLAGS
+ 	  LIBS="conftstm.$ac_objext"
+ 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+@@ -6830,8 +7161,8 @@
+   test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ 	    pipe_works=yes
+ 	  fi
+-	  LIBS="$lt_save_LIBS"
+-	  CFLAGS="$lt_save_CFLAGS"
++	  LIBS=$lt_globsym_save_LIBS
++	  CFLAGS=$lt_globsym_save_CFLAGS
+ 	else
+ 	  echo "cannot find nm_test_func in $nlist" >&5
+ 	fi
+@@ -6868,6 +7199,19 @@
+ $as_echo "ok" >&6; }
+ fi
+ 
++# Response file support.
++if test "$lt_cv_nm_interface" = "MS dumpbin"; then
++  nm_file_list_spec='@'
++elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
++  nm_file_list_spec='@'
++fi
++
++
++
++
++
++
++
+ 
+ 
+ 
+@@ -6888,6 +7232,42 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
++$as_echo_n "checking for sysroot... " >&6; }
++
++# Check whether --with-libtool-sysroot was given.
++if test "${with_libtool_sysroot+set}" = set; then :
++  withval=$with_libtool_sysroot;
++else
++  with_libtool_sysroot=no
++fi
++
++
++lt_sysroot=
++case ${with_libtool_sysroot} in #(
++ yes)
++   if test "$GCC" = yes; then
++     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
++   fi
++   ;; #(
++ /*)
++   lt_sysroot=`echo "$with_libtool_sysroot" | sed -e "$sed_quote_subst"`
++   ;; #(
++ no|'')
++   ;; #(
++ *)
++   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_libtool_sysroot}" >&5
++$as_echo "${with_libtool_sysroot}" >&6; }
++   as_fn_error "The sysroot must be an absolute path." "$LINENO" 5
++   ;;
++esac
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
++$as_echo "${lt_sysroot:-no}" >&6; }
++
++
++
++
+ 
+ # Check whether --enable-libtool-lock was given.
+ if test "${enable_libtool_lock+set}" = set; then :
+@@ -7095,6 +7475,123 @@
+ 
+ need_locks="$enable_libtool_lock"
+ 
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
++set dummy ${ac_tool_prefix}mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$MANIFEST_TOOL"; then
++  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
++if test -n "$MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
++$as_echo "$MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
++  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
++  # Extract the first word of "mt", so it can be a program name with args.
++set dummy mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_MANIFEST_TOOL"; then
++  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
++if test -n "$ac_ct_MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
++$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_MANIFEST_TOOL" = x; then
++    MANIFEST_TOOL=":"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
++  fi
++else
++  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
++fi
++
++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
++$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
++if test "${lt_cv_path_mainfest_tool+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_path_mainfest_tool=no
++  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
++  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
++  cat conftest.err >&5
++  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
++    lt_cv_path_mainfest_tool=yes
++  fi
++  rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
++$as_echo "$lt_cv_path_mainfest_tool" >&6; }
++if test "x$lt_cv_path_mainfest_tool" != xyes; then
++  MANIFEST_TOOL=:
++fi
++
++
++
++
++
+ 
+   case $host_os in
+     rhapsody* | darwin*)
+@@ -7658,6 +8155,8 @@
+       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+       echo "$AR cru libconftest.a conftest.o" >&5
+       $AR cru libconftest.a conftest.o 2>&5
++      echo "$RANLIB libconftest.a" >&5
++      $RANLIB libconftest.a 2>&5
+       cat > conftest.c << _LT_EOF
+ int main() { return 0;}
+ _LT_EOF
+@@ -7853,7 +8352,8 @@
+ LIBTOOL_DEPS="$ltmain"
+ 
+ # Always use our own libtool.
+-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++LIBTOOL='$(SHELL) $(top_builddir)'
++LIBTOOL="$LIBTOOL/${host_alias}-libtool"
+ 
+ 
+ 
+@@ -7942,7 +8442,7 @@
+ esac
+ 
+ # Global variables:
+-ofile=libtool
++ofile=${host_alias}-libtool
+ can_build_shared=yes
+ 
+ # All known linkers require a `.a' archive for static linking (except MSVC,
+@@ -8240,8 +8740,6 @@
+ lt_prog_compiler_pic=
+ lt_prog_compiler_static=
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 
+   if test "$GCC" = yes; then
+     lt_prog_compiler_wl='-Wl,'
+@@ -8407,6 +8905,12 @@
+ 	lt_prog_compiler_pic='--shared'
+ 	lt_prog_compiler_static='--static'
+ 	;;
++      nagfor*)
++	# NAG Fortran compiler
++	lt_prog_compiler_wl='-Wl,-Wl,,'
++	lt_prog_compiler_pic='-PIC'
++	lt_prog_compiler_static='-Bstatic'
++	;;
+       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+         # Portland Group compilers (*not* the Pentium gcc compiler,
+ 	# which looks to be a dead project)
+@@ -8469,7 +8973,7 @@
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-Bstatic'
+       case $cc_basename in
+-      f77* | f90* | f95*)
++      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ 	lt_prog_compiler_wl='-Qoption ld ';;
+       *)
+ 	lt_prog_compiler_wl='-Wl,';;
+@@ -8526,13 +9030,17 @@
+     lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+     ;;
+ esac
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+-$as_echo "$lt_prog_compiler_pic" >&6; }
+-
+-
+-
+-
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
++$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
++if test "${lt_cv_prog_compiler_pic+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
++$as_echo "$lt_cv_prog_compiler_pic" >&6; }
++lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -8593,6 +9101,11 @@
+ 
+ 
+ 
++
++
++
++
++
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -8943,7 +9456,8 @@
+       allow_undefined_flag=unsupported
+       always_export_symbols=no
+       enable_shared_with_static_runtimes=yes
+-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
++      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ 
+       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+         archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+@@ -8991,7 +9505,7 @@
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -9042,12 +9556,12 @@
+ 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ 	  hardcode_libdir_flag_spec=
+ 	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+-	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
++	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ 	  if test "x$supports_anon_versioning" = xyes; then
+ 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ 	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ 	      echo "local: *; };" >> $output_objdir/$libname.ver~
+-	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
++	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ 	  fi
+ 	  ;;
+ 	esac
+@@ -9061,8 +9575,8 @@
+ 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ 	wlarc=
+       else
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       fi
+       ;;
+ 
+@@ -9080,8 +9594,8 @@
+ 
+ _LT_EOF
+       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9127,8 +9641,8 @@
+ 
+     *)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9258,7 +9772,13 @@
+ 	allow_undefined_flag='-berok'
+         # Determine the default libpath from the value encoded in an
+         # empty executable.
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++        if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9271,22 +9791,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+@@ -9298,7 +9825,13 @@
+ 	else
+ 	 # Determine the default libpath from the value encoded in an
+ 	 # empty executable.
+-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	 if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9311,22 +9844,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+ 	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	  # Warning - without using the other run time loading flags,
+@@ -9371,20 +9911,63 @@
+       # Microsoft Visual C++.
+       # hardcode_libdir_flag_spec is actually meaningless, as there is
+       # no search path for DLLs.
+-      hardcode_libdir_flag_spec=' '
+-      allow_undefined_flag=unsupported
+-      # Tell ltmain to make .lib files, not .a files.
+-      libext=lib
+-      # Tell ltmain to make .dll files, not .so files.
+-      shrext_cmds=".dll"
+-      # FIXME: Setting linknames here is a bad hack.
+-      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+-      # The linker will automatically build a .lib file if we build a DLL.
+-      old_archive_from_new_cmds='true'
+-      # FIXME: Should let the user specify the lib program.
+-      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+-      fix_srcfile_path='`cygpath -w "$srcfile"`'
+-      enable_shared_with_static_runtimes=yes
++      case $cc_basename in
++      cl*)
++	# Native MSVC
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	always_export_symbols=yes
++	file_list_spec='@'
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	  else
++	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	  fi~
++	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	  linknames='
++	# The linker will not automatically build a static lib if we build a DLL.
++	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
++	enable_shared_with_static_runtimes=yes
++	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++	# Don't use ranlib
++	old_postinstall_cmds='chmod 644 $oldlib'
++	postlink_cmds='lt_outputfile="@OUTPUT@"~
++	  lt_tool_outputfile="@TOOL_OUTPUT@"~
++	  case $lt_outputfile in
++	    *.exe|*.EXE) ;;
++	    *)
++	      lt_outputfile="$lt_outputfile.exe"
++	      lt_tool_outputfile="$lt_tool_outputfile.exe"
++	      ;;
++	  esac~
++	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	    $RM "$lt_outputfile.manifest";
++	  fi'
++	;;
++      *)
++	# Assume MSVC wrapper
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
++	# The linker will automatically build a .lib file if we build a DLL.
++	old_archive_from_new_cmds='true'
++	# FIXME: Should let the user specify the lib program.
++	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
++	enable_shared_with_static_runtimes=yes
++	;;
++      esac
+       ;;
+ 
+     darwin* | rhapsody*)
+@@ -9445,7 +10028,7 @@
+ 
+     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+     freebsd* | dragonfly*)
+-      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec='-R$libdir'
+       hardcode_direct=yes
+       hardcode_shlibpath_var=no
+@@ -9453,7 +10036,7 @@
+ 
+     hpux9*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       else
+ 	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       fi
+@@ -9469,7 +10052,7 @@
+ 
+     hpux10*)
+       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+-	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       else
+ 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+       fi
+@@ -9493,10 +10076,10 @@
+ 	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	ia64*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	esac
+       else
+@@ -9575,23 +10158,36 @@
+ 
+     irix5* | irix6* | nonstopux*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	# Try to use the -exported_symbol ld option, if it does not
+ 	# work, assume that -exports_file does not work either and
+ 	# implicitly export all symbols.
+-        save_LDFLAGS="$LDFLAGS"
+-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	# This should be the same for all languages, so no per-tag cache variable.
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
++$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
++if test "${lt_cv_irix_exported_symbol+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  save_LDFLAGS="$LDFLAGS"
++	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
++	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-int foo(void) {}
++int foo (void) { return 0; }
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+-  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+-
++  lt_cv_irix_exported_symbol=yes
++else
++  lt_cv_irix_exported_symbol=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-        LDFLAGS="$save_LDFLAGS"
++           LDFLAGS="$save_LDFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
++$as_echo "$lt_cv_irix_exported_symbol" >&6; }
++	if test "$lt_cv_irix_exported_symbol" = yes; then
++          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
++	fi
+       else
+ 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+@@ -9676,7 +10272,7 @@
+     osf4* | osf5*)	# as osf3* with the addition of -msym flag
+       if test "$GCC" = yes; then
+ 	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+-	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+       else
+ 	allow_undefined_flag=' -expect_unresolved \*'
+@@ -9695,9 +10291,9 @@
+       no_undefined_flag=' -z defs'
+       if test "$GCC" = yes; then
+ 	wlarc='${wl}'
+-	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
++	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+       else
+ 	case `$CC -V 2>&1` in
+ 	*"Compilers 5.0"*)
+@@ -10273,8 +10869,9 @@
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -10307,13 +10904,71 @@
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -10405,7 +11060,7 @@
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -11245,10 +11900,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -11351,10 +12006,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -15064,13 +15719,20 @@
+ lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+ lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+ lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+ reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+ reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+ OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+ deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+ file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
++file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
++want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
++DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
++sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+ AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+ AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
++archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+ STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+ RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+ old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+@@ -15085,14 +15747,17 @@
+ lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
++nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
++lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+ objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+ MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
++lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+ lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+ need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
++MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+ DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+ NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+ LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+@@ -15125,12 +15790,12 @@
+ hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+ inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+ link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+ always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+ export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+ exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+ include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+ prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
++postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+ file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+ variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+ need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+@@ -15185,8 +15850,13 @@
+ OBJDUMP \
+ deplibs_check_method \
+ file_magic_cmd \
++file_magic_glob \
++want_nocaseglob \
++DLLTOOL \
++sharedlib_from_linklib_cmd \
+ AR \
+ AR_FLAGS \
++archiver_list_spec \
+ STRIP \
+ RANLIB \
+ CC \
+@@ -15196,12 +15866,14 @@
+ lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
++nm_file_list_spec \
+ lt_prog_compiler_no_builtin_flag \
+-lt_prog_compiler_wl \
+ lt_prog_compiler_pic \
++lt_prog_compiler_wl \
+ lt_prog_compiler_static \
+ lt_cv_prog_compiler_c_o \
+ need_locks \
++MANIFEST_TOOL \
+ DSYMUTIL \
+ NMEDIT \
+ LIPO \
+@@ -15217,7 +15889,6 @@
+ hardcode_libdir_flag_spec \
+ hardcode_libdir_flag_spec_ld \
+ hardcode_libdir_separator \
+-fix_srcfile_path \
+ exclude_expsyms \
+ include_expsyms \
+ file_list_spec \
+@@ -15253,6 +15924,7 @@
+ module_expsym_cmds \
+ export_symbols_cmds \
+ prelink_cmds \
++postlink_cmds \
+ postinstall_cmds \
+ postuninstall_cmds \
+ finish_cmds \
+@@ -16017,7 +16689,8 @@
+ # NOTE: Changes made to this file will be lost: look at ltmain.sh.
+ #
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ #   This file is part of GNU Libtool.
+@@ -16120,19 +16793,42 @@
+ # turn newlines into spaces.
+ NL2SP=$lt_lt_NL2SP
+ 
++# convert \$build file names to \$host format.
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++
++# convert \$build files to toolchain format.
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++
+ # An object symbol dumper.
+ OBJDUMP=$lt_OBJDUMP
+ 
+ # Method to check whether dependent libraries are shared objects.
+ deplibs_check_method=$lt_deplibs_check_method
+ 
+-# Command to use when deplibs_check_method == "file_magic".
++# Command to use when deplibs_check_method = "file_magic".
+ file_magic_cmd=$lt_file_magic_cmd
+ 
++# How to find potential files when deplibs_check_method = "file_magic".
++file_magic_glob=$lt_file_magic_glob
++
++# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
++want_nocaseglob=$lt_want_nocaseglob
++
++# DLL creation program.
++DLLTOOL=$lt_DLLTOOL
++
++# Command to associate shared and link libraries.
++sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
++
+ # The archiver.
+ AR=$lt_AR
++
++# Flags to create an archive.
+ AR_FLAGS=$lt_AR_FLAGS
+ 
++# How to feed a file listing to the archiver.
++archiver_list_spec=$lt_archiver_list_spec
++
+ # A symbol stripping program.
+ STRIP=$lt_STRIP
+ 
+@@ -16162,6 +16858,12 @@
+ # Transform the output of nm in a C name address pair when lib prefix is needed.
+ global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+ 
++# Specify filename containing input files for \$NM.
++nm_file_list_spec=$lt_nm_file_list_spec
++
++# The root where to search for dependent libraries,and in which our libraries should be installed.
++lt_sysroot=$lt_sysroot
++
+ # The name of the directory that contains temporary libtool files.
+ objdir=$objdir
+ 
+@@ -16171,6 +16873,9 @@
+ # Must we lock files when doing compilation?
+ need_locks=$lt_need_locks
+ 
++# Manifest tool.
++MANIFEST_TOOL=$lt_MANIFEST_TOOL
++
+ # Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+ DSYMUTIL=$lt_DSYMUTIL
+ 
+@@ -16285,12 +16990,12 @@
+ # Compiler flag to turn off builtin functions.
+ no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+ 
+-# How to pass a linker flag through the compiler.
+-wl=$lt_lt_prog_compiler_wl
+-
+ # Additional compiler flags for building library objects.
+ pic_flag=$lt_lt_prog_compiler_pic
+ 
++# How to pass a linker flag through the compiler.
++wl=$lt_lt_prog_compiler_wl
++
+ # Compiler flag to prevent dynamic linking.
+ link_static_flag=$lt_lt_prog_compiler_static
+ 
+@@ -16377,9 +17082,6 @@
+ # Whether libtool must link a program against all its dependency libraries.
+ link_all_deplibs=$link_all_deplibs
+ 
+-# Fix the shell variable \$srcfile for the compiler.
+-fix_srcfile_path=$lt_fix_srcfile_path
+-
+ # Set to "yes" if exported symbols are required.
+ always_export_symbols=$always_export_symbols
+ 
+@@ -16395,6 +17097,9 @@
+ # Commands necessary for linking programs (against libraries) with templates.
+ prelink_cmds=$lt_prelink_cmds
+ 
++# Commands necessary for finishing linking programs.
++postlink_cmds=$lt_postlink_cmds
++
+ # Specify filename containing input files.
+ file_list_spec=$lt_file_list_spec
+ 
+@@ -16427,210 +17132,169 @@
+   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+   # text mode, it properly converts lines to CR/LF.  This bash problem
+   # is reportedly fixed, but why not run on old versions too?
+-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  case $xsi_shell in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_dirname_and_basename file append nondir_replacement
+-# perform func_basename and func_dirname in a single function
+-# call:
+-#   dirname:  Compute the dirname of FILE.  If nonempty,
+-#             add APPEND to the result, otherwise set result
+-#             to NONDIR_REPLACEMENT.
+-#             value returned in "$func_dirname_result"
+-#   basename: Compute filename of FILE.
+-#             value retuned in "$func_basename_result"
+-# Implementation must be kept synchronized with func_dirname
+-# and func_basename. For efficiency, we do not delegate to
+-# those functions but instead duplicate the functionality here.
+-func_dirname_and_basename ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-func_stripname ()
+-{
+-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+-  # positional parameters, so assign one to ordinary parameter first.
+-  func_stripname_result=${3}
+-  func_stripname_result=${func_stripname_result#"${1}"}
+-  func_stripname_result=${func_stripname_result%"${2}"}
+-}
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=${1%%=*}
+-  func_opt_split_arg=${1#*=}
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  case ${1} in
+-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+-    *)    func_lo2o_result=${1} ;;
+-  esac
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=${1%.*}.lo
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=$(( $* ))
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=${#1}
+-}
+-
+-_LT_EOF
+-    ;;
+-  *) # Bourne compatible functions.
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+-}
+-
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-# func_strip_suffix prefix name
+-func_stripname ()
+-{
+-  case ${2} in
+-    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+-    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+-  esac
+-}
+-
+-# sed scripts:
+-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+-my_sed_long_arg='1s/^-[^=]*=//'
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+-  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=`expr "$@"`
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+-}
+-
+-_LT_EOF
+-esac
+-
+-case $lt_shell_append in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1+=\$2"
+-}
+-_LT_EOF
+-    ;;
+-  *)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1=\$$1\$2"
+-}
+-
+-_LT_EOF
+-    ;;
+-  esac
++  sed '$q' "$ltmain" >> "$cfgfile" \
++     || (rm -f "$cfgfile"; exit 1)
+ 
++  if test x"$xsi_shell" = xyes; then
++  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
++func_dirname ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_basename ()$/,/^} # func_basename /c\
++func_basename ()\
++{\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
++func_dirname_and_basename ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
++func_stripname ()\
++{\
++\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
++\    # positional parameters, so assign one to ordinary parameter first.\
++\    func_stripname_result=${3}\
++\    func_stripname_result=${func_stripname_result#"${1}"}\
++\    func_stripname_result=${func_stripname_result%"${2}"}\
++} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
++func_split_long_opt ()\
++{\
++\    func_split_long_opt_name=${1%%=*}\
++\    func_split_long_opt_arg=${1#*=}\
++} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
++func_split_short_opt ()\
++{\
++\    func_split_short_opt_arg=${1#??}\
++\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
++} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
++func_lo2o ()\
++{\
++\    case ${1} in\
++\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
++\      *)    func_lo2o_result=${1} ;;\
++\    esac\
++} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_xform ()$/,/^} # func_xform /c\
++func_xform ()\
++{\
++    func_xform_result=${1%.*}.lo\
++} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_arith ()$/,/^} # func_arith /c\
++func_arith ()\
++{\
++    func_arith_result=$(( $* ))\
++} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_len ()$/,/^} # func_len /c\
++func_len ()\
++{\
++    func_len_result=${#1}\
++} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++fi
++
++if test x"$lt_shell_append" = xyes; then
++  sed -e '/^func_append ()$/,/^} # func_append /c\
++func_append ()\
++{\
++    eval "${1}+=\\${2}"\
++} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
++func_append_quoted ()\
++{\
++\    func_quote_for_eval "${2}"\
++\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
++} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  # Save a `func_append' function call where possible by direct use of '+='
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++else
++  # Save a `func_append' function call even when '+=' is not available
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++fi
++
++if test x"$_lt_function_replace_fail" = x":"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
++$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
++fi
+ 
+-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+ 
+-  mv -f "$cfgfile" "$ofile" ||
++   mv -f "$cfgfile" "$ofile" ||
+     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+   chmod +x "$ofile"
+ 
+Index: binutils-2.24/gprof/configure
+===================================================================
+--- binutils-2.24.orig/gprof/configure	2013-12-15 11:09:51.443785606 -0800
++++ binutils-2.24/gprof/configure	2013-12-15 11:10:23.880452030 -0800
+@@ -629,8 +629,11 @@
+ LIPO
+ NMEDIT
+ DSYMUTIL
++MANIFEST_TOOL
+ RANLIB
++ac_ct_AR
+ AR
++DLLTOOL
+ OBJDUMP
+ LN_S
+ NM
+@@ -743,6 +746,7 @@
+ with_pic
+ enable_fast_install
+ with_gnu_ld
++with_libtool_sysroot
+ enable_libtool_lock
+ enable_nls
+ enable_maintainer_mode
+@@ -1397,6 +1401,8 @@
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
++  --with-libtool-sysroot=DIR Search for dependent libraries within DIR
++                        (or the compiler's sysroot if not specified).
+ 
+ Some influential environment variables:
+   CC          C compiler command
+@@ -5065,8 +5071,8 @@
+ 
+ 
+ 
+-macro_version='2.2.7a'
+-macro_revision='1.3134'
++macro_version='2.4'
++macro_revision='1.3293'
+ 
+ 
+ 
+@@ -5106,7 +5112,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+ $as_echo_n "checking how to print strings... " >&6; }
+ # Test print first, because it will be a builtin if present.
+-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+    test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+   ECHO='print -r --'
+ elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+@@ -5792,8 +5798,8 @@
+ # Try some XSI features
+ xsi_shell=no
+ ( _lt_dummy="a/b/c"
+-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+-      = c,a/b,, \
++  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
++      = c,a/b,b/c, \
+     && eval 'test $(( 1 + 1 )) -eq 2 \
+     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+   && xsi_shell=yes
+@@ -5842,6 +5848,80 @@
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
++$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
++if test "${lt_cv_to_host_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
++        ;;
++    esac
++    ;;
++  *-*-cygwin* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_noop
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
++        ;;
++    esac
++    ;;
++  * ) # unhandled hosts (and "normal" native builds)
++    lt_cv_to_host_file_cmd=func_convert_file_noop
++    ;;
++esac
++
++fi
++
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
++$as_echo "$lt_cv_to_host_file_cmd" >&6; }
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
++$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
++if test "${lt_cv_to_tool_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  #assume ordinary cross tools, or native build.
++lt_cv_to_tool_file_cmd=func_convert_file_noop
++case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
++        ;;
++    esac
++    ;;
++esac
++
++fi
++
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
++$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
++
++
++
++
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+ $as_echo_n "checking for $LD option to reload object files... " >&6; }
+ if test "${lt_cv_ld_reload_flag+set}" = set; then :
+@@ -5858,6 +5938,11 @@
+ esac
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ case $host_os in
++  cygwin* | mingw* | pw32* | cegcc*)
++    if test "$GCC" != yes; then
++      reload_cmds=false
++    fi
++    ;;
+   darwin*)
+     if test "$GCC" = yes; then
+       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+@@ -6026,7 +6111,8 @@
+     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+     lt_cv_file_magic_cmd='func_win32_libid'
+   else
+-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++    # Keep this pattern in sync with the one in func_win32_libid.
++    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+     lt_cv_file_magic_cmd='$OBJDUMP -f'
+   fi
+   ;;
+@@ -6103,11 +6189,6 @@
+   lt_cv_deplibs_check_method=pass_all
+   ;;
+ 
+-linux-uclibc*)
+-  lt_cv_deplibs_check_method=pass_all
+-  lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so`
+-  ;;
+-
+ netbsd*)
+   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+@@ -6185,6 +6266,21 @@
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+ $as_echo "$lt_cv_deplibs_check_method" >&6; }
++
++file_magic_glob=
++want_nocaseglob=no
++if test "$build" = "$host"; then
++  case $host_os in
++  mingw* | pw32*)
++    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
++      want_nocaseglob=yes
++    else
++      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
++    fi
++    ;;
++  esac
++fi
++
+ file_magic_cmd=$lt_cv_file_magic_cmd
+ deplibs_check_method=$lt_cv_deplibs_check_method
+ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+@@ -6200,9 +6296,162 @@
+ 
+ 
+ 
++
++
++
++
++
++
++
++
++
++
+ if test -n "$ac_tool_prefix"; then
+-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+-set dummy ${ac_tool_prefix}ar; ac_word=$2
++  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
++set dummy ${ac_tool_prefix}dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$DLLTOOL"; then
++  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++DLLTOOL=$ac_cv_prog_DLLTOOL
++if test -n "$DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
++$as_echo "$DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_DLLTOOL"; then
++  ac_ct_DLLTOOL=$DLLTOOL
++  # Extract the first word of "dlltool", so it can be a program name with args.
++set dummy dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_DLLTOOL"; then
++  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
++if test -n "$ac_ct_DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
++$as_echo "$ac_ct_DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_DLLTOOL" = x; then
++    DLLTOOL="false"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    DLLTOOL=$ac_ct_DLLTOOL
++  fi
++else
++  DLLTOOL="$ac_cv_prog_DLLTOOL"
++fi
++
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
++$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
++if test "${lt_cv_sharedlib_from_linklib_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_sharedlib_from_linklib_cmd='unknown'
++
++case $host_os in
++cygwin* | mingw* | pw32* | cegcc*)
++  # two different shell functions defined in ltmain.sh
++  # decide which to use based on capabilities of $DLLTOOL
++  case `$DLLTOOL --help 2>&1` in
++  *--identify-strict*)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
++    ;;
++  *)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
++    ;;
++  esac
++  ;;
++*)
++  # fallback: assume linklib IS sharedlib
++  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
++  ;;
++esac
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
++$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
++
++
++
++
++
++
++
++if test -n "$ac_tool_prefix"; then
++  for ac_prog in ar
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_AR+set}" = set; then :
+@@ -6218,7 +6467,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_AR="${ac_tool_prefix}ar"
++    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6238,11 +6487,15 @@
+ fi
+ 
+ 
++    test -n "$AR" && break
++  done
+ fi
+-if test -z "$ac_cv_prog_AR"; then
++if test -z "$AR"; then
+   ac_ct_AR=$AR
+-  # Extract the first word of "ar", so it can be a program name with args.
+-set dummy ar; ac_word=$2
++  for ac_prog in ar
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+@@ -6258,7 +6511,7 @@
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_ac_ct_AR="ar"
++    ac_cv_prog_ac_ct_AR="$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6277,6 +6530,10 @@
+ $as_echo "no" >&6; }
+ fi
+ 
++
++  test -n "$ac_ct_AR" && break
++done
++
+   if test "x$ac_ct_AR" = x; then
+     AR="false"
+   else
+@@ -6288,16 +6545,72 @@
+ esac
+     AR=$ac_ct_AR
+   fi
+-else
+-  AR="$ac_cv_prog_AR"
+ fi
+ 
+-test -z "$AR" && AR=ar
+-test -z "$AR_FLAGS" && AR_FLAGS=cru
++: ${AR=ar}
++: ${AR_FLAGS=cru}
++
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
++$as_echo_n "checking for archiver @FILE support... " >&6; }
++if test "${lt_cv_ar_at_file+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_ar_at_file=no
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
+ 
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  echo conftest.$ac_objext > conftest.lst
++      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
++      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++      if test "$ac_status" -eq 0; then
++	# Ensure the archiver fails upon bogus file names.
++	rm -f conftest.$ac_objext libconftest.a
++	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++	if test "$ac_status" -ne 0; then
++          lt_cv_ar_at_file=@
++        fi
++      fi
++      rm -f conftest.* libconftest.a
+ 
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ 
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
++$as_echo "$lt_cv_ar_at_file" >&6; }
+ 
++if test "x$lt_cv_ar_at_file" = xno; then
++  archiver_list_spec=
++else
++  archiver_list_spec=$lt_cv_ar_at_file
++fi
+ 
+ 
+ 
+@@ -6639,8 +6952,8 @@
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ 
+ # Transform an extracted symbol line into symbol name and symbol address
+-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+ 
+ # Handle CRLF in mingw tool chain
+ opt_cr=
+@@ -6676,6 +6989,7 @@
+   else
+     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+   fi
++  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+ 
+   # Check to see that the pipe works correctly.
+   pipe_works=no
+@@ -6717,6 +7031,18 @@
+       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ 	  cat <<_LT_EOF > conftest.$ac_ext
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT_DLSYM_CONST
++#else
++# define LT_DLSYM_CONST const
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -6728,7 +7054,7 @@
+ 	  cat <<_LT_EOF >> conftest.$ac_ext
+ 
+ /* The mapping between symbol names and symbols.  */
+-const struct {
++LT_DLSYM_CONST struct {
+   const char *name;
+   void       *address;
+ }
+@@ -6754,8 +7080,8 @@
+ _LT_EOF
+ 	  # Now try linking the two files.
+ 	  mv conftest.$ac_objext conftstm.$ac_objext
+-	  lt_save_LIBS="$LIBS"
+-	  lt_save_CFLAGS="$CFLAGS"
++	  lt_globsym_save_LIBS=$LIBS
++	  lt_globsym_save_CFLAGS=$CFLAGS
+ 	  LIBS="conftstm.$ac_objext"
+ 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+@@ -6765,8 +7091,8 @@
+   test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ 	    pipe_works=yes
+ 	  fi
+-	  LIBS="$lt_save_LIBS"
+-	  CFLAGS="$lt_save_CFLAGS"
++	  LIBS=$lt_globsym_save_LIBS
++	  CFLAGS=$lt_globsym_save_CFLAGS
+ 	else
+ 	  echo "cannot find nm_test_func in $nlist" >&5
+ 	fi
+@@ -6803,6 +7129,17 @@
+ $as_echo "ok" >&6; }
+ fi
+ 
++# Response file support.
++if test "$lt_cv_nm_interface" = "MS dumpbin"; then
++  nm_file_list_spec='@'
++elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
++  nm_file_list_spec='@'
++fi
++
++
++
++
++
+ 
+ 
+ 
+@@ -6824,6 +7161,44 @@
+ 
+ 
+ 
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
++$as_echo_n "checking for sysroot... " >&6; }
++
++# Check whether --with-libtool-sysroot was given.
++if test "${with_libtool_sysroot+set}" = set; then :
++  withval=$with_libtool_sysroot;
++else
++  with_libtool_sysroot=no
++fi
++
++
++lt_sysroot=
++case ${with_libtool_sysroot} in #(
++ yes)
++   if test "$GCC" = yes; then
++     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
++   fi
++   ;; #(
++ /*)
++   lt_sysroot=`echo "$with_libtool_sysroot" | sed -e "$sed_quote_subst"`
++   ;; #(
++ no|'')
++   ;; #(
++ *)
++   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_libtool_sysroot}" >&5
++$as_echo "${with_libtool_sysroot}" >&6; }
++   as_fn_error "The sysroot must be an absolute path." "$LINENO" 5
++   ;;
++esac
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
++$as_echo "${lt_sysroot:-no}" >&6; }
++
++
++
++
++
+ # Check whether --enable-libtool-lock was given.
+ if test "${enable_libtool_lock+set}" = set; then :
+   enableval=$enable_libtool_lock;
+@@ -7030,6 +7405,123 @@
+ 
+ need_locks="$enable_libtool_lock"
+ 
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
++set dummy ${ac_tool_prefix}mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$MANIFEST_TOOL"; then
++  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
++if test -n "$MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
++$as_echo "$MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
++  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
++  # Extract the first word of "mt", so it can be a program name with args.
++set dummy mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_MANIFEST_TOOL"; then
++  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
++if test -n "$ac_ct_MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
++$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_MANIFEST_TOOL" = x; then
++    MANIFEST_TOOL=":"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
++  fi
++else
++  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
++fi
++
++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
++$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
++if test "${lt_cv_path_mainfest_tool+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_path_mainfest_tool=no
++  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
++  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
++  cat conftest.err >&5
++  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
++    lt_cv_path_mainfest_tool=yes
++  fi
++  rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
++$as_echo "$lt_cv_path_mainfest_tool" >&6; }
++if test "x$lt_cv_path_mainfest_tool" != xyes; then
++  MANIFEST_TOOL=:
++fi
++
++
++
++
++
+ 
+   case $host_os in
+     rhapsody* | darwin*)
+@@ -7593,6 +8085,8 @@
+       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+       echo "$AR cru libconftest.a conftest.o" >&5
+       $AR cru libconftest.a conftest.o 2>&5
++      echo "$RANLIB libconftest.a" >&5
++      $RANLIB libconftest.a 2>&5
+       cat > conftest.c << _LT_EOF
+ int main() { return 0;}
+ _LT_EOF
+@@ -7788,7 +8282,8 @@
+ LIBTOOL_DEPS="$ltmain"
+ 
+ # Always use our own libtool.
+-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++LIBTOOL='$(SHELL) $(top_builddir)'
++LIBTOOL="$LIBTOOL/${host_alias}-libtool"
+ 
+ 
+ 
+@@ -7877,7 +8372,7 @@
+ esac
+ 
+ # Global variables:
+-ofile=libtool
++ofile=${host_alias}-libtool
+ can_build_shared=yes
+ 
+ # All known linkers require a `.a' archive for static linking (except MSVC,
+@@ -8175,8 +8670,6 @@
+ lt_prog_compiler_pic=
+ lt_prog_compiler_static=
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 
+   if test "$GCC" = yes; then
+     lt_prog_compiler_wl='-Wl,'
+@@ -8342,6 +8835,12 @@
+ 	lt_prog_compiler_pic='--shared'
+ 	lt_prog_compiler_static='--static'
+ 	;;
++      nagfor*)
++	# NAG Fortran compiler
++	lt_prog_compiler_wl='-Wl,-Wl,,'
++	lt_prog_compiler_pic='-PIC'
++	lt_prog_compiler_static='-Bstatic'
++	;;
+       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+         # Portland Group compilers (*not* the Pentium gcc compiler,
+ 	# which looks to be a dead project)
+@@ -8404,7 +8903,7 @@
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-Bstatic'
+       case $cc_basename in
+-      f77* | f90* | f95*)
++      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ 	lt_prog_compiler_wl='-Qoption ld ';;
+       *)
+ 	lt_prog_compiler_wl='-Wl,';;
+@@ -8461,13 +8960,17 @@
+     lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+     ;;
+ esac
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+-$as_echo "$lt_prog_compiler_pic" >&6; }
+-
+-
+-
+-
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
++$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
++if test "${lt_cv_prog_compiler_pic+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
++$as_echo "$lt_cv_prog_compiler_pic" >&6; }
++lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -8528,6 +9031,11 @@
+ 
+ 
+ 
++
++
++
++
++
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -8878,7 +9386,8 @@
+       allow_undefined_flag=unsupported
+       always_export_symbols=no
+       enable_shared_with_static_runtimes=yes
+-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
++      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ 
+       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+         archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+@@ -8926,7 +9435,7 @@
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -8977,12 +9486,12 @@
+ 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ 	  hardcode_libdir_flag_spec=
+ 	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+-	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
++	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ 	  if test "x$supports_anon_versioning" = xyes; then
+ 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ 	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ 	      echo "local: *; };" >> $output_objdir/$libname.ver~
+-	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
++	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ 	  fi
+ 	  ;;
+ 	esac
+@@ -8996,8 +9505,8 @@
+ 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ 	wlarc=
+       else
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       fi
+       ;;
+ 
+@@ -9015,8 +9524,8 @@
+ 
+ _LT_EOF
+       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9062,8 +9571,8 @@
+ 
+     *)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9193,7 +9702,13 @@
+ 	allow_undefined_flag='-berok'
+         # Determine the default libpath from the value encoded in an
+         # empty executable.
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++        if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9206,22 +9721,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+@@ -9233,7 +9755,13 @@
+ 	else
+ 	 # Determine the default libpath from the value encoded in an
+ 	 # empty executable.
+-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	 if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9246,22 +9774,29 @@
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+ 	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	  # Warning - without using the other run time loading flags,
+@@ -9306,20 +9841,63 @@
+       # Microsoft Visual C++.
+       # hardcode_libdir_flag_spec is actually meaningless, as there is
+       # no search path for DLLs.
+-      hardcode_libdir_flag_spec=' '
+-      allow_undefined_flag=unsupported
+-      # Tell ltmain to make .lib files, not .a files.
+-      libext=lib
+-      # Tell ltmain to make .dll files, not .so files.
+-      shrext_cmds=".dll"
+-      # FIXME: Setting linknames here is a bad hack.
+-      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+-      # The linker will automatically build a .lib file if we build a DLL.
+-      old_archive_from_new_cmds='true'
+-      # FIXME: Should let the user specify the lib program.
+-      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+-      fix_srcfile_path='`cygpath -w "$srcfile"`'
+-      enable_shared_with_static_runtimes=yes
++      case $cc_basename in
++      cl*)
++	# Native MSVC
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	always_export_symbols=yes
++	file_list_spec='@'
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	  else
++	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	  fi~
++	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	  linknames='
++	# The linker will not automatically build a static lib if we build a DLL.
++	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
++	enable_shared_with_static_runtimes=yes
++	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++	# Don't use ranlib
++	old_postinstall_cmds='chmod 644 $oldlib'
++	postlink_cmds='lt_outputfile="@OUTPUT@"~
++	  lt_tool_outputfile="@TOOL_OUTPUT@"~
++	  case $lt_outputfile in
++	    *.exe|*.EXE) ;;
++	    *)
++	      lt_outputfile="$lt_outputfile.exe"
++	      lt_tool_outputfile="$lt_tool_outputfile.exe"
++	      ;;
++	  esac~
++	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	    $RM "$lt_outputfile.manifest";
++	  fi'
++	;;
++      *)
++	# Assume MSVC wrapper
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
++	# The linker will automatically build a .lib file if we build a DLL.
++	old_archive_from_new_cmds='true'
++	# FIXME: Should let the user specify the lib program.
++	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
++	enable_shared_with_static_runtimes=yes
++	;;
++      esac
+       ;;
+ 
+     darwin* | rhapsody*)
+@@ -9380,7 +9958,7 @@
+ 
+     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+     freebsd* | dragonfly*)
+-      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec='-R$libdir'
+       hardcode_direct=yes
+       hardcode_shlibpath_var=no
+@@ -9388,7 +9966,7 @@
+ 
+     hpux9*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       else
+ 	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       fi
+@@ -9404,7 +9982,7 @@
+ 
+     hpux10*)
+       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+-	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       else
+ 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+       fi
+@@ -9428,10 +10006,10 @@
+ 	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	ia64*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	esac
+       else
+@@ -9510,23 +10088,36 @@
+ 
+     irix5* | irix6* | nonstopux*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	# Try to use the -exported_symbol ld option, if it does not
+ 	# work, assume that -exports_file does not work either and
+ 	# implicitly export all symbols.
+-        save_LDFLAGS="$LDFLAGS"
+-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	# This should be the same for all languages, so no per-tag cache variable.
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
++$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
++if test "${lt_cv_irix_exported_symbol+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  save_LDFLAGS="$LDFLAGS"
++	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
++	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-int foo(void) {}
++int foo (void) { return 0; }
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+-  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+-
++  lt_cv_irix_exported_symbol=yes
++else
++  lt_cv_irix_exported_symbol=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-        LDFLAGS="$save_LDFLAGS"
++           LDFLAGS="$save_LDFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
++$as_echo "$lt_cv_irix_exported_symbol" >&6; }
++	if test "$lt_cv_irix_exported_symbol" = yes; then
++          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
++	fi
+       else
+ 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+@@ -9611,7 +10202,7 @@
+     osf4* | osf5*)	# as osf3* with the addition of -msym flag
+       if test "$GCC" = yes; then
+ 	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+-	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+       else
+ 	allow_undefined_flag=' -expect_unresolved \*'
+@@ -9630,9 +10221,9 @@
+       no_undefined_flag=' -z defs'
+       if test "$GCC" = yes; then
+ 	wlarc='${wl}'
+-	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
++	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+       else
+ 	case `$CC -V 2>&1` in
+ 	*"Compilers 5.0"*)
+@@ -10208,8 +10799,9 @@
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -10242,13 +10834,71 @@
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -10340,7 +10990,7 @@
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -11180,10 +11830,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -11286,10 +11936,10 @@
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -12831,13 +13481,20 @@
+ lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+ lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+ lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+ reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+ reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+ OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+ deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+ file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
++file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
++want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
++DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
++sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+ AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+ AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
++archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+ STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+ RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+ old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+@@ -12852,14 +13509,17 @@
+ lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
++nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
++lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+ objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+ MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
++lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+ lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+ need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
++MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+ DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+ NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+ LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+@@ -12892,12 +13552,12 @@
+ hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+ inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+ link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+ always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+ export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+ exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+ include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+ prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
++postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+ file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+ variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+ need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+@@ -12952,8 +13612,13 @@
+ OBJDUMP \
+ deplibs_check_method \
+ file_magic_cmd \
++file_magic_glob \
++want_nocaseglob \
++DLLTOOL \
++sharedlib_from_linklib_cmd \
+ AR \
+ AR_FLAGS \
++archiver_list_spec \
+ STRIP \
+ RANLIB \
+ CC \
+@@ -12963,12 +13628,14 @@
+ lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
++nm_file_list_spec \
+ lt_prog_compiler_no_builtin_flag \
+-lt_prog_compiler_wl \
+ lt_prog_compiler_pic \
++lt_prog_compiler_wl \
+ lt_prog_compiler_static \
+ lt_cv_prog_compiler_c_o \
+ need_locks \
++MANIFEST_TOOL \
+ DSYMUTIL \
+ NMEDIT \
+ LIPO \
+@@ -12984,7 +13651,6 @@
+ hardcode_libdir_flag_spec \
+ hardcode_libdir_flag_spec_ld \
+ hardcode_libdir_separator \
+-fix_srcfile_path \
+ exclude_expsyms \
+ include_expsyms \
+ file_list_spec \
+@@ -13020,6 +13686,7 @@
+ module_expsym_cmds \
+ export_symbols_cmds \
+ prelink_cmds \
++postlink_cmds \
+ postinstall_cmds \
+ postuninstall_cmds \
+ finish_cmds \
+@@ -13776,7 +14443,8 @@
+ # NOTE: Changes made to this file will be lost: look at ltmain.sh.
+ #
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ #   This file is part of GNU Libtool.
+@@ -13879,19 +14547,42 @@
+ # turn newlines into spaces.
+ NL2SP=$lt_lt_NL2SP
+ 
++# convert \$build file names to \$host format.
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++
++# convert \$build files to toolchain format.
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++
+ # An object symbol dumper.
+ OBJDUMP=$lt_OBJDUMP
+ 
+ # Method to check whether dependent libraries are shared objects.
+ deplibs_check_method=$lt_deplibs_check_method
+ 
+-# Command to use when deplibs_check_method == "file_magic".
++# Command to use when deplibs_check_method = "file_magic".
+ file_magic_cmd=$lt_file_magic_cmd
+ 
++# How to find potential files when deplibs_check_method = "file_magic".
++file_magic_glob=$lt_file_magic_glob
++
++# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
++want_nocaseglob=$lt_want_nocaseglob
++
++# DLL creation program.
++DLLTOOL=$lt_DLLTOOL
++
++# Command to associate shared and link libraries.
++sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
++
+ # The archiver.
+ AR=$lt_AR
++
++# Flags to create an archive.
+ AR_FLAGS=$lt_AR_FLAGS
+ 
++# How to feed a file listing to the archiver.
++archiver_list_spec=$lt_archiver_list_spec
++
+ # A symbol stripping program.
+ STRIP=$lt_STRIP
+ 
+@@ -13921,6 +14612,12 @@
+ # Transform the output of nm in a C name address pair when lib prefix is needed.
+ global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+ 
++# Specify filename containing input files for \$NM.
++nm_file_list_spec=$lt_nm_file_list_spec
++
++# The root where to search for dependent libraries,and in which our libraries should be installed.
++lt_sysroot=$lt_sysroot
++
+ # The name of the directory that contains temporary libtool files.
+ objdir=$objdir
+ 
+@@ -13930,6 +14627,9 @@
+ # Must we lock files when doing compilation?
+ need_locks=$lt_need_locks
+ 
++# Manifest tool.
++MANIFEST_TOOL=$lt_MANIFEST_TOOL
++
+ # Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+ DSYMUTIL=$lt_DSYMUTIL
+ 
+@@ -14044,12 +14744,12 @@
+ # Compiler flag to turn off builtin functions.
+ no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+ 
+-# How to pass a linker flag through the compiler.
+-wl=$lt_lt_prog_compiler_wl
+-
+ # Additional compiler flags for building library objects.
+ pic_flag=$lt_lt_prog_compiler_pic
+ 
++# How to pass a linker flag through the compiler.
++wl=$lt_lt_prog_compiler_wl
++
+ # Compiler flag to prevent dynamic linking.
+ link_static_flag=$lt_lt_prog_compiler_static
+ 
+@@ -14136,9 +14836,6 @@
+ # Whether libtool must link a program against all its dependency libraries.
+ link_all_deplibs=$link_all_deplibs
+ 
+-# Fix the shell variable \$srcfile for the compiler.
+-fix_srcfile_path=$lt_fix_srcfile_path
+-
+ # Set to "yes" if exported symbols are required.
+ always_export_symbols=$always_export_symbols
+ 
+@@ -14154,6 +14851,9 @@
+ # Commands necessary for linking programs (against libraries) with templates.
+ prelink_cmds=$lt_prelink_cmds
+ 
++# Commands necessary for finishing linking programs.
++postlink_cmds=$lt_postlink_cmds
++
+ # Specify filename containing input files.
+ file_list_spec=$lt_file_list_spec
+ 
+@@ -14186,210 +14886,169 @@
+   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+   # text mode, it properly converts lines to CR/LF.  This bash problem
+   # is reportedly fixed, but why not run on old versions too?
+-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  case $xsi_shell in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_dirname_and_basename file append nondir_replacement
+-# perform func_basename and func_dirname in a single function
+-# call:
+-#   dirname:  Compute the dirname of FILE.  If nonempty,
+-#             add APPEND to the result, otherwise set result
+-#             to NONDIR_REPLACEMENT.
+-#             value returned in "$func_dirname_result"
+-#   basename: Compute filename of FILE.
+-#             value retuned in "$func_basename_result"
+-# Implementation must be kept synchronized with func_dirname
+-# and func_basename. For efficiency, we do not delegate to
+-# those functions but instead duplicate the functionality here.
+-func_dirname_and_basename ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-func_stripname ()
+-{
+-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+-  # positional parameters, so assign one to ordinary parameter first.
+-  func_stripname_result=${3}
+-  func_stripname_result=${func_stripname_result#"${1}"}
+-  func_stripname_result=${func_stripname_result%"${2}"}
+-}
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=${1%%=*}
+-  func_opt_split_arg=${1#*=}
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  case ${1} in
+-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+-    *)    func_lo2o_result=${1} ;;
+-  esac
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=${1%.*}.lo
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=$(( $* ))
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=${#1}
+-}
+-
+-_LT_EOF
+-    ;;
+-  *) # Bourne compatible functions.
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+-}
+-
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-# func_strip_suffix prefix name
+-func_stripname ()
+-{
+-  case ${2} in
+-    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+-    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+-  esac
+-}
+-
+-# sed scripts:
+-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+-my_sed_long_arg='1s/^-[^=]*=//'
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+-  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=`expr "$@"`
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+-}
+-
+-_LT_EOF
+-esac
+-
+-case $lt_shell_append in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1+=\$2"
+-}
+-_LT_EOF
+-    ;;
+-  *)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1=\$$1\$2"
+-}
+-
+-_LT_EOF
+-    ;;
+-  esac
++  sed '$q' "$ltmain" >> "$cfgfile" \
++     || (rm -f "$cfgfile"; exit 1)
+ 
++  if test x"$xsi_shell" = xyes; then
++  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
++func_dirname ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_basename ()$/,/^} # func_basename /c\
++func_basename ()\
++{\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
++func_dirname_and_basename ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
++func_stripname ()\
++{\
++\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
++\    # positional parameters, so assign one to ordinary parameter first.\
++\    func_stripname_result=${3}\
++\    func_stripname_result=${func_stripname_result#"${1}"}\
++\    func_stripname_result=${func_stripname_result%"${2}"}\
++} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
++func_split_long_opt ()\
++{\
++\    func_split_long_opt_name=${1%%=*}\
++\    func_split_long_opt_arg=${1#*=}\
++} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
++func_split_short_opt ()\
++{\
++\    func_split_short_opt_arg=${1#??}\
++\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
++} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
++func_lo2o ()\
++{\
++\    case ${1} in\
++\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
++\      *)    func_lo2o_result=${1} ;;\
++\    esac\
++} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_xform ()$/,/^} # func_xform /c\
++func_xform ()\
++{\
++    func_xform_result=${1%.*}.lo\
++} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_arith ()$/,/^} # func_arith /c\
++func_arith ()\
++{\
++    func_arith_result=$(( $* ))\
++} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_len ()$/,/^} # func_len /c\
++func_len ()\
++{\
++    func_len_result=${#1}\
++} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++fi
++
++if test x"$lt_shell_append" = xyes; then
++  sed -e '/^func_append ()$/,/^} # func_append /c\
++func_append ()\
++{\
++    eval "${1}+=\\${2}"\
++} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
++func_append_quoted ()\
++{\
++\    func_quote_for_eval "${2}"\
++\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
++} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  # Save a `func_append' function call where possible by direct use of '+='
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++else
++  # Save a `func_append' function call even when '+=' is not available
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++fi
++
++if test x"$_lt_function_replace_fail" = x":"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
++$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
++fi
+ 
+-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+ 
+-  mv -f "$cfgfile" "$ofile" ||
++   mv -f "$cfgfile" "$ofile" ||
+     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+   chmod +x "$ofile"
+ 
+Index: binutils-2.24/ld/configure
+===================================================================
+--- binutils-2.24.orig/ld/configure	2013-11-04 07:33:39.000000000 -0800
++++ binutils-2.24/ld/configure	2013-12-15 11:12:06.120451266 -0800
+@@ -654,8 +654,11 @@ OTOOL
+ LIPO
+ NMEDIT
+ DSYMUTIL
++MANIFEST_TOOL
+ RANLIB
++ac_ct_AR
+ AR
++DLLTOOL
+ OBJDUMP
+ LN_S
+ NM
+@@ -776,6 +779,7 @@ enable_static
+ with_pic
+ enable_fast_install
+ with_gnu_ld
++with_libtool_sysroot
+ enable_libtool_lock
+ enable_plugins
+ enable_largefile
+@@ -1453,6 +1457,8 @@ Optional Packages:
+   --with-pic              try to use only PIC/non-PIC objects [default=use
+                           both]
+   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
++  --with-libtool-sysroot=DIR Search for dependent libraries within DIR
++                        (or the compiler's sysroot if not specified).
+   --with-lib-path=dir1:dir2...  set default LIB_PATH
+   --with-sysroot=DIR Search for usr/lib et al within DIR.
+   --with-zlib             include zlib support (auto/yes/no) default=auto
+@@ -5645,8 +5651,8 @@ esac
+ 
+ 
+ 
+-macro_version='2.2.7a'
+-macro_revision='1.3134'
++macro_version='2.4'
++macro_revision='1.3293'
+ 
+ 
+ 
+@@ -5686,7 +5692,7 @@ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+ $as_echo_n "checking how to print strings... " >&6; }
+ # Test print first, because it will be a builtin if present.
+-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+    test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+   ECHO='print -r --'
+ elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+@@ -6372,8 +6378,8 @@ $as_echo_n "checking whether the shell understands some XSI constructs... " >&6;
+ # Try some XSI features
+ xsi_shell=no
+ ( _lt_dummy="a/b/c"
+-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+-      = c,a/b,, \
++  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
++      = c,a/b,b/c, \
+     && eval 'test $(( 1 + 1 )) -eq 2 \
+     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+   && xsi_shell=yes
+@@ -6422,6 +6428,80 @@ esac
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
++$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
++if test "${lt_cv_to_host_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
++        ;;
++    esac
++    ;;
++  *-*-cygwin* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
++        ;;
++      *-*-cygwin* )
++        lt_cv_to_host_file_cmd=func_convert_file_noop
++        ;;
++      * ) # otherwise, assume *nix
++        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
++        ;;
++    esac
++    ;;
++  * ) # unhandled hosts (and "normal" native builds)
++    lt_cv_to_host_file_cmd=func_convert_file_noop
++    ;;
++esac
++
++fi
++
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
++$as_echo "$lt_cv_to_host_file_cmd" >&6; }
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
++$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
++if test "${lt_cv_to_tool_file_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  #assume ordinary cross tools, or native build.
++lt_cv_to_tool_file_cmd=func_convert_file_noop
++case $host in
++  *-*-mingw* )
++    case $build in
++      *-*-mingw* ) # actually msys
++        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
++        ;;
++    esac
++    ;;
++esac
++
++fi
++
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
++$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
++
++
++
++
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+ $as_echo_n "checking for $LD option to reload object files... " >&6; }
+ if test "${lt_cv_ld_reload_flag+set}" = set; then :
+@@ -6438,6 +6518,11 @@ case $reload_flag in
+ esac
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ case $host_os in
++  cygwin* | mingw* | pw32* | cegcc*)
++    if test "$GCC" != yes; then
++      reload_cmds=false
++    fi
++    ;;
+   darwin*)
+     if test "$GCC" = yes; then
+       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+@@ -6606,7 +6691,8 @@ mingw* | pw32*)
+     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+     lt_cv_file_magic_cmd='func_win32_libid'
+   else
+-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++    # Keep this pattern in sync with the one in func_win32_libid.
++    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+     lt_cv_file_magic_cmd='$OBJDUMP -f'
+   fi
+   ;;
+@@ -6760,6 +6846,21 @@ esac
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+ $as_echo "$lt_cv_deplibs_check_method" >&6; }
++
++file_magic_glob=
++want_nocaseglob=no
++if test "$build" = "$host"; then
++  case $host_os in
++  mingw* | pw32*)
++    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
++      want_nocaseglob=yes
++    else
++      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
++    fi
++    ;;
++  esac
++fi
++
+ file_magic_cmd=$lt_cv_file_magic_cmd
+ deplibs_check_method=$lt_cv_deplibs_check_method
+ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+@@ -6775,9 +6876,162 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
+ 
+ 
+ 
++
++
++
++
++
++
++
++
++
++
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
++set dummy ${ac_tool_prefix}dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$DLLTOOL"; then
++  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++DLLTOOL=$ac_cv_prog_DLLTOOL
++if test -n "$DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
++$as_echo "$DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_DLLTOOL"; then
++  ac_ct_DLLTOOL=$DLLTOOL
++  # Extract the first word of "dlltool", so it can be a program name with args.
++set dummy dlltool; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_DLLTOOL"; then
++  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
++if test -n "$ac_ct_DLLTOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
++$as_echo "$ac_ct_DLLTOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_DLLTOOL" = x; then
++    DLLTOOL="false"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    DLLTOOL=$ac_ct_DLLTOOL
++  fi
++else
++  DLLTOOL="$ac_cv_prog_DLLTOOL"
++fi
++
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++
++
++
++
++
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
++$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
++if test "${lt_cv_sharedlib_from_linklib_cmd+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_sharedlib_from_linklib_cmd='unknown'
++
++case $host_os in
++cygwin* | mingw* | pw32* | cegcc*)
++  # two different shell functions defined in ltmain.sh
++  # decide which to use based on capabilities of $DLLTOOL
++  case `$DLLTOOL --help 2>&1` in
++  *--identify-strict*)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
++    ;;
++  *)
++    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
++    ;;
++  esac
++  ;;
++*)
++  # fallback: assume linklib IS sharedlib
++  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
++  ;;
++esac
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
++$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
++
++
++
++
++
++
++
+ if test -n "$ac_tool_prefix"; then
+-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+-set dummy ${ac_tool_prefix}ar; ac_word=$2
++  for ac_prog in ar
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_AR+set}" = set; then :
+@@ -6793,7 +7047,7 @@ do
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_AR="${ac_tool_prefix}ar"
++    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6813,11 +7067,15 @@ $as_echo "no" >&6; }
+ fi
+ 
+ 
++    test -n "$AR" && break
++  done
+ fi
+-if test -z "$ac_cv_prog_AR"; then
++if test -z "$AR"; then
+   ac_ct_AR=$AR
+-  # Extract the first word of "ar", so it can be a program name with args.
+-set dummy ar; ac_word=$2
++  for ac_prog in ar
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+ $as_echo_n "checking for $ac_word... " >&6; }
+ if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+@@ -6833,7 +7091,7 @@ do
+   test -z "$as_dir" && as_dir=.
+     for ac_exec_ext in '' $ac_executable_extensions; do
+   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+-    ac_cv_prog_ac_ct_AR="ar"
++    ac_cv_prog_ac_ct_AR="$ac_prog"
+     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+@@ -6852,6 +7110,10 @@ else
+ $as_echo "no" >&6; }
+ fi
+ 
++
++  test -n "$ac_ct_AR" && break
++done
++
+   if test "x$ac_ct_AR" = x; then
+     AR="false"
+   else
+@@ -6863,12 +7125,12 @@ ac_tool_warned=yes ;;
+ esac
+     AR=$ac_ct_AR
+   fi
+-else
+-  AR="$ac_cv_prog_AR"
+ fi
+ 
+-test -z "$AR" && AR=ar
+-test -z "$AR_FLAGS" && AR_FLAGS=cru
++: ${AR=ar}
++: ${AR_FLAGS=cru}
++
++
+ 
+ 
+ 
+@@ -6878,6 +7140,62 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
++$as_echo_n "checking for archiver @FILE support... " >&6; }
++if test "${lt_cv_ar_at_file+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_ar_at_file=no
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  echo conftest.$ac_objext > conftest.lst
++      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
++      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++      if test "$ac_status" -eq 0; then
++	# Ensure the archiver fails upon bogus file names.
++	rm -f conftest.$ac_objext libconftest.a
++	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
++  (eval $lt_ar_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++	if test "$ac_status" -ne 0; then
++          lt_cv_ar_at_file=@
++        fi
++      fi
++      rm -f conftest.* libconftest.a
++
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
++$as_echo "$lt_cv_ar_at_file" >&6; }
++
++if test "x$lt_cv_ar_at_file" = xno; then
++  archiver_list_spec=
++else
++  archiver_list_spec=$lt_cv_ar_at_file
++fi
++
++
++
++
++
+ 
+ 
+ if test -n "$ac_tool_prefix"; then
+@@ -7214,8 +7532,8 @@ esac
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ 
+ # Transform an extracted symbol line into symbol name and symbol address
+-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+ 
+ # Handle CRLF in mingw tool chain
+ opt_cr=
+@@ -7251,6 +7569,7 @@ for ac_symprfx in "" "_"; do
+   else
+     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+   fi
++  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+ 
+   # Check to see that the pipe works correctly.
+   pipe_works=no
+@@ -7292,6 +7611,18 @@ _LT_EOF
+       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ 	  cat <<_LT_EOF > conftest.$ac_ext
++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
++#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
++/* DATA imports from DLLs on WIN32 con't be const, because runtime
++   relocations are performed -- see ld's documentation on pseudo-relocs.  */
++# define LT_DLSYM_CONST
++#elif defined(__osf__)
++/* This system does not cope well with relocations in const data.  */
++# define LT_DLSYM_CONST
++#else
++# define LT_DLSYM_CONST const
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -7303,7 +7634,7 @@ _LT_EOF
+ 	  cat <<_LT_EOF >> conftest.$ac_ext
+ 
+ /* The mapping between symbol names and symbols.  */
+-const struct {
++LT_DLSYM_CONST struct {
+   const char *name;
+   void       *address;
+ }
+@@ -7329,8 +7660,8 @@ static const void *lt_preloaded_setup() {
+ _LT_EOF
+ 	  # Now try linking the two files.
+ 	  mv conftest.$ac_objext conftstm.$ac_objext
+-	  lt_save_LIBS="$LIBS"
+-	  lt_save_CFLAGS="$CFLAGS"
++	  lt_globsym_save_LIBS=$LIBS
++	  lt_globsym_save_CFLAGS=$CFLAGS
+ 	  LIBS="conftstm.$ac_objext"
+ 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+@@ -7340,8 +7671,8 @@ _LT_EOF
+   test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ 	    pipe_works=yes
+ 	  fi
+-	  LIBS="$lt_save_LIBS"
+-	  CFLAGS="$lt_save_CFLAGS"
++	  LIBS=$lt_globsym_save_LIBS
++	  CFLAGS=$lt_globsym_save_CFLAGS
+ 	else
+ 	  echo "cannot find nm_test_func in $nlist" >&5
+ 	fi
+@@ -7378,6 +7709,19 @@ else
+ $as_echo "ok" >&6; }
+ fi
+ 
++# Response file support.
++if test "$lt_cv_nm_interface" = "MS dumpbin"; then
++  nm_file_list_spec='@'
++elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
++  nm_file_list_spec='@'
++fi
++
++
++
++
++
++
++
+ 
+ 
+ 
+@@ -7398,6 +7742,42 @@ fi
+ 
+ 
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
++$as_echo_n "checking for sysroot... " >&6; }
++
++# Check whether --with-libtool-sysroot was given.
++if test "${with_libtool_sysroot+set}" = set; then :
++  withval=$with_libtool_sysroot;
++else
++  with_libtool_sysroot=no
++fi
++
++
++lt_sysroot=
++case ${with_libtool_sysroot} in #(
++ yes)
++   if test "$GCC" = yes; then
++     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
++   fi
++   ;; #(
++ /*)
++   lt_sysroot=`echo "$with_libtool_sysroot" | sed -e "$sed_quote_subst"`
++   ;; #(
++ no|'')
++   ;; #(
++ *)
++   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_libtool_sysroot}" >&5
++$as_echo "${with_libtool_sysroot}" >&6; }
++   as_fn_error "The sysroot must be an absolute path." "$LINENO" 5
++   ;;
++esac
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
++$as_echo "${lt_sysroot:-no}" >&6; }
++
++
++
++
+ 
+ # Check whether --enable-libtool-lock was given.
+ if test "${enable_libtool_lock+set}" = set; then :
+@@ -7605,6 +7985,123 @@ esac
+ 
+ need_locks="$enable_libtool_lock"
+ 
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
++set dummy ${ac_tool_prefix}mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$MANIFEST_TOOL"; then
++  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
++if test -n "$MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
++$as_echo "$MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
++  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
++  # Extract the first word of "mt", so it can be a program name with args.
++set dummy mt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_ac_ct_MANIFEST_TOOL+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_MANIFEST_TOOL"; then
++  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
++if test -n "$ac_ct_MANIFEST_TOOL"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
++$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_MANIFEST_TOOL" = x; then
++    MANIFEST_TOOL=":"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
++  fi
++else
++  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
++fi
++
++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
++$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
++if test "${lt_cv_path_mainfest_tool+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_path_mainfest_tool=no
++  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
++  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
++  cat conftest.err >&5
++  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
++    lt_cv_path_mainfest_tool=yes
++  fi
++  rm -f conftest*
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
++$as_echo "$lt_cv_path_mainfest_tool" >&6; }
++if test "x$lt_cv_path_mainfest_tool" != xyes; then
++  MANIFEST_TOOL=:
++fi
++
++
++
++
++
+ 
+   case $host_os in
+     rhapsody* | darwin*)
+@@ -8168,6 +8665,8 @@ _LT_EOF
+       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+       echo "$AR cru libconftest.a conftest.o" >&5
+       $AR cru libconftest.a conftest.o 2>&5
++      echo "$RANLIB libconftest.a" >&5
++      $RANLIB libconftest.a 2>&5
+       cat > conftest.c << _LT_EOF
+ int main() { return 0;}
+ _LT_EOF
+@@ -8236,6 +8735,16 @@ done
+ 
+ 
+ 
++func_stripname_cnf ()
++{
++  case ${2} in
++  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
++  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
++  esac
++} # func_stripname_cnf
++
++
++
+ 
+ 
+ # Set options
+@@ -8364,7 +8873,8 @@ fi
+ LIBTOOL_DEPS="$ltmain"
+ 
+ # Always use our own libtool.
+-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++LIBTOOL='$(SHELL) $(top_builddir)'
++LIBTOOL="$LIBTOOL/${host_alias}-libtool"
+ 
+ 
+ 
+@@ -8453,7 +8963,7 @@ aix3*)
+ esac
+ 
+ # Global variables:
+-ofile=libtool
++ofile=${host_alias}-libtool
+ can_build_shared=yes
+ 
+ # All known linkers require a `.a' archive for static linking (except MSVC,
+@@ -8751,8 +9261,6 @@ fi
+ lt_prog_compiler_pic=
+ lt_prog_compiler_static=
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 
+   if test "$GCC" = yes; then
+     lt_prog_compiler_wl='-Wl,'
+@@ -8918,6 +9426,12 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 	lt_prog_compiler_pic='--shared'
+ 	lt_prog_compiler_static='--static'
+ 	;;
++      nagfor*)
++	# NAG Fortran compiler
++	lt_prog_compiler_wl='-Wl,-Wl,,'
++	lt_prog_compiler_pic='-PIC'
++	lt_prog_compiler_static='-Bstatic'
++	;;
+       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+         # Portland Group compilers (*not* the Pentium gcc compiler,
+ 	# which looks to be a dead project)
+@@ -8980,7 +9494,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-Bstatic'
+       case $cc_basename in
+-      f77* | f90* | f95*)
++      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ 	lt_prog_compiler_wl='-Qoption ld ';;
+       *)
+ 	lt_prog_compiler_wl='-Wl,';;
+@@ -9037,13 +9551,17 @@ case $host_os in
+     lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+     ;;
+ esac
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+-$as_echo "$lt_prog_compiler_pic" >&6; }
+-
+-
+-
+-
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
++$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
++if test "${lt_cv_prog_compiler_pic+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
++$as_echo "$lt_cv_prog_compiler_pic" >&6; }
++lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -9104,6 +9622,11 @@ fi
+ 
+ 
+ 
++
++
++
++
++
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -9454,7 +9977,8 @@ _LT_EOF
+       allow_undefined_flag=unsupported
+       always_export_symbols=no
+       enable_shared_with_static_runtimes=yes
+-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
++      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ 
+       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+         archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+@@ -9502,7 +10026,7 @@ _LT_EOF
+       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ 	 && test "$tmp_diet" = no
+       then
+-	tmp_addflag=
++	tmp_addflag=' $pic_flag'
+ 	tmp_sharedflag='-shared'
+ 	case $cc_basename,$host_cpu in
+         pgcc*)				# Portland Group C compiler
+@@ -9553,12 +10077,12 @@ _LT_EOF
+ 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ 	  hardcode_libdir_flag_spec=
+ 	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+-	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
++	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ 	  if test "x$supports_anon_versioning" = xyes; then
+ 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ 	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ 	      echo "local: *; };" >> $output_objdir/$libname.ver~
+-	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
++	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ 	  fi
+ 	  ;;
+ 	esac
+@@ -9572,8 +10096,8 @@ _LT_EOF
+ 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ 	wlarc=
+       else
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       fi
+       ;;
+ 
+@@ -9591,8 +10115,8 @@ _LT_EOF
+ 
+ _LT_EOF
+       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9638,8 +10162,8 @@ _LT_EOF
+ 
+     *)
+       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       else
+ 	ld_shlibs=no
+       fi
+@@ -9769,7 +10293,13 @@ _LT_EOF
+ 	allow_undefined_flag='-berok'
+         # Determine the default libpath from the value encoded in an
+         # empty executable.
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++        if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9782,22 +10312,29 @@ main ()
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+@@ -9809,7 +10346,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 	else
+ 	 # Determine the default libpath from the value encoded in an
+ 	 # empty executable.
+-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	 if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath_+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -9822,22 +10365,29 @@ main ()
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath_"; then
++    lt_cv_aix_libpath_="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath_
++fi
+ 
+ 	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	  # Warning - without using the other run time loading flags,
+@@ -9881,21 +10431,64 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+       # When not using gcc, we currently assume that we are using
+       # Microsoft Visual C++.
+       # hardcode_libdir_flag_spec is actually meaningless, as there is
+-      # no search path for DLLs.
+-      hardcode_libdir_flag_spec=' '
+-      allow_undefined_flag=unsupported
+-      # Tell ltmain to make .lib files, not .a files.
+-      libext=lib
+-      # Tell ltmain to make .dll files, not .so files.
+-      shrext_cmds=".dll"
+-      # FIXME: Setting linknames here is a bad hack.
+-      archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+-      # The linker will automatically build a .lib file if we build a DLL.
+-      old_archive_from_new_cmds='true'
+-      # FIXME: Should let the user specify the lib program.
+-      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+-      fix_srcfile_path='`cygpath -w "$srcfile"`'
+-      enable_shared_with_static_runtimes=yes
++      # no search path for DLLs.
++      case $cc_basename in
++      cl*)
++	# Native MSVC
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	always_export_symbols=yes
++	file_list_spec='@'
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	  else
++	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	  fi~
++	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	  linknames='
++	# The linker will not automatically build a static lib if we build a DLL.
++	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
++	enable_shared_with_static_runtimes=yes
++	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
++	# Don't use ranlib
++	old_postinstall_cmds='chmod 644 $oldlib'
++	postlink_cmds='lt_outputfile="@OUTPUT@"~
++	  lt_tool_outputfile="@TOOL_OUTPUT@"~
++	  case $lt_outputfile in
++	    *.exe|*.EXE) ;;
++	    *)
++	      lt_outputfile="$lt_outputfile.exe"
++	      lt_tool_outputfile="$lt_tool_outputfile.exe"
++	      ;;
++	  esac~
++	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	    $RM "$lt_outputfile.manifest";
++	  fi'
++	;;
++      *)
++	# Assume MSVC wrapper
++	hardcode_libdir_flag_spec=' '
++	allow_undefined_flag=unsupported
++	# Tell ltmain to make .lib files, not .a files.
++	libext=lib
++	# Tell ltmain to make .dll files, not .so files.
++	shrext_cmds=".dll"
++	# FIXME: Setting linknames here is a bad hack.
++	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
++	# The linker will automatically build a .lib file if we build a DLL.
++	old_archive_from_new_cmds='true'
++	# FIXME: Should let the user specify the lib program.
++	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
++	enable_shared_with_static_runtimes=yes
++	;;
++      esac
+       ;;
+ 
+     darwin* | rhapsody*)
+@@ -9956,7 +10549,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 
+     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+     freebsd* | dragonfly*)
+-      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec='-R$libdir'
+       hardcode_direct=yes
+       hardcode_shlibpath_var=no
+@@ -9964,7 +10557,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 
+     hpux9*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       else
+ 	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       fi
+@@ -9980,7 +10573,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 
+     hpux10*)
+       if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+-	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       else
+ 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+       fi
+@@ -10004,10 +10597,10 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	ia64*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	*)
+-	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
++	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ 	  ;;
+ 	esac
+       else
+@@ -10086,23 +10679,36 @@ fi
+ 
+     irix5* | irix6* | nonstopux*)
+       if test "$GCC" = yes; then
+-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	# Try to use the -exported_symbol ld option, if it does not
+ 	# work, assume that -exports_file does not work either and
+ 	# implicitly export all symbols.
+-        save_LDFLAGS="$LDFLAGS"
+-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	# This should be the same for all languages, so no per-tag cache variable.
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
++$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
++if test "${lt_cv_irix_exported_symbol+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  save_LDFLAGS="$LDFLAGS"
++	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
++	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-int foo(void) {}
++int foo (void) { return 0; }
+ _ACEOF
+ if ac_fn_c_try_link "$LINENO"; then :
+-  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+-
++  lt_cv_irix_exported_symbol=yes
++else
++  lt_cv_irix_exported_symbol=no
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-        LDFLAGS="$save_LDFLAGS"
++           LDFLAGS="$save_LDFLAGS"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
++$as_echo "$lt_cv_irix_exported_symbol" >&6; }
++	if test "$lt_cv_irix_exported_symbol" = yes; then
++          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
++	fi
+       else
+ 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+@@ -10187,7 +10793,7 @@ rm -f core conftest.err conftest.$ac_objext \
+     osf4* | osf5*)	# as osf3* with the addition of -msym flag
+       if test "$GCC" = yes; then
+ 	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+-	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+       else
+ 	allow_undefined_flag=' -expect_unresolved \*'
+@@ -10206,9 +10812,9 @@ rm -f core conftest.err conftest.$ac_objext \
+       no_undefined_flag=' -z defs'
+       if test "$GCC" = yes; then
+ 	wlarc='${wl}'
+-	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
++	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+       else
+ 	case `$CC -V 2>&1` in
+ 	*"Compilers 5.0"*)
+@@ -10784,8 +11390,9 @@ cygwin* | mingw* | pw32* | cegcc*)
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -10818,13 +11425,71 @@ cygwin* | mingw* | pw32* | cegcc*)
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -10916,7 +11581,7 @@ haiku*)
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -11712,7 +12377,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 11715 "configure"
++#line $LINENO "configure"
+ #include "confdefs.h"
+ 
+ #if HAVE_DLFCN_H
+@@ -11756,10 +12421,10 @@ else
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -11818,7 +12483,7 @@ else
+   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+   lt_status=$lt_dlunknown
+   cat > conftest.$ac_ext <<_LT_EOF
+-#line 11821 "configure"
++#line $LINENO "configure"
+ #include "confdefs.h"
+ 
+ #if HAVE_DLFCN_H
+@@ -11862,10 +12527,10 @@ else
+ /* When -fvisbility=hidden is used, assume the code has been annotated
+    correspondingly for the symbols needed.  */
+ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+-void fnord () __attribute__((visibility("default")));
++int fnord () __attribute__((visibility("default")));
+ #endif
+ 
+-void fnord () { int i=42; }
++int fnord () { return 42; }
+ int main ()
+ {
+   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+@@ -12257,6 +12922,7 @@ $RM -r conftest*
+ 
+   # Allow CC to be a program name with arguments.
+   lt_save_CC=$CC
++  lt_save_CFLAGS=$CFLAGS
+   lt_save_LD=$LD
+   lt_save_GCC=$GCC
+   GCC=$GXX
+@@ -12274,6 +12940,7 @@ $RM -r conftest*
+   fi
+   test -z "${LDCXX+set}" || LD=$LDCXX
+   CC=${CXX-"c++"}
++  CFLAGS=$CXXFLAGS
+   compiler=$CC
+   compiler_CXX=$CC
+   for cc_temp in $compiler""; do
+@@ -12413,8 +13080,8 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
+       # Check if GNU C++ uses GNU ld as the underlying linker, since the
+       # archiving commands below assume that GNU ld is being used.
+       if test "$with_gnu_ld" = yes; then
+-        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+-        archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
++        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ 
+         hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+         export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+@@ -12556,7 +13223,13 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
+           allow_undefined_flag_CXX='-berok'
+           # Determine the default libpath from the value encoded in an empty
+           # executable.
+-          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++          if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath__CXX+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -12569,22 +13242,29 @@ main ()
+ _ACEOF
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath__CXX"; then
++    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath__CXX"; then
++    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath__CXX
++fi
+ 
+           hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 
+@@ -12597,7 +13277,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+           else
+ 	    # Determine the default libpath from the value encoded in an
+ 	    # empty executable.
+-	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++	    if test "${lt_cv_aix_libpath+set}" = set; then
++  aix_libpath=$lt_cv_aix_libpath
++else
++  if test "${lt_cv_aix_libpath__CXX+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+ int
+@@ -12610,22 +13296,29 @@ main ()
+ _ACEOF
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ 
+-lt_aix_libpath_sed='
+-    /Import File Strings/,/^$/ {
+-	/^0/ {
+-	    s/^0  *\(.*\)$/\1/
+-	    p
+-	}
+-    }'
+-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-# Check for a 64-bit object if we didn't find anything.
+-if test -z "$aix_libpath"; then
+-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+-fi
++  lt_aix_libpath_sed='
++      /Import File Strings/,/^$/ {
++	  /^0/ {
++	      s/^0  *\([^ ]*\) *$/\1/
++	      p
++	  }
++      }'
++  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  # Check for a 64-bit object if we didn't find anything.
++  if test -z "$lt_cv_aix_libpath__CXX"; then
++    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
++  fi
+ fi
+ rm -f core conftest.err conftest.$ac_objext \
+     conftest$ac_exeext conftest.$ac_ext
+-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
++  if test -z "$lt_cv_aix_libpath__CXX"; then
++    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
++  fi
++
++fi
++
++  aix_libpath=$lt_cv_aix_libpath__CXX
++fi
+ 
+ 	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+ 	    # Warning - without using the other run time loading flags,
+@@ -12668,29 +13361,75 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+         ;;
+ 
+       cygwin* | mingw* | pw32* | cegcc*)
+-        # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+-        # as there is no search path for DLLs.
+-        hardcode_libdir_flag_spec_CXX='-L$libdir'
+-        export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+-        allow_undefined_flag_CXX=unsupported
+-        always_export_symbols_CXX=no
+-        enable_shared_with_static_runtimes_CXX=yes
+-
+-        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+-          archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+-          # If the export-symbols file already is a .def file (1st line
+-          # is EXPORTS), use it as is; otherwise, prepend...
+-          archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+-	    cp $export_symbols $output_objdir/$soname.def;
+-          else
+-	    echo EXPORTS > $output_objdir/$soname.def;
+-	    cat $export_symbols >> $output_objdir/$soname.def;
+-          fi~
+-          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+-        else
+-          ld_shlibs_CXX=no
+-        fi
+-        ;;
++	case $GXX,$cc_basename in
++	,cl* | no,cl*)
++	  # Native MSVC
++	  # hardcode_libdir_flag_spec is actually meaningless, as there is
++	  # no search path for DLLs.
++	  hardcode_libdir_flag_spec_CXX=' '
++	  allow_undefined_flag_CXX=unsupported
++	  always_export_symbols_CXX=yes
++	  file_list_spec_CXX='@'
++	  # Tell ltmain to make .lib files, not .a files.
++	  libext=lib
++	  # Tell ltmain to make .dll files, not .so files.
++	  shrext_cmds=".dll"
++	  # FIXME: Setting linknames here is a bad hack.
++	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
++	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
++	    else
++	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
++	    fi~
++	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
++	    linknames='
++	  # The linker will not automatically build a static lib if we build a DLL.
++	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
++	  enable_shared_with_static_runtimes_CXX=yes
++	  # Don't use ranlib
++	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
++	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
++	    lt_tool_outputfile="@TOOL_OUTPUT@"~
++	    case $lt_outputfile in
++	      *.exe|*.EXE) ;;
++	      *)
++		lt_outputfile="$lt_outputfile.exe"
++		lt_tool_outputfile="$lt_tool_outputfile.exe"
++		;;
++	    esac~
++	    func_to_tool_file "$lt_outputfile"~
++	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
++	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
++	      $RM "$lt_outputfile.manifest";
++	    fi'
++	  ;;
++	*)
++	  # g++
++	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
++	  # as there is no search path for DLLs.
++	  hardcode_libdir_flag_spec_CXX='-L$libdir'
++	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
++	  allow_undefined_flag_CXX=unsupported
++	  always_export_symbols_CXX=no
++	  enable_shared_with_static_runtimes_CXX=yes
++
++	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
++	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
++	    # If the export-symbols file already is a .def file (1st line
++	    # is EXPORTS), use it as is; otherwise, prepend...
++	    archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
++	      cp $export_symbols $output_objdir/$soname.def;
++	    else
++	      echo EXPORTS > $output_objdir/$soname.def;
++	      cat $export_symbols >> $output_objdir/$soname.def;
++	    fi~
++	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
++	  else
++	    ld_shlibs_CXX=no
++	  fi
++	  ;;
++	esac
++	;;
+       darwin* | rhapsody*)
+ 
+ 
+@@ -12796,7 +13535,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+             ;;
+           *)
+             if test "$GXX" = yes; then
+-              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
++              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+             else
+               # FIXME: insert proper C++ library support
+               ld_shlibs_CXX=no
+@@ -12867,10 +13606,10 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ 	            ;;
+ 	          ia64*)
+-	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
++	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ 	            ;;
+ 	          *)
+-	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
++	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ 	            ;;
+ 	        esac
+ 	      fi
+@@ -12911,9 +13650,9 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+           *)
+ 	    if test "$GXX" = yes; then
+ 	      if test "$with_gnu_ld" = no; then
+-	        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 	      else
+-	        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
++	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ 	      fi
+ 	    fi
+ 	    link_all_deplibs_CXX=yes
+@@ -12983,20 +13722,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 	      prelink_cmds_CXX='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+-		compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
++		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ 	      old_archive_cmds_CXX='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+-		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
++		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ 		$RANLIB $oldlib'
+ 	      archive_cmds_CXX='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+-		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
++		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ 	      archive_expsym_cmds_CXX='tpldir=Template.dir~
+ 		rm -rf $tpldir~
+ 		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+-		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
++		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ 	      ;;
+ 	    *) # Version 6 and above use weak symbols
+ 	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+@@ -13191,7 +13930,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 		  ;;
+ 	        *)
+-	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ 		  ;;
+ 	      esac
+ 
+@@ -13237,7 +13976,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 
+       solaris*)
+         case $cc_basename in
+-          CC*)
++          CC* | sunCC*)
+ 	    # Sun C++ 4.2, 5.x and Centerline C++
+             archive_cmds_need_lc_CXX=yes
+ 	    no_undefined_flag_CXX=' -zdefs'
+@@ -13278,9 +14017,9 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+ 	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ 	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+ 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+-	        archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
++	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ 	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+-		  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
++		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ 
+ 	        # Commands to make compiler produce verbose output that lists
+ 	        # what "hidden" libraries, object files and flags are used when
+@@ -13415,6 +14154,13 @@ private:
+ };
+ _LT_EOF
+ 
++
++_lt_libdeps_save_CFLAGS=$CFLAGS
++case "$CC $CFLAGS " in #(
++*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
++*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
++esac
++
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+   (eval $ac_compile) 2>&5
+   ac_status=$?
+@@ -13428,7 +14174,7 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+   pre_test_object_deps_done=no
+ 
+   for p in `eval "$output_verbose_link_cmd"`; do
+-    case $p in
++    case ${prev}${p} in
+ 
+     -L* | -R* | -l*)
+        # Some compilers place space between "-{L,R}" and the path.
+@@ -13437,13 +14183,22 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+           test $p = "-R"; then
+ 	 prev=$p
+ 	 continue
+-       else
+-	 prev=
+        fi
+ 
++       # Expand the sysroot to ease extracting the directories later.
++       if test -z "$prev"; then
++         case $p in
++         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
++         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
++         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
++         esac
++       fi
++       case $p in
++       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
++       esac
+        if test "$pre_test_object_deps_done" = no; then
+-	 case $p in
+-	 -L* | -R*)
++	 case ${prev} in
++	 -L | -R)
+ 	   # Internal compiler library paths should come after those
+ 	   # provided the user.  The postdeps already come after the
+ 	   # user supplied libs so there is no need to process them.
+@@ -13463,8 +14218,10 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ 	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+ 	 fi
+        fi
++       prev=
+        ;;
+ 
++    *.lto.$objext) ;; # Ignore GCC LTO objects
+     *.$objext)
+        # This assumes that the test object file only shows up
+        # once in the compiler output.
+@@ -13500,6 +14257,7 @@ else
+ fi
+ 
+ $RM -f confest.$objext
++CFLAGS=$_lt_libdeps_save_CFLAGS
+ 
+ # PORTME: override above test on systems where it is broken
+ case $host_os in
+@@ -13535,7 +14293,7 @@ linux*)
+ 
+ solaris*)
+   case $cc_basename in
+-  CC*)
++  CC* | sunCC*)
+     # The more standards-conforming stlport4 library is
+     # incompatible with the Cstd library. Avoid specifying
+     # it if it's in CXXFLAGS. Ignore libCrun as
+@@ -13600,8 +14358,6 @@ fi
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX=
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 
+   # C++ specific cases for pic, static, wl, etc.
+   if test "$GXX" = yes; then
+@@ -13706,6 +14462,11 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 	  ;;
+ 	esac
+ 	;;
++      mingw* | cygwin* | os2* | pw32* | cegcc*)
++	# This hack is so that the source file can tell whether it is being
++	# built for inclusion in a dll (and should export symbols for example).
++	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
++	;;
+       dgux*)
+ 	case $cc_basename in
+ 	  ec++*)
+@@ -13858,7 +14619,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+ 	;;
+       solaris*)
+ 	case $cc_basename in
+-	  CC*)
++	  CC* | sunCC*)
+ 	    # Sun C++ 4.2, 5.x and Centerline C++
+ 	    lt_prog_compiler_pic_CXX='-KPIC'
+ 	    lt_prog_compiler_static_CXX='-Bstatic'
+@@ -13923,10 +14684,17 @@ case $host_os in
+     lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+     ;;
+ esac
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5
+-$as_echo "$lt_prog_compiler_pic_CXX" >&6; }
+-
+ 
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
++$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
++if test "${lt_cv_prog_compiler_pic_CXX+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
++$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
++lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+ 
+ #
+ # Check to make sure the PIC flag actually works.
+@@ -13984,6 +14752,8 @@ fi
+ 
+ 
+ 
++
++
+ #
+ # Check to make sure the static flag actually works.
+ #
+@@ -14161,6 +14931,7 @@ fi
+ $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+ 
+   export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
++  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+   case $host_os in
+   aix[4-9]*)
+     # If we're using GNU nm, then we don't want the "-C" option.
+@@ -14175,15 +14946,20 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
+     ;;
+   pw32*)
+     export_symbols_cmds_CXX="$ltdll_cmds"
+-  ;;
++    ;;
+   cygwin* | mingw* | cegcc*)
+-    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+-  ;;
++    case $cc_basename in
++    cl*) ;;
++    *)
++      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
++      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
++      ;;
++    esac
++    ;;
+   *)
+     export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+-  ;;
++    ;;
+   esac
+-  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ 
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+ $as_echo "$ld_shlibs_CXX" >&6; }
+@@ -14446,8 +15222,9 @@ cygwin* | mingw* | pw32* | cegcc*)
+   need_version=no
+   need_lib_prefix=no
+ 
+-  case $GCC,$host_os in
+-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
++  case $GCC,$cc_basename in
++  yes,*)
++    # gcc
+     library_names_spec='$libname.dll.a'
+     # DLL is installed to $(libdir)/../bin by postinstall_cmds
+     postinstall_cmds='base_file=`basename \${file}`~
+@@ -14479,13 +15256,71 @@ cygwin* | mingw* | pw32* | cegcc*)
+       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+       ;;
+     esac
++    dynamic_linker='Win32 ld.exe'
++    ;;
++
++  *,cl*)
++    # Native MSVC
++    libname_spec='$name'
++    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
++    library_names_spec='${libname}.dll.lib'
++
++    case $build_os in
++    mingw*)
++      sys_lib_search_path_spec=
++      lt_save_ifs=$IFS
++      IFS=';'
++      for lt_path in $LIB
++      do
++        IFS=$lt_save_ifs
++        # Let DOS variable expansion print the short 8.3 style file name.
++        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
++        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
++      done
++      IFS=$lt_save_ifs
++      # Convert to MSYS style.
++      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
++      ;;
++    cygwin*)
++      # Convert to unix form, then to dos form, then back to unix form
++      # but this time dos style (no spaces!) so that the unix form looks
++      # like /cygdrive/c/PROGRA~1:/cygdr...
++      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
++      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
++      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      ;;
++    *)
++      sys_lib_search_path_spec="$LIB"
++      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
++        # It is most probably a Windows format PATH.
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
++      else
++        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
++      fi
++      # FIXME: find the short name or the path components, as spaces are
++      # common. (e.g. "Program Files" -> "PROGRA~1")
++      ;;
++    esac
++
++    # DLL is installed to $(libdir)/../bin by postinstall_cmds
++    postinstall_cmds='base_file=`basename \${file}`~
++      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
++      dldir=$destdir/`dirname \$dlpath`~
++      test -d \$dldir || mkdir -p \$dldir~
++      $install_prog $dir/$dlname \$dldir/$dlname'
++    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
++      dlpath=$dir/\$dldll~
++       $RM \$dlpath'
++    shlibpath_overrides_runpath=yes
++    dynamic_linker='Win32 link.exe'
+     ;;
+ 
+   *)
++    # Assume MSVC wrapper
+     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
++    dynamic_linker='Win32 ld.exe'
+     ;;
+   esac
+-  dynamic_linker='Win32 ld.exe'
+   # FIXME: first we should search . and the directory the executable is in
+   shlibpath_var=PATH
+   ;;
+@@ -14576,7 +15411,7 @@ haiku*)
+   soname_spec='${libname}${release}${shared_ext}$major'
+   shlibpath_var=LIBRARY_PATH
+   shlibpath_overrides_runpath=yes
+-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
++  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+   hardcode_into_libs=yes
+   ;;
+ 
+@@ -15035,6 +15870,7 @@ fi
+   fi # test -n "$compiler"
+ 
+   CC=$lt_save_CC
++  CFLAGS=$lt_save_CFLAGS
+   LDCXX=$LD
+   LD=$lt_save_LD
+   GCC=$lt_save_GCC
+@@ -17807,13 +18643,20 @@ exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+ lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+ lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+ lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
++lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+ reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+ reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+ OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+ deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+ file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
++file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
++want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
++DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
++sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+ AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+ AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
++archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+ STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+ RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+ old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+@@ -17828,14 +18671,17 @@ lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$de
+ lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
++nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
++lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+ objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+ MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+-lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
++lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+ lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+ need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
++MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+ DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+ NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+ LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+@@ -17868,12 +18714,12 @@ hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_q
+ hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+ inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+ link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+-fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+ always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+ export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+ exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+ include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+ prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
++postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+ file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+ variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+ need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+@@ -17912,8 +18758,8 @@ old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote
+ compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+ GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+-lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
++lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+ lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+ lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+ archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+@@ -17940,12 +18786,12 @@ hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_
+ hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+ inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+ link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+-fix_srcfile_path_CXX='`$ECHO "$fix_srcfile_path_CXX" | $SED "$delay_single_quote_subst"`'
+ always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+ export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+ exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+ include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+ prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
++postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+ file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+ hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+ compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+@@ -17983,8 +18829,13 @@ reload_flag \
+ OBJDUMP \
+ deplibs_check_method \
+ file_magic_cmd \
++file_magic_glob \
++want_nocaseglob \
++DLLTOOL \
++sharedlib_from_linklib_cmd \
+ AR \
+ AR_FLAGS \
++archiver_list_spec \
+ STRIP \
+ RANLIB \
+ CC \
+@@ -17994,12 +18845,14 @@ lt_cv_sys_global_symbol_pipe \
+ lt_cv_sys_global_symbol_to_cdecl \
+ lt_cv_sys_global_symbol_to_c_name_address \
+ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
++nm_file_list_spec \
+ lt_prog_compiler_no_builtin_flag \
+-lt_prog_compiler_wl \
+ lt_prog_compiler_pic \
++lt_prog_compiler_wl \
+ lt_prog_compiler_static \
+ lt_cv_prog_compiler_c_o \
+ need_locks \
++MANIFEST_TOOL \
+ DSYMUTIL \
+ NMEDIT \
+ LIPO \
+@@ -18015,7 +18868,6 @@ no_undefined_flag \
+ hardcode_libdir_flag_spec \
+ hardcode_libdir_flag_spec_ld \
+ hardcode_libdir_separator \
+-fix_srcfile_path \
+ exclude_expsyms \
+ include_expsyms \
+ file_list_spec \
+@@ -18037,8 +18889,8 @@ LD_CXX \
+ reload_flag_CXX \
+ compiler_CXX \
+ lt_prog_compiler_no_builtin_flag_CXX \
+-lt_prog_compiler_wl_CXX \
+ lt_prog_compiler_pic_CXX \
++lt_prog_compiler_wl_CXX \
+ lt_prog_compiler_static_CXX \
+ lt_cv_prog_compiler_c_o_CXX \
+ export_dynamic_flag_spec_CXX \
+@@ -18050,7 +18902,6 @@ no_undefined_flag_CXX \
+ hardcode_libdir_flag_spec_CXX \
+ hardcode_libdir_flag_spec_ld_CXX \
+ hardcode_libdir_separator_CXX \
+-fix_srcfile_path_CXX \
+ exclude_expsyms_CXX \
+ include_expsyms_CXX \
+ file_list_spec_CXX \
+@@ -18084,6 +18935,7 @@ module_cmds \
+ module_expsym_cmds \
+ export_symbols_cmds \
+ prelink_cmds \
++postlink_cmds \
+ postinstall_cmds \
+ postuninstall_cmds \
+ finish_cmds \
+@@ -18098,7 +18950,8 @@ archive_expsym_cmds_CXX \
+ module_cmds_CXX \
+ module_expsym_cmds_CXX \
+ export_symbols_cmds_CXX \
+-prelink_cmds_CXX; do
++prelink_cmds_CXX \
++postlink_cmds_CXX; do
+     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+     *[\\\\\\\`\\"\\\$]*)
+       eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+@@ -18891,7 +19744,8 @@ $as_echo X"$file" |
+ # NOTE: Changes made to this file will be lost: look at ltmain.sh.
+ #
+ #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+-#                 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
++#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
++#                 Inc.
+ #   Written by Gordon Matzigkeit, 1996
+ #
+ #   This file is part of GNU Libtool.
+@@ -18994,19 +19848,42 @@ SP2NL=$lt_lt_SP2NL
+ # turn newlines into spaces.
+ NL2SP=$lt_lt_NL2SP
+ 
++# convert \$build file names to \$host format.
++to_host_file_cmd=$lt_cv_to_host_file_cmd
++
++# convert \$build files to toolchain format.
++to_tool_file_cmd=$lt_cv_to_tool_file_cmd
++
+ # An object symbol dumper.
+ OBJDUMP=$lt_OBJDUMP
+ 
+ # Method to check whether dependent libraries are shared objects.
+ deplibs_check_method=$lt_deplibs_check_method
+ 
+-# Command to use when deplibs_check_method == "file_magic".
++# Command to use when deplibs_check_method = "file_magic".
+ file_magic_cmd=$lt_file_magic_cmd
+ 
++# How to find potential files when deplibs_check_method = "file_magic".
++file_magic_glob=$lt_file_magic_glob
++
++# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
++want_nocaseglob=$lt_want_nocaseglob
++
++# DLL creation program.
++DLLTOOL=$lt_DLLTOOL
++
++# Command to associate shared and link libraries.
++sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
++
+ # The archiver.
+ AR=$lt_AR
++
++# Flags to create an archive.
+ AR_FLAGS=$lt_AR_FLAGS
+ 
++# How to feed a file listing to the archiver.
++archiver_list_spec=$lt_archiver_list_spec
++
+ # A symbol stripping program.
+ STRIP=$lt_STRIP
+ 
+@@ -19036,6 +19913,12 @@ global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+ # Transform the output of nm in a C name address pair when lib prefix is needed.
+ global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+ 
++# Specify filename containing input files for \$NM.
++nm_file_list_spec=$lt_nm_file_list_spec
++
++# The root where to search for dependent libraries,and in which our libraries should be installed.
++lt_sysroot=$lt_sysroot
++
+ # The name of the directory that contains temporary libtool files.
+ objdir=$objdir
+ 
+@@ -19045,6 +19928,9 @@ MAGIC_CMD=$MAGIC_CMD
+ # Must we lock files when doing compilation?
+ need_locks=$lt_need_locks
+ 
++# Manifest tool.
++MANIFEST_TOOL=$lt_MANIFEST_TOOL
++
+ # Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+ DSYMUTIL=$lt_DSYMUTIL
+ 
+@@ -19159,12 +20045,12 @@ with_gcc=$GCC
+ # Compiler flag to turn off builtin functions.
+ no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+ 
+-# How to pass a linker flag through the compiler.
+-wl=$lt_lt_prog_compiler_wl
+-
+ # Additional compiler flags for building library objects.
+ pic_flag=$lt_lt_prog_compiler_pic
+ 
++# How to pass a linker flag through the compiler.
++wl=$lt_lt_prog_compiler_wl
++
+ # Compiler flag to prevent dynamic linking.
+ link_static_flag=$lt_lt_prog_compiler_static
+ 
+@@ -19251,9 +20137,6 @@ inherit_rpath=$inherit_rpath
+ # Whether libtool must link a program against all its dependency libraries.
+ link_all_deplibs=$link_all_deplibs
+ 
+-# Fix the shell variable \$srcfile for the compiler.
+-fix_srcfile_path=$lt_fix_srcfile_path
+-
+ # Set to "yes" if exported symbols are required.
+ always_export_symbols=$always_export_symbols
+ 
+@@ -19269,6 +20152,9 @@ include_expsyms=$lt_include_expsyms
+ # Commands necessary for linking programs (against libraries) with templates.
+ prelink_cmds=$lt_prelink_cmds
+ 
++# Commands necessary for finishing linking programs.
++postlink_cmds=$lt_postlink_cmds
++
+ # Specify filename containing input files.
+ file_list_spec=$lt_file_list_spec
+ 
+@@ -19315,210 +20201,169 @@ ltmain="$ac_aux_dir/ltmain.sh"
+   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+   # text mode, it properly converts lines to CR/LF.  This bash problem
+   # is reportedly fixed, but why not run on old versions too?
+-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  case $xsi_shell in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_dirname_and_basename file append nondir_replacement
+-# perform func_basename and func_dirname in a single function
+-# call:
+-#   dirname:  Compute the dirname of FILE.  If nonempty,
+-#             add APPEND to the result, otherwise set result
+-#             to NONDIR_REPLACEMENT.
+-#             value returned in "$func_dirname_result"
+-#   basename: Compute filename of FILE.
+-#             value retuned in "$func_basename_result"
+-# Implementation must be kept synchronized with func_dirname
+-# and func_basename. For efficiency, we do not delegate to
+-# those functions but instead duplicate the functionality here.
+-func_dirname_and_basename ()
+-{
+-  case ${1} in
+-    */*) func_dirname_result="${1%/*}${2}" ;;
+-    *  ) func_dirname_result="${3}" ;;
+-  esac
+-  func_basename_result="${1##*/}"
+-}
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-func_stripname ()
+-{
+-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+-  # positional parameters, so assign one to ordinary parameter first.
+-  func_stripname_result=${3}
+-  func_stripname_result=${func_stripname_result#"${1}"}
+-  func_stripname_result=${func_stripname_result%"${2}"}
+-}
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=${1%%=*}
+-  func_opt_split_arg=${1#*=}
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  case ${1} in
+-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+-    *)    func_lo2o_result=${1} ;;
+-  esac
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=${1%.*}.lo
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=$(( $* ))
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=${#1}
+-}
+-
+-_LT_EOF
+-    ;;
+-  *) # Bourne compatible functions.
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_dirname file append nondir_replacement
+-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+-# otherwise set result to NONDIR_REPLACEMENT.
+-func_dirname ()
+-{
+-  # Extract subdirectory from the argument.
+-  func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+-  if test "X$func_dirname_result" = "X${1}"; then
+-    func_dirname_result="${3}"
+-  else
+-    func_dirname_result="$func_dirname_result${2}"
+-  fi
+-}
+-
+-# func_basename file
+-func_basename ()
+-{
+-  func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+-}
+-
+-
+-# func_stripname prefix suffix name
+-# strip PREFIX and SUFFIX off of NAME.
+-# PREFIX and SUFFIX must not contain globbing or regex special
+-# characters, hashes, percent signs, but SUFFIX may contain a leading
+-# dot (in which case that matches only a dot).
+-# func_strip_suffix prefix name
+-func_stripname ()
+-{
+-  case ${2} in
+-    .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+-    *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+-  esac
+-}
+-
+-# sed scripts:
+-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+-my_sed_long_arg='1s/^-[^=]*=//'
+-
+-# func_opt_split
+-func_opt_split ()
+-{
+-  func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+-  func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+-}
+-
+-# func_lo2o object
+-func_lo2o ()
+-{
+-  func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+-}
+-
+-# func_xform libobj-or-source
+-func_xform ()
+-{
+-  func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+-}
+-
+-# func_arith arithmetic-term...
+-func_arith ()
+-{
+-  func_arith_result=`expr "$@"`
+-}
+-
+-# func_len string
+-# STRING may not start with a hyphen.
+-func_len ()
+-{
+-  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+-}
+-
+-_LT_EOF
+-esac
+-
+-case $lt_shell_append in
+-  yes)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1+=\$2"
+-}
+-_LT_EOF
+-    ;;
+-  *)
+-    cat << \_LT_EOF >> "$cfgfile"
+-
+-# func_append var value
+-# Append VALUE to the end of shell variable VAR.
+-func_append ()
+-{
+-  eval "$1=\$$1\$2"
+-}
+-
+-_LT_EOF
+-    ;;
+-  esac
+-
+-
+-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+-    || (rm -f "$cfgfile"; exit 1)
+-
+-  mv -f "$cfgfile" "$ofile" ||
++  sed '$q' "$ltmain" >> "$cfgfile" \
++     || (rm -f "$cfgfile"; exit 1)
++
++  if test x"$xsi_shell" = xyes; then
++  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
++func_dirname ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_basename ()$/,/^} # func_basename /c\
++func_basename ()\
++{\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
++func_dirname_and_basename ()\
++{\
++\    case ${1} in\
++\      */*) func_dirname_result="${1%/*}${2}" ;;\
++\      *  ) func_dirname_result="${3}" ;;\
++\    esac\
++\    func_basename_result="${1##*/}"\
++} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
++func_stripname ()\
++{\
++\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
++\    # positional parameters, so assign one to ordinary parameter first.\
++\    func_stripname_result=${3}\
++\    func_stripname_result=${func_stripname_result#"${1}"}\
++\    func_stripname_result=${func_stripname_result%"${2}"}\
++} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
++func_split_long_opt ()\
++{\
++\    func_split_long_opt_name=${1%%=*}\
++\    func_split_long_opt_arg=${1#*=}\
++} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
++func_split_short_opt ()\
++{\
++\    func_split_short_opt_arg=${1#??}\
++\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
++} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
++func_lo2o ()\
++{\
++\    case ${1} in\
++\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
++\      *)    func_lo2o_result=${1} ;;\
++\    esac\
++} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_xform ()$/,/^} # func_xform /c\
++func_xform ()\
++{\
++    func_xform_result=${1%.*}.lo\
++} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_arith ()$/,/^} # func_arith /c\
++func_arith ()\
++{\
++    func_arith_result=$(( $* ))\
++} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_len ()$/,/^} # func_len /c\
++func_len ()\
++{\
++    func_len_result=${#1}\
++} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++fi
++
++if test x"$lt_shell_append" = xyes; then
++  sed -e '/^func_append ()$/,/^} # func_append /c\
++func_append ()\
++{\
++    eval "${1}+=\\${2}"\
++} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
++func_append_quoted ()\
++{\
++\    func_quote_for_eval "${2}"\
++\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
++} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
++  && mv -f "$cfgfile.tmp" "$cfgfile" \
++    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++test 0 -eq $? || _lt_function_replace_fail=:
++
++
++  # Save a `func_append' function call where possible by direct use of '+='
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++else
++  # Save a `func_append' function call even when '+=' is not available
++  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
++    && mv -f "$cfgfile.tmp" "$cfgfile" \
++      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
++  test 0 -eq $? || _lt_function_replace_fail=:
++fi
++
++if test x"$_lt_function_replace_fail" = x":"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
++$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
++fi
++
++
++   mv -f "$cfgfile" "$ofile" ||
+     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+   chmod +x "$ofile"
+ 
+@@ -19546,12 +20391,12 @@ with_gcc=$GCC_CXX
+ # Compiler flag to turn off builtin functions.
+ no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+ 
+-# How to pass a linker flag through the compiler.
+-wl=$lt_lt_prog_compiler_wl_CXX
+-
+ # Additional compiler flags for building library objects.
+ pic_flag=$lt_lt_prog_compiler_pic_CXX
+ 
++# How to pass a linker flag through the compiler.
++wl=$lt_lt_prog_compiler_wl_CXX
++
+ # Compiler flag to prevent dynamic linking.
+ link_static_flag=$lt_lt_prog_compiler_static_CXX
+ 
+@@ -19638,9 +20483,6 @@ inherit_rpath=$inherit_rpath_CXX
+ # Whether libtool must link a program against all its dependency libraries.
+ link_all_deplibs=$link_all_deplibs_CXX
+ 
+-# Fix the shell variable \$srcfile for the compiler.
+-fix_srcfile_path=$lt_fix_srcfile_path_CXX
+-
+ # Set to "yes" if exported symbols are required.
+ always_export_symbols=$always_export_symbols_CXX
+ 
+@@ -19656,6 +20498,9 @@ include_expsyms=$lt_include_expsyms_CXX
+ # Commands necessary for linking programs (against libraries) with templates.
+ prelink_cmds=$lt_prelink_cmds_CXX
+ 
++# Commands necessary for finishing linking programs.
++postlink_cmds=$lt_postlink_cmds_CXX
++
+ # Specify filename containing input files.
+ file_list_spec=$lt_file_list_spec_CXX
+ 
+Index: binutils-2.24/bfd/configure.ac
+===================================================================
+--- binutils-2.24.orig/bfd/configure.ac	2013-12-02 01:30:28.000000000 -0800
++++ binutils-2.24/bfd/configure.ac	2013-12-15 11:10:23.887118697 -0800
+@@ -568,7 +568,7 @@
+   x=`sed -n -e 's/^[ 	]*PICFLAG[ 	]*=[ 	]*//p' < ../libiberty/Makefile | sed -n '$p'`
+ changequote([,])dnl
+   if test -n "$x"; then
+-    SHARED_LIBADD="-L`pwd`/../libiberty/pic -liberty"
++    SHARED_LIBADD="`pwd`/../libiberty/pic/libiberty.a"
+   fi
+ 
+ # More hacks to build DLLs on Windows.
+Index: binutils-2.24/opcodes/configure.ac
+===================================================================
+--- binutils-2.24.orig/opcodes/configure.ac	2013-11-04 07:33:40.000000000 -0800
++++ binutils-2.24/opcodes/configure.ac	2013-12-15 11:10:23.887118697 -0800
+@@ -162,7 +162,7 @@
+   x=`sed -n -e 's/^[ 	]*PICFLAG[ 	]*=[ 	]*//p' < ../libiberty/Makefile | sed -n '$p'`
+ changequote([,])dnl
+   if test -n "$x"; then
+-    SHARED_LIBADD="-L`pwd`/../libiberty/pic -liberty"
++    SHARED_LIBADD="`pwd`/../libiberty/pic/libiberty.a"
+   fi
+ 
+   case "${host}" in
diff --git a/recipes-devtools/binutils/binutils/libtool-rpath-fix.patch b/recipes-devtools/binutils/binutils/libtool-rpath-fix.patch
new file mode 100644
index 0000000..4fcffa4
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/libtool-rpath-fix.patch
@@ -0,0 +1,39 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+Enabling sysroot support in libtool exposed a bug where the final
+library had an RPATH encoded into it which still pointed to the
+sysroot. This works around the issue until it gets sorted out
+upstream.
+
+Fix suggested by Richard Purdie <richard.purdie@linuxfoundation.org> 
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
+Index: binutils-2.22/ltmain.sh
+===================================================================
+--- binutils-2.22.orig/ltmain.sh
++++ binutils-2.22/ltmain.sh
+@@ -8035,9 +8035,11 @@ EOF
+ 	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ 	  for libdir in $rpath; do
+ 	    if test -n "$hardcode_libdir_flag_spec"; then
++		  func_replace_sysroot "$libdir"
++		  libdir=$func_replace_sysroot_result
++		  func_stripname '=' '' "$libdir"
++		  libdir=$func_stripname_result
+ 	      if test -n "$hardcode_libdir_separator"; then
+-		func_replace_sysroot "$libdir"
+-		libdir=$func_replace_sysroot_result
+ 		if test -z "$hardcode_libdirs"; then
+ 		  hardcode_libdirs="$libdir"
+ 		else
+@@ -8770,6 +8772,10 @@ EOF
+       hardcode_libdirs=
+       for libdir in $compile_rpath $finalize_rpath; do
+ 	if test -n "$hardcode_libdir_flag_spec"; then
++	  func_replace_sysroot "$libdir"
++	  libdir=$func_replace_sysroot_result
++	  func_stripname '=' '' "$libdir"
++	  libdir=$func_stripname_result
+ 	  if test -n "$hardcode_libdir_separator"; then
+ 	    if test -z "$hardcode_libdirs"; then
+ 	      hardcode_libdirs="$libdir"
diff --git a/recipes-devtools/binutils/binutils/mips64-default-ld-emulation.patch b/recipes-devtools/binutils/binutils/mips64-default-ld-emulation.patch
new file mode 100644
index 0000000..e668faa
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/mips64-default-ld-emulation.patch
@@ -0,0 +1,48 @@
+for mips64*-*-linux we change the default emulations to be
+N64 instead of N32
+
+Upstream-Status: Inappropriate [ OE configuration Specific]
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Index: binutils-2.24/bfd/config.bfd
+===================================================================
+--- binutils-2.24.orig/bfd/config.bfd	2013-11-04 07:33:37.000000000 -0800
++++ binutils-2.24/bfd/config.bfd	2013-12-15 11:54:57.113765374 -0800
+Index: binutils-2.24/ld/configure.tgt
+@@ -1062,12 +1062,12 @@ case "${targ}" in
+     targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
+     ;;
+   mips64*el-*-linux*)
+-    targ_defvec=mips_elf32_ntrad_le_vec
+-    targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
++    targ_defvec=mips_elf64_trad_le_vec
++    targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_be_vec"
+     ;;
+   mips64*-*-linux*)
+-    targ_defvec=mips_elf32_ntrad_be_vec
+-    targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
++    targ_defvec=mips_elf64_trad_be_vec
++    targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_be_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_le_vec"
+     ;;
+   mips*el-*-linux*)
+     targ_defvec=mips_elf32_trad_le_vec
+===================================================================
+--- binutils-2.24.orig/ld/configure.tgt	2013-11-26 03:37:33.000000000 -0800
++++ binutils-2.24/ld/configure.tgt	2013-12-15 11:50:52.273766155 -0800
+@@ -471,11 +471,11 @@
+ mips*-*-vxworks*)	targ_emul=elf32ebmipvxworks
+ 		        targ_extra_emuls="elf32elmipvxworks" ;;
+ mips*-*-windiss)	targ_emul=elf32mipswindiss ;;
+-mips64*el-*-linux-*)	targ_emul=elf32ltsmipn32
+-			targ_extra_emuls="elf32btsmipn32 elf32ltsmip elf32btsmip elf64ltsmip elf64btsmip"
++mips64*el-*-linux-*)	targ_emul=elf64ltsmip
++			targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32ltsmip elf32btsmip elf64btsmip"
+ 			targ_extra_libpath=$targ_extra_emuls ;;
+-mips64*-*-linux-*)	targ_emul=elf32btsmipn32
+-			targ_extra_emuls="elf32ltsmipn32 elf32btsmip elf32ltsmip elf64btsmip elf64ltsmip"
++mips64*-*-linux-*)	targ_emul=elf64btsmip
++			targ_extra_emuls="elf32btsmipn32 elf32ltsmipn32 elf32btsmip elf32ltsmip elf64ltsmip"
+ 			targ_extra_libpath=$targ_extra_emuls ;;
+ mips*el-*-linux-*)	targ_emul=elf32ltsmip
+ 			targ_extra_emuls="elf32btsmip elf32ltsmipn32 elf64ltsmip elf32btsmipn32 elf64btsmip"
diff --git a/recipes-devtools/binutils/binutils/relocatable_sdk.patch b/recipes-devtools/binutils/binutils/relocatable_sdk.patch
new file mode 100644
index 0000000..7408c31
--- /dev/null
+++ b/recipes-devtools/binutils/binutils/relocatable_sdk.patch
@@ -0,0 +1,49 @@
+Upstream-Status: Inappropriate [SDK specific]
+
+This patch will modify the ELF linker scripts so that the crosssdk linker will
+generate binaries with a 4096 bytes PT_INTERP section. When the binaries will
+be relocated, at SDK install time, the interpreter path can be easily changed
+by the relocating script.
+
+Signed-off-by: Laurentiu Palcu <laurentiu.palcu@intel.com>
+
+Index: binutils_git/ld/genscripts.sh
+===================================================================
+--- binutils_git.orig/ld/genscripts.sh	2012-11-21 11:58:23.325441925 +0200
++++ binutils_git/ld/genscripts.sh	2012-11-21 12:03:42.106815400 +0200
+@@ -290,6 +290,7 @@
+ LD_FLAG=r
+ DATA_ALIGNMENT=${DATA_ALIGNMENT_r}
+ DEFAULT_DATA_ALIGNMENT="ALIGN(${SEGMENT_SIZE})"
++PARTIAL_LINKING=" "
+ ( echo "/* Script for ld -r: link without relocation */"
+   . ${CUSTOMIZER_SCRIPT}
+   . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+@@ -298,10 +299,12 @@
+ LD_FLAG=u
+ DATA_ALIGNMENT=${DATA_ALIGNMENT_u}
+ CONSTRUCTING=" "
++PARTIAL_LINKING=" "
+ ( echo "/* Script for ld -Ur: link w/out relocation, do create constructors */"
+   . ${CUSTOMIZER_SCRIPT}
+   . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+ ) | sed -e '/^ *$/d;s/[ 	]*$//' > ldscripts/${EMULATION_NAME}.xu
++unset PARTIAL_LINKING
+ 
+ LD_FLAG=
+ DATA_ALIGNMENT=${DATA_ALIGNMENT_}
+Index: binutils_git/ld/scripttempl/elf.sc
+===================================================================
+--- binutils_git.orig/ld/scripttempl/elf.sc	2012-11-21 12:02:26.800377384 +0200
++++ binutils_git/ld/scripttempl/elf.sc	2012-11-21 12:04:16.166109621 +0200
+@@ -124,8 +124,8 @@
+   DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);"
+   DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT-0}, .);"
+ fi
+-if test -z "${INITIAL_READONLY_SECTIONS}${CREATE_SHLIB}"; then
+-  INITIAL_READONLY_SECTIONS=".interp       ${RELOCATING-0} : { *(.interp) }"
++if test -z "${INITIAL_READONLY_SECTIONS}${CREATE_SHLIB}${PARTIAL_LINKING}"; then
++  INITIAL_READONLY_SECTIONS=".interp       ${RELOCATING-0} : { *(.interp); . = 0x1000; }"
+ fi
+ if test -z "$PLT"; then
+   IPLT=".iplt         ${RELOCATING-0} : { *(.iplt) }"
diff --git a/recipes-devtools/binutils/binutils_2.25.bb b/recipes-devtools/binutils/binutils_2.25.bb
new file mode 100644
index 0000000..160451c
--- /dev/null
+++ b/recipes-devtools/binutils/binutils_2.25.bb
@@ -0,0 +1,45 @@
+require binutils.inc
+require binutils-${PV}.inc
+
+DEPENDS += "flex bison zlib"
+
+EXTRA_OECONF += "--with-sysroot=/ \
+                --enable-install-libbfd \
+                --enable-install-libiberty \
+                --enable-shared \
+                "
+
+EXTRA_OECONF_class-native = "--enable-targets=all \
+                             --enable-64-bit-bfd \
+                             --enable-install-libiberty \
+                             --enable-install-libbfd"
+
+do_install_class-native () {
+	autotools_do_install
+
+	# Install the libiberty header
+	install -d ${D}${includedir}
+	install -m 644 ${S}/include/ansidecl.h ${D}${includedir}
+	install -m 644 ${S}/include/libiberty.h ${D}${includedir}
+        
+	# We only want libiberty, libbfd and libopcodes
+	rm -rf ${D}${bindir}
+        rm -f ${D}/${bindir}/embedspu || :
+	rm -rf ${D}${prefix}/${TARGET_SYS}
+	rm -rf ${D}${prefix}/lib/ldscripts
+	rm -rf ${D}${prefix}/share/info
+	rm -rf ${D}${prefix}/share/locale
+	rm -rf ${D}${prefix}/share/man
+	rmdir ${D}${prefix}/share || :
+	rmdir ${D}/${libdir}/gcc-lib || :
+	rmdir ${D}/${libdir}64/gcc-lib || :
+	rmdir ${D}/${libdir} || :
+	rmdir ${D}/${libdir}64 || :
+}
+
+do_install_append () {
+        # we dont really care about embedspu for ppc so remove it
+        rm -f ${D}/${bindir}/*embedspu || :
+}
+
+BBCLASSEXTEND = "native"
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 11/18] gcc : add 4.9 version
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (14 preceding siblings ...)
  2017-12-28 10:05 ` [PATCH 10/18] binutils: add 2.25 version Chunrong Guo
@ 2017-12-28 10:05 ` Chunrong Guo
  2017-12-28 10:05 ` [PATCH 09/18] glibc : add 2.20 version Chunrong Guo
  2018-01-04 14:33 ` [PATCH 01/18] e500v2.inc: add recipe Bob Cochran
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:05 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

*ppc machine only  support gcc 4.9 version

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 recipes-devtools/gcc/gcc-4.9.inc                   |  129 +
 .../0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch     |   42 +
 .../gcc/gcc-4.9/0001.gcc.e6500-FSF-49x.patch       | 2613 +++++++++++
 .../gcc/gcc-4.9/0002-uclibc-conf.patch             |   53 +
 .../gcc/gcc-4.9/0002.gcc.builtin_isel-49x.patch    | 1112 +++++
 .../0003-gcc-uclibc-locale-ctype_touplow_t.patch   |   87 +
 .../gcc/gcc-4.9/0003.gcc.widen_types-49x.patch     | 1531 +++++++
 .../gcc/gcc-4.9/0004-uclibc-locale.patch           | 2862 +++++++++++++
 .../gcc/gcc-4.9/0004.gcc.extelim-v4-49x.patch      | 4526 ++++++++++++++++++++
 .../gcc/gcc-4.9/0005-uclibc-locale-no__x.patch     |  257 ++
 .../0005.gcc.extelim_vrp_kugan-v1-49x.patch        |  709 +++
 .../gcc/gcc-4.9/0006-uclibc-locale-wchar_fix.patch |   68 +
 .../gcc-4.9/0006.gcc.opt-array-offset-49x.patch    |  366 ++
 .../gcc/gcc-4.9/0007-uclibc-locale-update.patch    |  542 +++
 .../gcc/gcc-4.9/0007.gcc.aeabi-49x.patch           |  440 ++
 .../gcc/gcc-4.9/0008-missing-execinfo_h.patch      |   28 +
 .../gcc-4.9/0008.gcc.fix_regalloc_for_482.patch    |   23 +
 .../gcc/gcc-4.9/0009-c99-snprintf.patch            |   28 +
 .../gcc/gcc-4.9/0009.gcc.rm_slow_tests-47.patch    |   67 +
 .../gcc/gcc-4.9/0010-c99-complex-ugly-hack.patch   |   29 +
 .../gcc/gcc-4.9/0010.gcc.fix_mingw32.patch         |   12 +
 .../gcc/gcc-4.9/0011-index_macro.patch             |   44 +
 .../gcc-4.9/0011.gcc.no_power_builtins-48.patch    |   24 +
 .../gcc/gcc-4.9/0012.gcc.ld_unaligned-460.patch    |   32 +
 .../gcc/gcc-4.9/0013-libstdc-namespace.patch       |   54 +
 .../gcc-4.9/0013.gcc.local_unaligned_altivec.patch |   32 +
 recipes-devtools/gcc/gcc-4.9/0014-sh-pr24836.patch |   45 +
 .../gcc/gcc-4.9/0014.gcc.soft_float-470.patch      |   16 +
 ...GET_ENDIAN_OPTION-for-determining-MULTILI.patch |   47 +
 .../gcc/gcc-4.9/0015.gcc.case_values-48.patch      |   43 +
 .../0016-gcc-poison-system-directories.patch       |  190 +
 .../0016.gcc.fix_pr63854_pass_manager.patch        |   22 +
 .../gcc/gcc-4.9/0017-gcc-poison-dir-extend.patch   |   39 +
 .../gcc/gcc-4.9/0017.gcc.builtin_isel_doc.patch    |  109 +
 .../0018-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch |   73 +
 .../gcc/gcc-4.9/0018.gcc.experimental_move.patch   |   32 +
 .../gcc/gcc-4.9/0019-64-bit-multilib-hack.patch    |   82 +
 .../gcc/gcc-4.9/0019.gcc.e5500_mfocr.patch         |  181 +
 .../gcc/gcc-4.9/0020-optional-libstdc.patch        |   98 +
 .../0020.gcc.load_on_store_bypass-48x.patch        |  137 +
 ...0021-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch |   59 +
 .../gcc/gcc-4.9/0021.gcc.fix_constvector.patch     |   43 +
 .../gcc/gcc-4.9/0022-COLLECT_GCC_OPTIONS.patch     |   38 +
 .../gcc-4.9/0022.gcc.fix_pr63908_unwind_info.patch |  170 +
 ...efaults.h-in-B-instead-of-S-and-t-oe-in-B.patch |   96 +
 .../gcc-4.9/0023.gcc.fix_pr60158_fixup_table.patch |  121 +
 .../gcc/gcc-4.9/0024-PR-target-32219.patch         |   62 +
 ...0024.gcc.have-pre-modify-disp-support-49x.patch | 1078 +++++
 .../gcc-4.9/0025-fortran-cross-compile-hack.patch  |   46 +
 ...gcc.fix_ENGR00298583_dwarf-vector-reg_49x.patch |  113 +
 .../gcc/gcc-4.9/0026-libgcc-sjlj-check.patch       |   74 +
 ...26.gcc.fix_MTWX51605-memset-array-init_48.patch |  129 +
 .../gcc/gcc-4.9/0027-cpp-honor-sysroot.patch       |   54 +
 ...027.gcc.fix_altivec_constant_alignment-v2.patch |   33 +
 .../gcc-4.9/0028-MIPS64-Default-to-N64-ABI.patch   |   31 +
 .../gcc-4.9/0028.gcc.fix_altivec_reload_gs8.patch  |   29 +
 ...C_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch |  228 +
 .../gcc-4.9/0029.gcc.fix_postfix_gimplifier.patch  |   92 +
 ...0030-gcc-Fix-argument-list-too-long-error.patch |   40 +
 .../gcc-4.9/0030.gcc.fix_adjust_address_cost.patch |  346 ++
 .../gcc/gcc-4.9/0031-Disable-sdt.patch             |  113 +
 .../0031.gcc.fix_adjust_sched_loopinv_cost.patch   |  154 +
 recipes-devtools/gcc/gcc-4.9/0032-libtool.patch    |   42 +
 .../0032.gcc.fix_e5500_mulli_pipeline.patch        |   36 +
 ...4-pass-fix-v4bx-to-linker-to-support-EABI.patch |   40 +
 .../0033.gcc.fix_e500mc_addi_pipeline.patch        |   44 +
 ...tilib-config-files-from-B-instead-of-usin.patch |  102 +
 .../0034.gcc.fix_ENGR00292364_debug_frame.patch    |   63 +
 .../gcc-4.9/0035.gcc.fix_ENGR00215936_49x.patch    |  159 +
 .../0036.gcc.enable_soft_multilib-49x.patch        |   23 +
 .../gcc/gcc-4.9/0037.gcc.fix_49x-doc.patch         |   30 +
 .../gcc-4.9/0038.gcc.fix_emulation_spec_48.patch   |   56 +
 .../gcc/gcc-4.9/0039.gcc.create_maeabi.patch       |  746 ++++
 .../gcc/gcc-4.9/0040-fix-g++-sysroot.patch         |   40 +
 .../gcc/gcc-4.9/0040.gcc.rm_e500v2_loops_48.patch  |  795 ++++
 .../gcc/gcc-4.9/0041-libtool-avoid-libdir.patch    |   19 +
 .../0041.gcc.fix_e5500-e6500-aeabi-multi-lib.patch |   46 +
 .../gcc/gcc-4.9/0042.gcc.fix_ivopts.patch          |  157 +
 recipes-devtools/gcc/gcc-4.9/0043-cpp.patch        |   40 +
 .../gcc-4.9/0043.gcc.sysroot_spec_only_linux.patch |   30 +
 recipes-devtools/gcc/gcc-4.9/0044-gengtypes.patch  |   97 +
 .../gcc/gcc-4.9/0046-libatomic-deptracking.patch   |   41 +
 recipes-devtools/gcc/gcc-4.9/0047-repomembug.patch |   53 +
 ...AltiVec-generation-on-powepc-linux-target.patch |   42 +
 ...Use-dbx_reg_number-for-spanning-registers.patch |   80 +
 recipes-devtools/gcc/gcc-4.9/0051-eabispe.patch    |   23 +
 ...hook-to-override-DWARF2-frame-register-si.patch |  138 +
 ...fault-from-calling-free-on-non-malloc-d-a.patch |   66 +
 ...Makefile.in-fix-parallel-building-failure.patch |   61 +
 .../gcc-4.9/0055-dwarf-reg-processing-helper.patch |  148 +
 .../0056-define-default-cfa-register-mapping.patch |   75 +
 .../gcc/gcc-4.9/0057-aarch64-config.patch          |   32 +
 .../gcc/gcc-4.9/0058-gcc-r212171.patch             |  113 +
 .../0059-gcc-PR-rtl-optimization-63348.patch       |   59 +
 ...e500-double-in-SPE_SIMD_REGNO_P-registers.patch |   55 +
 .../gcc/gcc-4.9/0061-target-gcc-includedir.patch   |   81 +
 ...IBS_DIR-replacement-instead-of-hardcoding.patch |   24 +
 .../gcc/gcc-4.9/0063-nativesdk-gcc-support.patch   |  198 +
 .../0064-handle-target-sysroot-multilib.patch      |   88 +
 ...-gcc-483-universal-initializer-no-warning.patch |  107 +
 .../qoriq-ppc/0019-64-bit-multilib-hack.patch      |   65 +
 ...AltiVec-generation-on-powepc-linux-target.patch |   43 +
 .../qoriq-ppc/0066-cxxflags-for-build.patch        |  126 +
 recipes-devtools/gcc/gcc-configure-common.inc      |  129 +
 recipes-devtools/gcc/gcc-cross-canadian.inc        |  177 +
 recipes-devtools/gcc/gcc-cross-canadian_4.9.bb     |    5 +
 .../gcc/gcc-cross-canadian_4.9.bbappend            |   11 +
 recipes-devtools/gcc/gcc-cross-initial.inc         |   89 +
 recipes-devtools/gcc/gcc-cross-initial_4.9.bb      |    2 +
 .../gcc/gcc-cross-initial_4.9.bbappend             |    1 +
 recipes-devtools/gcc/gcc-cross.inc                 |  216 +
 recipes-devtools/gcc/gcc-cross_4.9.bb              |    3 +
 recipes-devtools/gcc/gcc-cross_4.9.bbappend        |    5 +
 recipes-devtools/gcc/gcc-crosssdk-initial.inc      |   10 +
 recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bb   |    3 +
 .../gcc/gcc-crosssdk-initial_4.9.bbappend          |    1 +
 recipes-devtools/gcc/gcc-crosssdk.inc              |   12 +
 recipes-devtools/gcc/gcc-crosssdk_4.9.bb           |    2 +
 recipes-devtools/gcc/gcc-crosssdk_4.9.bbappend     |    1 +
 recipes-devtools/gcc/gcc-fsl.inc                   |   70 +
 recipes-devtools/gcc/gcc-multilib-config.inc       |  228 +
 recipes-devtools/gcc/gcc-runtime_4.9.bb            |    3 +
 recipes-devtools/gcc/gcc-runtime_4.9.bbappend      |    1 +
 recipes-devtools/gcc/gcc-sanitizers.inc            |  119 +
 recipes-devtools/gcc/gcc-sanitizers_4.9.bb         |    2 +
 recipes-devtools/gcc/gcc-sanitizers_4.9.bbappend   |    1 +
 recipes-devtools/gcc/gcc-shared-source.inc         |   11 +
 recipes-devtools/gcc/gcc-source.inc                |   36 +
 recipes-devtools/gcc/gcc-source_4.9.bb             |    4 +
 recipes-devtools/gcc/gcc-source_4.9.bbappend       |    1 +
 recipes-devtools/gcc/gcc-target.inc                |  214 +
 recipes-devtools/gcc/gcc_4.9.bb                    |   13 +
 recipes-devtools/gcc/gcc_4.9.bbappend              |    1 +
 recipes-devtools/gcc/libgcc-common.inc             |  144 +
 recipes-devtools/gcc/libgcc-initial_4.9.bb         |    2 +
 recipes-devtools/gcc/libgcc-initial_4.9.bbappend   |    1 +
 recipes-devtools/gcc/libgcc_4.9.bb                 |    2 +
 recipes-devtools/gcc/libgcc_4.9.bbappend           |    1 +
 recipes-devtools/gcc/libgfortran.inc               |   74 +
 recipes-devtools/gcc/libgfortran_4.9.bb            |    3 +
 recipes-devtools/gcc/libgfortran_4.9.bbappend      |    1 +
 141 files changed, 25855 insertions(+)
 create mode 100644 recipes-devtools/gcc/gcc-4.9.inc
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0001.gcc.e6500-FSF-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0002-uclibc-conf.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0002.gcc.builtin_isel-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0003-gcc-uclibc-locale-ctype_touplow_t.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0003.gcc.widen_types-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0004-uclibc-locale.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0004.gcc.extelim-v4-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0005-uclibc-locale-no__x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0005.gcc.extelim_vrp_kugan-v1-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0006-uclibc-locale-wchar_fix.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0006.gcc.opt-array-offset-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0007-uclibc-locale-update.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0007.gcc.aeabi-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0008-missing-execinfo_h.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0008.gcc.fix_regalloc_for_482.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0009-c99-snprintf.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0009.gcc.rm_slow_tests-47.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0010-c99-complex-ugly-hack.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0010.gcc.fix_mingw32.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0011-index_macro.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0011.gcc.no_power_builtins-48.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0012.gcc.ld_unaligned-460.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0013-libstdc-namespace.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0013.gcc.local_unaligned_altivec.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0014-sh-pr24836.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0014.gcc.soft_float-470.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0015-arm-Use-TARGET_ENDIAN_OPTION-for-determining-MULTILI.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0015.gcc.case_values-48.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0016-gcc-poison-system-directories.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0016.gcc.fix_pr63854_pass_manager.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0017-gcc-poison-dir-extend.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0017.gcc.builtin_isel_doc.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0018-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0018.gcc.experimental_move.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0019-64-bit-multilib-hack.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0019.gcc.e5500_mfocr.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0020-optional-libstdc.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0020.gcc.load_on_store_bypass-48x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0021-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0021.gcc.fix_constvector.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0022-COLLECT_GCC_OPTIONS.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0022.gcc.fix_pr63908_unwind_info.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0023-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0023.gcc.fix_pr60158_fixup_table.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0024-PR-target-32219.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0024.gcc.have-pre-modify-disp-support-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0025-fortran-cross-compile-hack.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0025.gcc.fix_ENGR00298583_dwarf-vector-reg_49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0026-libgcc-sjlj-check.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0026.gcc.fix_MTWX51605-memset-array-init_48.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0027-cpp-honor-sysroot.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0027.gcc.fix_altivec_constant_alignment-v2.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0028-MIPS64-Default-to-N64-ABI.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0028.gcc.fix_altivec_reload_gs8.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0029-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0029.gcc.fix_postfix_gimplifier.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0030-gcc-Fix-argument-list-too-long-error.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0030.gcc.fix_adjust_address_cost.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0031-Disable-sdt.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0031.gcc.fix_adjust_sched_loopinv_cost.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0032-libtool.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0032.gcc.fix_e5500_mulli_pipeline.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0033-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0033.gcc.fix_e500mc_addi_pipeline.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0034-Use-the-multilib-config-files-from-B-instead-of-usin.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0034.gcc.fix_ENGR00292364_debug_frame.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0035.gcc.fix_ENGR00215936_49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0036.gcc.enable_soft_multilib-49x.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0037.gcc.fix_49x-doc.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0038.gcc.fix_emulation_spec_48.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0039.gcc.create_maeabi.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0040-fix-g++-sysroot.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0040.gcc.rm_e500v2_loops_48.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0041-libtool-avoid-libdir.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0041.gcc.fix_e5500-e6500-aeabi-multi-lib.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0042.gcc.fix_ivopts.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0043-cpp.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0043.gcc.sysroot_spec_only_linux.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0044-gengtypes.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0046-libatomic-deptracking.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0047-repomembug.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0050-Revert-Use-dbx_reg_number-for-spanning-registers.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0051-eabispe.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0052-Add-target-hook-to-override-DWARF2-frame-register-si.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0053-gcc-fix-segfault-from-calling-free-on-non-malloc-d-a.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0054-gcc-Makefile.in-fix-parallel-building-failure.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0055-dwarf-reg-processing-helper.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0056-define-default-cfa-register-mapping.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0057-aarch64-config.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0058-gcc-r212171.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0059-gcc-PR-rtl-optimization-63348.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0060-Only-allow-e500-double-in-SPE_SIMD_REGNO_P-registers.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0061-target-gcc-includedir.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0062-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0063-nativesdk-gcc-support.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0064-handle-target-sysroot-multilib.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/0065-gcc-483-universal-initializer-no-warning.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0019-64-bit-multilib-hack.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch
 create mode 100644 recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0066-cxxflags-for-build.patch
 create mode 100644 recipes-devtools/gcc/gcc-configure-common.inc
 create mode 100644 recipes-devtools/gcc/gcc-cross-canadian.inc
 create mode 100644 recipes-devtools/gcc/gcc-cross-canadian_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-cross-canadian_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-cross-initial.inc
 create mode 100644 recipes-devtools/gcc/gcc-cross-initial_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-cross-initial_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-cross.inc
 create mode 100644 recipes-devtools/gcc/gcc-cross_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-cross_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-crosssdk-initial.inc
 create mode 100644 recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-crosssdk.inc
 create mode 100644 recipes-devtools/gcc/gcc-crosssdk_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-crosssdk_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-fsl.inc
 create mode 100644 recipes-devtools/gcc/gcc-multilib-config.inc
 create mode 100644 recipes-devtools/gcc/gcc-runtime_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-runtime_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-sanitizers.inc
 create mode 100644 recipes-devtools/gcc/gcc-sanitizers_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-sanitizers_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-shared-source.inc
 create mode 100644 recipes-devtools/gcc/gcc-source.inc
 create mode 100644 recipes-devtools/gcc/gcc-source_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc-source_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/gcc-target.inc
 create mode 100644 recipes-devtools/gcc/gcc_4.9.bb
 create mode 100644 recipes-devtools/gcc/gcc_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/libgcc-common.inc
 create mode 100644 recipes-devtools/gcc/libgcc-initial_4.9.bb
 create mode 100644 recipes-devtools/gcc/libgcc-initial_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/libgcc_4.9.bb
 create mode 100644 recipes-devtools/gcc/libgcc_4.9.bbappend
 create mode 100644 recipes-devtools/gcc/libgfortran.inc
 create mode 100644 recipes-devtools/gcc/libgfortran_4.9.bb
 create mode 100644 recipes-devtools/gcc/libgfortran_4.9.bbappend

diff --git a/recipes-devtools/gcc/gcc-4.9.inc b/recipes-devtools/gcc/gcc-4.9.inc
new file mode 100644
index 0000000..5dba399
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9.inc
@@ -0,0 +1,129 @@
+require recipes-devtools/gcc/gcc-common.inc
+
+# Third digit in PV should be incremented after a minor release
+
+PV = "4.9.3"
+
+# BINV should be incremented to a revision after a minor gcc release
+
+BINV = "4.9.3"
+
+FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc-4.9:"
+
+DEPENDS =+ "mpfr gmp libmpc zlib"
+NATIVEDEPS = "mpfr-native gmp-native libmpc-native zlib-native"
+
+LICENSE = "GPL-3.0-with-GCC-exception & GPLv3"
+
+LIC_FILES_CHKSUM = "\
+    file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
+    file://COPYING3;md5=d32239bcb673463ab874e80d47fae504 \
+    file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6 \
+    file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1 \
+    file://COPYING.RUNTIME;md5=fe60d87048567d4fe8c8a0ed2448bcc8 \
+"
+
+SRC_URI = "\
+    ${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.bz2 \
+    file://0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch \
+    file://0002-uclibc-conf.patch \
+    file://0003-gcc-uclibc-locale-ctype_touplow_t.patch \
+    file://0004-uclibc-locale.patch \
+    file://0005-uclibc-locale-no__x.patch \
+    file://0006-uclibc-locale-wchar_fix.patch \
+    file://0007-uclibc-locale-update.patch \
+    file://0008-missing-execinfo_h.patch \
+    file://0009-c99-snprintf.patch \
+    file://0010-c99-complex-ugly-hack.patch \
+    file://0011-index_macro.patch \
+    file://0013-libstdc-namespace.patch \
+    file://0014-sh-pr24836.patch \
+    file://0015-arm-Use-TARGET_ENDIAN_OPTION-for-determining-MULTILI.patch \
+    file://0016-gcc-poison-system-directories.patch \
+    file://0017-gcc-poison-dir-extend.patch \
+    file://0018-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch \
+    file://0019-64-bit-multilib-hack.patch \
+    file://0020-optional-libstdc.patch \
+    file://0021-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch \
+    file://0022-COLLECT_GCC_OPTIONS.patch \
+    file://0023-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch \
+    file://0024-PR-target-32219.patch \
+    file://0025-fortran-cross-compile-hack.patch \
+    file://0026-libgcc-sjlj-check.patch \
+    file://0027-cpp-honor-sysroot.patch \
+    file://0028-MIPS64-Default-to-N64-ABI.patch \
+    file://0029-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch \
+    file://0030-gcc-Fix-argument-list-too-long-error.patch \
+    file://0031-Disable-sdt.patch \
+    file://0032-libtool.patch \
+    file://0033-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch \
+    file://0034-Use-the-multilib-config-files-from-B-instead-of-usin.patch \
+    file://0040-fix-g++-sysroot.patch \
+    file://0041-libtool-avoid-libdir.patch \
+    file://0043-cpp.patch \
+    file://0044-gengtypes.patch \
+    file://0046-libatomic-deptracking.patch \
+    file://0047-repomembug.patch \
+    file://0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch \
+    file://0050-Revert-Use-dbx_reg_number-for-spanning-registers.patch \
+    file://0051-eabispe.patch \
+    file://0052-Add-target-hook-to-override-DWARF2-frame-register-si.patch \
+    file://0053-gcc-fix-segfault-from-calling-free-on-non-malloc-d-a.patch \
+    file://0054-gcc-Makefile.in-fix-parallel-building-failure.patch \
+    file://0055-dwarf-reg-processing-helper.patch \
+    file://0056-define-default-cfa-register-mapping.patch \
+    file://0057-aarch64-config.patch \
+    file://0058-gcc-r212171.patch \
+    file://0059-gcc-PR-rtl-optimization-63348.patch \
+    file://0060-Only-allow-e500-double-in-SPE_SIMD_REGNO_P-registers.patch \
+    file://0061-target-gcc-includedir.patch \
+    file://0062-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch \
+    file://0063-nativesdk-gcc-support.patch \
+    file://0064-handle-target-sysroot-multilib.patch \
+    file://0065-gcc-483-universal-initializer-no-warning.patch \
+"
+SRC_URI[md5sum] = "6f831b4d251872736e8e9cc09746f327"
+SRC_URI[sha256sum] = "2332b2a5a321b57508b9031354a8503af6fdfb868b8c1748d33028d100a8b67e"
+
+S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}"
+B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}"
+
+# Language Overrides
+FORTRAN = ""
+JAVA = ""
+
+LTO = "--enable-lto"
+
+EXTRA_OECONF_BASE = "\
+    ${LTO} \
+    --enable-libssp \
+    --disable-bootstrap \
+    --disable-libmudflap \
+    --with-system-zlib \
+    --with-linker-hash-style=${LINKER_HASH_STYLE} \
+    --enable-linker-build-id \
+    --with-ppl=no \
+    --with-cloog=no \
+    --enable-checking=release \
+    --enable-cheaders=c_global \
+"
+
+EXTRA_OECONF_INITIAL = "\
+    --disable-libmudflap \
+    --disable-libgomp \
+    --disable-libssp \
+    --disable-libquadmath \
+    --with-system-zlib \
+    --disable-lto \
+    --disable-plugin \
+    --enable-decimal-float=no \
+"
+
+EXTRA_OECONF_append_libc-uclibc = " --disable-decimal-float "
+
+EXTRA_OECONF_PATHS = "\
+    --with-gxx-include-dir=/not/exist{target_includedir}/c++/${BINV} \
+    --with-sysroot=/not/exist \
+    --with-build-sysroot=${STAGING_DIR_TARGET} \
+"
+INSANE_SKIP_${PN} += "ldflags"
diff --git a/recipes-devtools/gcc/gcc-4.9/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch b/recipes-devtools/gcc/gcc-4.9/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch
new file mode 100644
index 0000000..e588011
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch
@@ -0,0 +1,42 @@
+From bf3d96ae58fa180b8b468d25dc2e0209daca2751 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:37:11 +0400
+Subject: [PATCH 01/35] gcc-4.3.1: ARCH_FLAGS_FOR_TARGET
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [embedded specific]
+---
+ configure    |    2 +-
+ configure.ac |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure b/configure
+index d809535..1b76c90 100755
+--- a/configure
++++ b/configure
+@@ -7439,7 +7439,7 @@ fi
+ # for target_alias and gcc doesn't manage it consistently.
+ target_configargs="--cache-file=./config.cache ${target_configargs}"
+ 
+-FLAGS_FOR_TARGET=
++FLAGS_FOR_TARGET="$ARCH_FLAGS_FOR_TARGET"
+ case " $target_configdirs " in
+  *" newlib "*)
+   case " $target_configargs " in
+diff --git a/configure.ac b/configure.ac
+index 48ec1aa..89d1d3f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -2873,7 +2873,7 @@ fi
+ # for target_alias and gcc doesn't manage it consistently.
+ target_configargs="--cache-file=./config.cache ${target_configargs}"
+ 
+-FLAGS_FOR_TARGET=
++FLAGS_FOR_TARGET="$ARCH_FLAGS_FOR_TARGET"
+ case " $target_configdirs " in
+  *" newlib "*)
+   case " $target_configargs " in
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0001.gcc.e6500-FSF-49x.patch b/recipes-devtools/gcc/gcc-4.9/0001.gcc.e6500-FSF-49x.patch
new file mode 100644
index 0000000..4d6077b
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0001.gcc.e6500-FSF-49x.patch
@@ -0,0 +1,2613 @@
+diff -Naur gcc-4.9.1/gcc/config/rs6000/altivec.h gcc-4.9.1-e6500-FSF/gcc/config/rs6000/altivec.h
+--- gcc-4.9.1/gcc/config/rs6000/altivec.h	2014-03-27 15:07:16.000000000 -0500
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/altivec.h	2014-07-17 02:38:35.039383000 -0500
+@@ -371,6 +371,30 @@
+ #define vec_vupklsw __builtin_vec_vupklsw
+ #endif
+ 
++#ifdef __ALTIVEC2__
++/* New Altivec instructions */
++#define vec_absd __builtin_vec_absd
++#define vec_lvexbx __builtin_vec_lvexbx
++#define vec_lvexhx __builtin_vec_lvexhx
++#define vec_lvexwx __builtin_vec_lvexwx
++#define vec_stvexbx __builtin_vec_stvexbx
++#define vec_stvexhx __builtin_vec_stvexhx
++#define vec_stvexwx __builtin_vec_stvexwx
++#define vec_lvswx __builtin_vec_lvswx
++#define vec_lvswxl __builtin_vec_lvswxl
++#define vec_stvswx __builtin_vec_stvswx
++#define vec_stvswxl __builtin_vec_stvswxl
++#define vec_lvsm __builtin_vec_lvsm
++#define vec_lvtlx __builtin_vec_lvtlx
++#define vec_lvtlxl __builtin_vec_lvtlxl
++#define vec_lvtrx __builtin_vec_lvtrx
++#define vec_lvtrxl __builtin_vec_lvtrxl
++#define vec_stvflx __builtin_vec_stvflx
++#define vec_stvflxl __builtin_vec_stvflxl
++#define vec_stvfrx __builtin_vec_stvfrx
++#define vec_stvfrxl __builtin_vec_stvfrxl
++#endif
++
+ /* Predicates.
+    For C++, we use templates in order to allow non-parenthesized arguments.
+    For C, instead, we use macros since non-parenthesized arguments were
+diff -Naur gcc-4.9.1/gcc/config/rs6000/altivec.md gcc-4.9.1-e6500-FSF/gcc/config/rs6000/altivec.md
+--- gcc-4.9.1/gcc/config/rs6000/altivec.md	2014-04-30 14:30:47.000000000 -0500
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/altivec.md	2014-07-17 02:38:35.041383001 -0500
+@@ -81,9 +81,11 @@
+    UNSPEC_LVSL
+    UNSPEC_LVSR
+    UNSPEC_LVE
++   UNSPEC_LVEX
+    UNSPEC_STVX
+    UNSPEC_STVXL
+    UNSPEC_STVE
++   UNSPEC_STVEX
+    UNSPEC_SET_VSCR
+    UNSPEC_GET_VRSAVE
+    UNSPEC_LVX
+@@ -111,6 +113,19 @@
+    UNSPEC_STVLXL
+    UNSPEC_STVRX
+    UNSPEC_STVRXL
++   UNSPEC_LVTLX
++   UNSPEC_LVTLXL
++   UNSPEC_LVTRX
++   UNSPEC_LVTRXL
++   UNSPEC_STVFLX
++   UNSPEC_STVFLXL
++   UNSPEC_STVFRX
++   UNSPEC_STVFRXL
++   UNSPEC_LVSWX
++   UNSPEC_LVSWXL
++   UNSPEC_STVSWX
++   UNSPEC_STVSWXL
++   UNSPEC_LVSM
+    UNSPEC_VMULWHUB
+    UNSPEC_VMULWLUB
+    UNSPEC_VMULWHSB
+@@ -131,6 +146,9 @@
+    UNSPEC_VUPKLS_V4SF
+    UNSPEC_VUPKHU_V4SF
+    UNSPEC_VUPKLU_V4SF
++   UNSPEC_VABSDUB
++   UNSPEC_VABSDUH
++   UNSPEC_VABSDUW
+    UNSPEC_VGBBD
+    UNSPEC_VMRGH_DIRECT
+    UNSPEC_VMRGL_DIRECT
+@@ -401,6 +419,34 @@
+ 
+ ;; Simple binary operations.
+ 
++;; absd
++(define_insn "altivec_vabsduw"
++  [(set (match_operand:V4SI 0 "register_operand" "=v")
++        (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
++                      (match_operand:V4SI 2 "register_operand" "v")]
++		     UNSPEC_VABSDUW))]
++  "TARGET_ALTIVEC2"
++  "vabsduw %0,%1,%2"
++  [(set_attr "type" "vecsimple")])
++
++(define_insn "altivec_vabsduh"
++  [(set (match_operand:V8HI 0 "register_operand" "=v")
++        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
++                      (match_operand:V8HI 2 "register_operand" "v")]
++		     UNSPEC_VABSDUH))]
++  "TARGET_ALTIVEC2"
++  "vabsduh %0,%1,%2"
++  [(set_attr "type" "vecsimple")])
++
++(define_insn "altivec_vabsdub"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
++                       (match_operand:V16QI 2 "register_operand" "v")]
++		      UNSPEC_VABSDUB))]
++  "TARGET_ALTIVEC2"
++  "vabsdub %0,%1,%2"
++  [(set_attr "type" "vecsimple")])
++
+ ;; add
+ (define_insn "add<mode>3"
+   [(set (match_operand:VI2 0 "register_operand" "=v")
+@@ -2368,6 +2414,15 @@
+   "lvewx %0,%y1"
+   [(set_attr "type" "vecload")])
+ 
++(define_insn "altivec_lvex<VI_char>x"
++  [(parallel
++    [(set (match_operand:VI 0 "register_operand" "=v")
++         (match_operand:VI 1 "memory_operand" "Z"))
++     (unspec [(const_int 0)] UNSPEC_LVEX)])]
++  "TARGET_ALTIVEC2"
++  "lvex<VI_char>x %0,%y1"
++  [(set_attr "type" "vecload")])
++
+ (define_expand "altivec_lvxl_<mode>"
+   [(parallel
+     [(set (match_operand:VM2 0 "register_operand" "=v")
+@@ -2486,6 +2541,13 @@
+   "stvewx %1,%y0"
+   [(set_attr "type" "vecstore")])
+ 
++(define_insn "altivec_stvex<VI_char>x"
++  [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
++	(unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVEX))]
++  "TARGET_ALTIVEC2"
++  "stvex<VI_char>x %1,%y0"
++  [(set_attr "type" "vecstore")])
++
+ ;; Generate
+ ;;    xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0
+ ;;    vsubu?m SCRATCH2,SCRATCH1,%1
+@@ -3151,6 +3213,116 @@
+   "stvrxl %1,%y0"
+   [(set_attr "type" "vecstore")])
+ 
++(define_insn "altivec_lvtlx"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++		      UNSPEC_LVTLX))]
++  "TARGET_ALTIVEC2"
++  "lvtlx %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvtlxl"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++		      UNSPEC_LVTLXL))]
++  "TARGET_ALTIVEC2"
++  "lvtlxl %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvtrx"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++		      UNSPEC_LVTRX))]
++  "TARGET_ALTIVEC2"
++  "lvtrx %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvtrxl"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++		      UNSPEC_LVTRXL))]
++  "TARGET_ALTIVEC2"
++  "lvtrxl %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_stvflx"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++	  (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFLX)])]
++  "TARGET_ALTIVEC2"
++  "stvflx %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvflxl"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++	  (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFLXL)])]
++  "TARGET_ALTIVEC2"
++  "stvflxl %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvfrx"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++	  (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFRX)])]
++  "TARGET_ALTIVEC2"
++  "stvfrx %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvfrxl"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++	  (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFRXL)])]
++  "TARGET_ALTIVEC2"
++  "stvfrxl %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_lvswx"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++		      UNSPEC_LVSWX))]
++  "TARGET_ALTIVEC2"
++  "lvswx %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvswxl"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++		      UNSPEC_LVSWXL))]
++  "TARGET_ALTIVEC2"
++  "lvswxl %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvsm"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++		      UNSPEC_LVSM))]
++  "TARGET_ALTIVEC2"
++  "lvsm %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_stvswx"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++	  (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVSWX)])]
++  "TARGET_ALTIVEC2"
++  "stvswx %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvswxl"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++	  (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVSWXL)])]
++  "TARGET_ALTIVEC2"
++  "stvswxl %1,%y0"
++  [(set_attr "type" "vecstore")])
++
+ (define_expand "vec_unpacks_float_hi_v8hi"
+  [(set (match_operand:V4SF 0 "register_operand" "")
+         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000-builtin.def gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000-builtin.def
+--- gcc-4.9.1/gcc/config/rs6000/rs6000-builtin.def	2014-06-13 16:56:16.000000000 -0500
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000-builtin.def	2014-07-17 02:48:57.988383002 -0500
+@@ -632,6 +632,42 @@
+ 		     | RS6000_BTC_BINARY),				\
+ 		    CODE_FOR_ ## ICODE)			/* ICODE */
+ 
++/* Power ISA 2.07 altivec */
++#define BU_ALTIVC2_2(ENUM, NAME, ATTR, ICODE)                          \
++  RS6000_BUILTIN_2 (ALTIVEC_BUILTIN_ ## ENUM,          /* ENUM */      \
++                   "__builtin_altivec_" NAME,          /* NAME */      \
++                   (RS6000_BTM_ALTIVEC                 /* MASK */      \
++                    | RS6000_BTM_ALTIVEC2),                            \
++                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
++                    | RS6000_BTC_BINARY),                              \
++                   CODE_FOR_ ## ICODE)                 /* ICODE */
++
++#define BU_ALTIVC2_X(ENUM, NAME, ATTR)                                 \
++  RS6000_BUILTIN_X (ALTIVEC_BUILTIN_ ## ENUM,          /* ENUM */      \
++                   "__builtin_altivec_" NAME,          /* NAME */      \
++                   (RS6000_BTM_ALTIVEC                 /* MASK */      \
++                    | RS6000_BTM_ALTIVEC2),                            \
++                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
++                    | RS6000_BTC_SPECIAL),                             \
++                   CODE_FOR_nothing)                   /* ICODE */
++
++#define BU_ALTIVC2_OVERLOAD_2(ENUM, NAME)                              \
++  RS6000_BUILTIN_2 (ALTIVEC_BUILTIN_VEC_ ## ENUM,      /* ENUM */      \
++                   "__builtin_vec_" NAME,              /* NAME */      \
++                   (RS6000_BTM_ALTIVEC                 /* MASK */      \
++                    | RS6000_BTM_ALTIVEC2),                            \
++                   (RS6000_BTC_OVERLOADED              /* ATTR */      \
++                    | RS6000_BTC_BINARY),                              \
++                   CODE_FOR_nothing)                   /* ICODE */
++
++#define BU_ALTIVC2_OVERLOAD_X(ENUM, NAME)                              \
++  RS6000_BUILTIN_X (ALTIVEC_BUILTIN_VEC_ ## ENUM,      /* ENUM */      \
++                   "__builtin_vec_" NAME,              /* NAME */      \
++                   (RS6000_BTM_ALTIVEC                 /* MASK */      \
++                    | RS6000_BTM_ALTIVEC2),                            \
++                   (RS6000_BTC_OVERLOADED              /* ATTR */      \
++                    | RS6000_BTC_SPECIAL),                             \
++                   CODE_FOR_nothing)                   /* ICODE */
+ #endif
+ 
+ /* Insure 0 is not a legitimate index.  */
+@@ -685,6 +721,9 @@
+ BU_ALTIVEC_D (DSTSTT,	      "dststt",		MISC,  	altivec_dststt)
+ 
+ /* Altivec 2 argument builtin functions.  */
++BU_ALTIVC2_2 (VABSDUB,        "vabsdub",	CONST,	altivec_vabsdub)
++BU_ALTIVC2_2 (VABSDUH,        "vabsduh",	CONST,	altivec_vabsduh)
++BU_ALTIVC2_2 (VABSDUW,        "vabsduw",	CONST,	altivec_vabsduw)
+ BU_ALTIVEC_2 (VADDUBM,        "vaddubm",	CONST,	addv16qi3)
+ BU_ALTIVEC_2 (VADDUHM,	      "vadduhm",	CONST,	addv8hi3)
+ BU_ALTIVEC_2 (VADDUWM,	      "vadduwm",	CONST,	addv4si3)
+@@ -876,6 +915,9 @@
+ BU_ALTIVEC_X (LVEBX,		"lvebx",	    MEM)
+ BU_ALTIVEC_X (LVEHX,		"lvehx",	    MEM)
+ BU_ALTIVEC_X (LVEWX,		"lvewx",	    MEM)
++BU_ALTIVC2_X (LVEXBX,		"lvexbx",	    MEM)
++BU_ALTIVC2_X (LVEXHX,		"lvexhx",	    MEM)
++BU_ALTIVC2_X (LVEXWX,		"lvexwx",	    MEM)
+ BU_ALTIVEC_X (LVXL,		"lvxl",		    MEM)
+ BU_ALTIVEC_X (LVXL_V2DF,	"lvxl_v2df",	    MEM)
+ BU_ALTIVEC_X (LVXL_V2DI,	"lvxl_v2di",	    MEM)
+@@ -901,9 +943,19 @@
+ BU_ALTIVEC_C (LVLXL,		"lvlxl",	    MEM)
+ BU_ALTIVEC_C (LVRX,		"lvrx",		    MEM)
+ BU_ALTIVEC_C (LVRXL,		"lvrxl",	    MEM)
++BU_ALTIVC2_X (LVTLX,           "lvtlx",            MEM)
++BU_ALTIVC2_X (LVTLXL,          "lvtlxl",           MEM)
++BU_ALTIVC2_X (LVTRX,           "lvtrx",            MEM)
++BU_ALTIVC2_X (LVTRXL,          "lvtrxl",           MEM)
++BU_ALTIVC2_X (LVSWX,           "lvswx",            MEM)
++BU_ALTIVC2_X (LVSWXL,          "lvswxl",           MEM)
++BU_ALTIVC2_X (LVSM,            "lvsm",             MEM)
+ BU_ALTIVEC_X (STVEBX,		"stvebx",	    MEM)
+ BU_ALTIVEC_X (STVEHX,		"stvehx",	    MEM)
+ BU_ALTIVEC_X (STVEWX,		"stvewx",	    MEM)
++BU_ALTIVC2_X (STVEXBX,         "stvexbx",          MEM)
++BU_ALTIVC2_X (STVEXHX,         "stvexhx",          MEM)
++BU_ALTIVC2_X (STVEXWX,         "stvexwx",          MEM)
+ BU_ALTIVEC_X (STVXL,		"stvxl",	    MEM)
+ BU_ALTIVEC_X (STVXL_V2DF,	"stvxl_v2df",	    MEM)
+ BU_ALTIVEC_X (STVXL_V2DI,	"stvxl_v2di",	    MEM)
+@@ -915,6 +967,12 @@
+ BU_ALTIVEC_C (STVLXL,		"stvlxl",	    MEM)
+ BU_ALTIVEC_C (STVRX,		"stvrx",	    MEM)
+ BU_ALTIVEC_C (STVRXL,		"stvrxl",	    MEM)
++BU_ALTIVC2_X (STVFLX,          "stvflx",           MEM)
++BU_ALTIVC2_X (STVFLXL,         "stvflxl",          MEM)
++BU_ALTIVC2_X (STVFRX,          "stvfrx",           MEM)
++BU_ALTIVC2_X (STVFRXL,         "stvfrxl",          MEM)
++BU_ALTIVC2_X (STVSWX,          "stvswx",           MEM)
++BU_ALTIVC2_X (STVSWXL,         "stvswxl",          MEM)
+ BU_ALTIVEC_X (MASK_FOR_LOAD,	"mask_for_load",    MISC)
+ BU_ALTIVEC_X (MASK_FOR_STORE,	"mask_for_store",   MISC)
+ BU_ALTIVEC_X (VEC_INIT_V4SI,	"vec_init_v4si",    CONST)
+@@ -959,6 +1017,10 @@
+ BU_ALTIVEC_OVERLOAD_D (DSTSTT,	   "dststt")
+ 
+ /* 2 argument Altivec overloaded builtins.  */
++BU_ALTIVC2_OVERLOAD_2 (ABSD,	   "absd")
++BU_ALTIVC2_OVERLOAD_2 (ABSDUB,	   "absdub")
++BU_ALTIVC2_OVERLOAD_2 (ABSDUH,	   "absduh")
++BU_ALTIVC2_OVERLOAD_2 (ABSDUW,	   "absduw")
+ BU_ALTIVEC_OVERLOAD_2 (ADD,	   "add")
+ BU_ALTIVEC_OVERLOAD_2 (ADDC,	   "addc")
+ BU_ALTIVEC_OVERLOAD_2 (ADDS,	   "adds")
+@@ -1131,10 +1193,20 @@
+ BU_ALTIVEC_OVERLOAD_X (LVEBX,	   "lvebx")
+ BU_ALTIVEC_OVERLOAD_X (LVEHX,	   "lvehx")
+ BU_ALTIVEC_OVERLOAD_X (LVEWX,	   "lvewx")
++BU_ALTIVC2_OVERLOAD_X (LVEXBX,	   "lvexbx")
++BU_ALTIVC2_OVERLOAD_X (LVEXHX,	   "lvexhx")
++BU_ALTIVC2_OVERLOAD_X (LVEXWX,	   "lvexwx")
+ BU_ALTIVEC_OVERLOAD_X (LVLX,	   "lvlx")
+ BU_ALTIVEC_OVERLOAD_X (LVLXL,	   "lvlxl")
+ BU_ALTIVEC_OVERLOAD_X (LVRX,	   "lvrx")
+ BU_ALTIVEC_OVERLOAD_X (LVRXL,	   "lvrxl")
++BU_ALTIVC2_OVERLOAD_X (LVTLX,	   "lvtlx")
++BU_ALTIVC2_OVERLOAD_X (LVTLXL,	   "lvtlxl")
++BU_ALTIVC2_OVERLOAD_X (LVTRX,	   "lvtrx")
++BU_ALTIVC2_OVERLOAD_X (LVTRXL,	   "lvtrxl")
++BU_ALTIVC2_OVERLOAD_X (LVSWX,	   "lvswx")
++BU_ALTIVC2_OVERLOAD_X (LVSWXL,	   "lvswxl")
++BU_ALTIVC2_OVERLOAD_X (LVSM,	   "lvsm")
+ BU_ALTIVEC_OVERLOAD_X (LVSL,	   "lvsl")
+ BU_ALTIVEC_OVERLOAD_X (LVSR,	   "lvsr")
+ BU_ALTIVEC_OVERLOAD_X (PROMOTE,	   "promote")
+@@ -1148,10 +1220,19 @@
+ BU_ALTIVEC_OVERLOAD_X (STVEBX,	   "stvebx")
+ BU_ALTIVEC_OVERLOAD_X (STVEHX,	   "stvehx")
+ BU_ALTIVEC_OVERLOAD_X (STVEWX,	   "stvewx")
++BU_ALTIVC2_OVERLOAD_X (STVEXBX,	   "stvexbx")
++BU_ALTIVC2_OVERLOAD_X (STVEXHX,	   "stvexhx")
++BU_ALTIVC2_OVERLOAD_X (STVEXWX,	   "stvexwx")
+ BU_ALTIVEC_OVERLOAD_X (STVLX,	   "stvlx")
+ BU_ALTIVEC_OVERLOAD_X (STVLXL,	   "stvlxl")
+ BU_ALTIVEC_OVERLOAD_X (STVRX,	   "stvrx")
+ BU_ALTIVEC_OVERLOAD_X (STVRXL,	   "stvrxl")
++BU_ALTIVC2_OVERLOAD_X (STVFLX,	   "stvflx")
++BU_ALTIVC2_OVERLOAD_X (STVFLXL,	   "stvflxl")
++BU_ALTIVC2_OVERLOAD_X (STVFRX,	   "stvfrx")
++BU_ALTIVC2_OVERLOAD_X (STVFRXL,	   "stvfrxl")
++BU_ALTIVC2_OVERLOAD_X (STVSWX,	   "stvswx")
++BU_ALTIVC2_OVERLOAD_X (STVSWXL,	   "stvswxl")
+ BU_ALTIVEC_OVERLOAD_X (VCFSX,	   "vcfsx")
+ BU_ALTIVEC_OVERLOAD_X (VCFUX,	   "vcfux")
+ BU_ALTIVEC_OVERLOAD_X (VSPLTB,	   "vspltb")
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.c gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.c	2014-06-13 16:56:16.000000000 -0500
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.c	2014-07-17 02:38:35.049383001 -0500
+@@ -3024,6 +3024,7 @@
+ rs6000_builtin_mask_calculate (void)
+ {
+   return (((TARGET_ALTIVEC)		    ? RS6000_BTM_ALTIVEC   : 0)
++          | ((TARGET_ALTIVEC2)              ? RS6000_BTM_ALTIVEC2  : 0)
+ 	  | ((TARGET_VSX)		    ? RS6000_BTM_VSX	   : 0)
+ 	  | ((TARGET_SPE)		    ? RS6000_BTM_SPE	   : 0)
+ 	  | ((TARGET_PAIRED_FLOAT)	    ? RS6000_BTM_PAIRED	   : 0)
+@@ -3462,6 +3463,15 @@
+ 	  || rs6000_cpu == PROCESSOR_PPCE6500))
+     rs6000_block_move_inline_limit = 128;
+ 
++  /* Those machines does not have fsqrt instruction */
++  if (rs6000_cpu == PROCESSOR_PPCE5500
++      || rs6000_cpu == PROCESSOR_PPCE6500)
++    target_flags &= ~(MASK_PPC_GPOPT);
++
++  /* Those machines implements a slow mfocr opcode */
++  if (rs6000_cpu == PROCESSOR_PPCE5500)
++    target_flags &= ~MASK_MFCRF;
++
+   /* store_one_arg depends on expand_block_move to handle at least the
+      size of reg_parm_stack_space.  */
+   if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
+@@ -12895,6 +12905,12 @@
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
+     case ALTIVEC_BUILTIN_STVEWX:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
++    case ALTIVEC_BUILTIN_STVEXBX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvexbx, exp);
++    case ALTIVEC_BUILTIN_STVEXHX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvexhx, exp);
++    case ALTIVEC_BUILTIN_STVEXWX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvexwx, exp);
+     case ALTIVEC_BUILTIN_STVXL_V2DF:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v2df, exp);
+     case ALTIVEC_BUILTIN_STVXL_V2DI:
+@@ -12917,6 +12933,18 @@
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
+     case ALTIVEC_BUILTIN_STVRXL:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
++    case ALTIVEC_BUILTIN_STVFLX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvflx, exp);
++    case ALTIVEC_BUILTIN_STVFLXL:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvflxl, exp);
++    case ALTIVEC_BUILTIN_STVFRX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvfrx, exp);
++    case ALTIVEC_BUILTIN_STVFRXL:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvfrxl, exp);
++    case ALTIVEC_BUILTIN_STVSWX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvswx, exp);
++    case ALTIVEC_BUILTIN_STVSWXL:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvswxl, exp);
+ 
+     case VSX_BUILTIN_STXVD2X_V1TI:
+       return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v1ti, exp);
+@@ -13065,6 +13093,15 @@
+     case ALTIVEC_BUILTIN_LVXL_V4SF:
+       return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4sf,
+ 					exp, target, false);
++    case ALTIVEC_BUILTIN_LVEXBX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvexbx,
++					exp, target, false);
++    case ALTIVEC_BUILTIN_LVEXHX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvexhx,
++					exp, target, false);
++    case ALTIVEC_BUILTIN_LVEXWX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvexwx,
++					exp, target, false);
+     case ALTIVEC_BUILTIN_LVXL:
+     case ALTIVEC_BUILTIN_LVXL_V4SI:
+       return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4si,
+@@ -13106,6 +13143,27 @@
+     case ALTIVEC_BUILTIN_LVRXL:
+       return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
+ 					exp, target, true);
++    case ALTIVEC_BUILTIN_LVTLX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtlx,
++                                        exp, target, true);
++    case ALTIVEC_BUILTIN_LVTLXL:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtlxl,
++                                        exp, target, true);
++    case ALTIVEC_BUILTIN_LVTRX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtrx,
++                                        exp, target, true);
++    case ALTIVEC_BUILTIN_LVTRXL:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtrxl,
++                                        exp, target, true);
++    case ALTIVEC_BUILTIN_LVSWX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvswx,
++                                        exp, target, true);
++    case ALTIVEC_BUILTIN_LVSWXL:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvswxl,
++                                        exp, target, true);
++    case ALTIVEC_BUILTIN_LVSM:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsm,
++                                        exp, target, true);
+     case VSX_BUILTIN_LXVD2X_V1TI:
+       return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v1ti,
+ 					exp, target, false);
+@@ -14489,6 +14547,9 @@
+   def_builtin ("__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
+   def_builtin ("__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
+   def_builtin ("__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
++  def_builtin ("__builtin_altivec_lvexbx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEXBX);
++  def_builtin ("__builtin_altivec_lvexhx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEXHX);
++  def_builtin ("__builtin_altivec_lvexwx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEXWX);
+   def_builtin ("__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
+   def_builtin ("__builtin_altivec_lvxl_v2df", v2df_ftype_long_pcvoid,
+ 	       ALTIVEC_BUILTIN_LVXL_V2DF);
+@@ -14544,6 +14605,9 @@
+ 	       ALTIVEC_BUILTIN_STVXL_V16QI);
+   def_builtin ("__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
+   def_builtin ("__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
++  def_builtin ("__builtin_altivec_stvexbx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEXBX);
++  def_builtin ("__builtin_altivec_stvexhx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEXHX);
++  def_builtin ("__builtin_altivec_stvexwx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEXWX);
+   def_builtin ("__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
+   def_builtin ("__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
+   def_builtin ("__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
+@@ -14552,12 +14616,18 @@
+   def_builtin ("__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
+   def_builtin ("__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
+   def_builtin ("__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
++  def_builtin ("__builtin_vec_lvexbx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEXBX);
++  def_builtin ("__builtin_vec_lvexhx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEXHX);
++  def_builtin ("__builtin_vec_lvexwx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEXWX);
+   def_builtin ("__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
+   def_builtin ("__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
+   def_builtin ("__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
+   def_builtin ("__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
+   def_builtin ("__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
+   def_builtin ("__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
++  def_builtin ("__builtin_vec_stvexwx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEXWX);
++  def_builtin ("__builtin_vec_stvexbx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEXBX);
++  def_builtin ("__builtin_vec_stvexhx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEXHX);
+ 
+   def_builtin ("__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
+ 	       VSX_BUILTIN_LXVD2X_V2DF);
+@@ -14588,6 +14658,40 @@
+   def_builtin ("__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
+ 	       VSX_BUILTIN_VEC_ST);
+ 
++  /* Power ISA 2.07 */
++  def_builtin ("__builtin_altivec_lvtlx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTLX);
++  def_builtin ("__builtin_altivec_lvtlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTLXL);
++  def_builtin ("__builtin_altivec_lvtrx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTRX);
++  def_builtin ("__builtin_altivec_lvtrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTRXL);
++
++  def_builtin ("__builtin_vec_lvtlx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTLX);
++  def_builtin ("__builtin_vec_lvtlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTLXL);
++  def_builtin ("__builtin_vec_lvtrx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTRX);
++  def_builtin ("__builtin_vec_lvtrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTRXL);
++
++  def_builtin ("__builtin_altivec_stvflx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFLX);
++  def_builtin ("__builtin_altivec_stvflxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFLXL);
++  def_builtin ("__builtin_altivec_stvfrx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFRX);
++  def_builtin ("__builtin_altivec_stvfrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFRXL);
++
++  def_builtin ("__builtin_vec_stvflx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFLX);
++  def_builtin ("__builtin_vec_stvflxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFLXL);
++  def_builtin ("__builtin_vec_stvfrx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFRX);
++  def_builtin ("__builtin_vec_stvfrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFRXL);
++
++  def_builtin ("__builtin_altivec_lvswx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSWX);
++  def_builtin ("__builtin_altivec_lvswxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSWXL);
++  def_builtin ("__builtin_vec_lvswx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSWX);
++  def_builtin ("__builtin_vec_lvswxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSWXL);
++
++  def_builtin ("__builtin_altivec_lvsm",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSM);
++  def_builtin ("__builtin_vec_lvsm",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSM);
++
++  def_builtin ("__builtin_altivec_stvswx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVSWX);
++  def_builtin ("__builtin_altivec_stvswxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVSWXL);
++  def_builtin ("__builtin_vec_stvswx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVSWX);
++  def_builtin ("__builtin_vec_stvswxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVSWXL);
++
+   def_builtin ("__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
+   def_builtin ("__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
+   def_builtin ("__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
+@@ -15007,6 +15111,9 @@
+     case ALTIVEC_BUILTIN_VMULEUH_UNS:
+     case ALTIVEC_BUILTIN_VMULOUB_UNS:
+     case ALTIVEC_BUILTIN_VMULOUH_UNS:
++    case ALTIVEC_BUILTIN_VABSDUB:
++    case ALTIVEC_BUILTIN_VABSDUH:
++    case ALTIVEC_BUILTIN_VABSDUW:
+     case CRYPTO_BUILTIN_VCIPHER:
+     case CRYPTO_BUILTIN_VCIPHERLAST:
+     case CRYPTO_BUILTIN_VNCIPHER:
+@@ -31277,6 +31384,7 @@
+ static struct rs6000_opt_mask const rs6000_opt_masks[] =
+ {
+   { "altivec",			OPTION_MASK_ALTIVEC,		false, true  },
++  { "altivec2",			OPTION_MASK_ALTIVEC2,		false, true  },
+   { "cmpb",			OPTION_MASK_CMPB,		false, true  },
+   { "crypto",			OPTION_MASK_CRYPTO,		false, true  },
+   { "direct-move",		OPTION_MASK_DIRECT_MOVE,	false, true  },
+@@ -31335,6 +31443,7 @@
+ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
+ {
+   { "altivec",		 RS6000_BTM_ALTIVEC,	false, false },
++  { "altivec2",		 RS6000_BTM_ALTIVEC2,	false, false },
+   { "vsx",		 RS6000_BTM_VSX,	false, false },
+   { "spe",		 RS6000_BTM_SPE,	false, false },
+   { "paired",		 RS6000_BTM_PAIRED,	false, false },
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000-c.c gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000-c.c
+--- gcc-4.9.1/gcc/config/rs6000/rs6000-c.c	2014-03-27 15:07:16.000000000 -0500
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000-c.c	2014-07-17 02:38:35.051383001 -0500
+@@ -350,6 +350,8 @@
+       if (!flag_iso)
+ 	rs6000_define_or_undefine_macro (define_p, "__APPLE_ALTIVEC__");
+     }
++  if ((flags & OPTION_MASK_ALTIVEC2) != 0)
++    rs6000_define_or_undefine_macro (define_p, "__ALTIVEC2__");
+   if ((flags & OPTION_MASK_VSX) != 0)
+     rs6000_define_or_undefine_macro (define_p, "__VSX__");
+   if ((flags & OPTION_MASK_HTM) != 0)
+@@ -671,6 +673,24 @@
+     RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 },
+ 
+   /* Binary AltiVec/VSX builtins.  */
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUB,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUB,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUB,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUH,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUH,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUH,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUW,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUW,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_VABSDUW,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 },
+   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
+     RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 },
+   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
+@@ -1215,6 +1235,24 @@
+     RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
+   { ALTIVEC_BUILTIN_VEC_LVEBX, ALTIVEC_BUILTIN_LVEBX,
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXHX, ALTIVEC_BUILTIN_LVEXHX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXHX, ALTIVEC_BUILTIN_LVEXHX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXBX, ALTIVEC_BUILTIN_LVEXBX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXBX, ALTIVEC_BUILTIN_LVEXBX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
+   { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SF,
+     RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
+   { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SF,
+@@ -1467,6 +1505,258 @@
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
+   { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL,
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
+   { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB,
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
+   { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB,
+@@ -3012,6 +3302,46 @@
+     RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
+   { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX,
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
+   { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SF,
+     RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
+   { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SF,
+@@ -3216,6 +3546,222 @@
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
+   { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL,
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
+   { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
+     RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE },
+   { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000-cpus.def gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000-cpus.def
+--- gcc-4.9.1/gcc/config/rs6000/rs6000-cpus.def	2014-01-23 19:56:48.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000-cpus.def	2014-07-17 02:38:35.051383001 -0500
+@@ -95,6 +95,7 @@
+ 				 | OPTION_MASK_SOFT_FLOAT		\
+ 				 | OPTION_MASK_STRICT_ALIGN_OPTIONAL	\
+ 				 | OPTION_MASK_VSX			\
++				 | OPTION_MASK_ALTIVEC2			\
+ 				 | OPTION_MASK_VSX_TIMODE)
+ 
+ #endif
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.h gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.h
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.h	2014-06-13 16:56:16.000000000 -0500
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.h	2014-07-17 02:38:35.052383000 -0500
+@@ -523,13 +523,15 @@
+ 
+ #define TARGET_FCTIDZ	TARGET_FCFID
+ #define TARGET_STFIWX	TARGET_PPC_GFXOPT
+-#define TARGET_LFIWAX	TARGET_CMPB
+-#define TARGET_LFIWZX	TARGET_POPCNTD
+-#define TARGET_FCFIDS	TARGET_POPCNTD
+-#define TARGET_FCFIDU	TARGET_POPCNTD
+-#define TARGET_FCFIDUS	TARGET_POPCNTD
+-#define TARGET_FCTIDUZ	TARGET_POPCNTD
+-#define TARGET_FCTIWUZ	TARGET_POPCNTD
++#define TARGET_LFIWAX	(TARGET_CMPB && rs6000_cpu != PROCESSOR_PPCE5500 \
++			 && rs6000_cpu != PROCESSOR_PPCE6500)
++#define TARGET_LFIWZX	(TARGET_POPCNTD && rs6000_cpu != PROCESSOR_PPCE5500 \
++			 && rs6000_cpu != PROCESSOR_PPCE6500)
++#define TARGET_FCFIDS	TARGET_LFIWZX
++#define TARGET_FCFIDU	TARGET_LFIWZX
++#define TARGET_FCFIDUS	TARGET_LFIWZX
++#define TARGET_FCTIDUZ	TARGET_LFIWZX
++#define TARGET_FCTIWUZ	TARGET_LFIWZX
+ 
+ #define TARGET_XSCVDPSPN	(TARGET_DIRECT_MOVE || TARGET_P8_VECTOR)
+ #define TARGET_XSCVSPDPN	(TARGET_DIRECT_MOVE || TARGET_P8_VECTOR)
+@@ -657,10 +659,14 @@
+ 
+ #define TARGET_FRE	(TARGET_HARD_FLOAT && TARGET_FPRS \
+ 			 && TARGET_DOUBLE_FLOAT \
+-			 && (TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)))
++			 && (TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) \
++			 && rs6000_cpu != PROCESSOR_PPCE5500 \
++			 && rs6000_cpu != PROCESSOR_PPCE6500)
+ 
+ #define TARGET_FRSQRTES	(TARGET_HARD_FLOAT && TARGET_POPCNTB \
+-			 && TARGET_FPRS && TARGET_SINGLE_FLOAT)
++			 && TARGET_FPRS && TARGET_SINGLE_FLOAT \
++			 && rs6000_cpu != PROCESSOR_PPCE5500 \
++			 && rs6000_cpu != PROCESSOR_PPCE6500)
+ 
+ #define TARGET_FRSQRTE	(TARGET_HARD_FLOAT && TARGET_FPRS \
+ 			 && TARGET_DOUBLE_FLOAT \
+@@ -2512,6 +2518,7 @@
+    aren't in target_flags.  */
+ #define RS6000_BTM_ALWAYS	0		/* Always enabled.  */
+ #define RS6000_BTM_ALTIVEC	MASK_ALTIVEC	/* VMX/altivec vectors.  */
++#define RS6000_BTM_ALTIVEC2	OPTION_MASK_ALTIVEC2 /* ISA 2.07 altivec vectors.  */
+ #define RS6000_BTM_VSX		MASK_VSX	/* VSX (vector/scalar).  */
+ #define RS6000_BTM_P8_VECTOR	MASK_P8_VECTOR	/* ISA 2.07 vector.  */
+ #define RS6000_BTM_CRYPTO	MASK_CRYPTO	/* crypto funcs.  */
+@@ -2529,6 +2536,7 @@
+ #define RS6000_BTM_LDBL128	MASK_MULTIPLE	/* 128-bit long double.  */
+ 
+ #define RS6000_BTM_COMMON	(RS6000_BTM_ALTIVEC			\
++				 | RS6000_BTM_ALTIVEC2			\
+ 				 | RS6000_BTM_VSX			\
+ 				 | RS6000_BTM_P8_VECTOR			\
+ 				 | RS6000_BTM_CRYPTO			\
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.md gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.md
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.md	2014-06-13 16:56:16.000000000 -0500
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.md	2014-07-17 02:38:35.053383000 -0500
+@@ -5342,10 +5342,10 @@
+    && ((TARGET_PPC_GFXOPT
+         && !HONOR_NANS (<MODE>mode)
+         && !HONOR_SIGNED_ZEROS (<MODE>mode))
+-       || TARGET_CMPB
++       || TARGET_LFIWAX
+        || VECTOR_UNIT_VSX_P (<MODE>mode))"
+ {
+-  if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
++  if (TARGET_LFIWAX || VECTOR_UNIT_VSX_P (<MODE>mode))
+     {
+       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
+ 					     operands[2]));
+@@ -5364,7 +5364,7 @@
+ 	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
+ 		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
+ 		     UNSPEC_COPYSIGN))]
+-  "TARGET_<MODE>_FPR && TARGET_CMPB"
++  "TARGET_<MODE>_FPR && TARGET_LFIWAX"
+   "@
+    fcpsgn %0,%2,%1
+    xscpsgn<Fvsx> %x0,%x2,%x1"
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.opt gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.opt
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.opt	2014-01-23 19:56:48.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/config/rs6000/rs6000.opt	2014-07-17 02:38:35.054383000 -0500
+@@ -148,6 +148,10 @@
+ Target Report RejectNegative Var(rs6000_altivec_element_order, 2)
+ Generate Altivec instructions using big-endian element order
+ 
++maltivec2
++Target Report Mask(ALTIVEC2) Var(rs6000_isa_flags)
++Use AltiVec PowerPC V2.07 instructions
++
+ mhard-dfp
+ Target Report Mask(DFP) Var(rs6000_isa_flags)
+ Use decimal floating point instructions
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c	2014-07-17 02:38:35.054383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtlx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc1(long a, void *p)           { return __builtin_altivec_lvtlx (a,p); }
++vsf  llx01(long a, vsf *p)          { return __builtin_vec_lvtlx (a,p); }
++vsf  llx02(long a, sf *p)           { return __builtin_vec_lvtlx (a,p); }
++vbi  llx03(long a, vbi *p)          { return __builtin_vec_lvtlx (a,p); }
++vsi  llx04(long a, vsi *p)          { return __builtin_vec_lvtlx (a,p); }
++vsi  llx05(long a, si *p)           { return __builtin_vec_lvtlx (a,p); }
++vui  llx06(long a, vui *p)          { return __builtin_vec_lvtlx (a,p); }
++vui  llx07(long a, ui *p)           { return __builtin_vec_lvtlx (a,p); }
++vbs  llx08(long a, vbs *p)          { return __builtin_vec_lvtlx (a,p); }
++vp   llx09(long a, vp *p)           { return __builtin_vec_lvtlx (a,p); }
++vss  llx10(long a, vss *p)          { return __builtin_vec_lvtlx (a,p); }
++vss  llx11(long a, ss *p)           { return __builtin_vec_lvtlx (a,p); }
++vus  llx12(long a, vus *p)          { return __builtin_vec_lvtlx (a,p); }
++vus  llx13(long a, us *p)           { return __builtin_vec_lvtlx (a,p); }
++vbc  llx14(long a, vbc *p)          { return __builtin_vec_lvtlx (a,p); }
++vsc  llx15(long a, vsc *p)          { return __builtin_vec_lvtlx (a,p); }
++vsc  llx16(long a, sc *p)           { return __builtin_vec_lvtlx (a,p); }
++vuc  llx17(long a, vuc *p)          { return __builtin_vec_lvtlx (a,p); }
++vuc  llx18(long a, uc *p)           { return __builtin_vec_lvtlx (a,p); }
++vsf  Dllx01(long a, vsf *p)         { return vec_lvtlx (a,p); }
++vsf  Dllx02(long a, sf *p)          { return vec_lvtlx (a,p); }
++vbi  Dllx03(long a, vbi *p)         { return vec_lvtlx (a,p); }
++vsi  Dllx04(long a, vsi *p)         { return vec_lvtlx (a,p); }
++vsi  Dllx05(long a, si *p)          { return vec_lvtlx (a,p); }
++vui  Dllx06(long a, vui *p)         { return vec_lvtlx (a,p); }
++vui  Dllx07(long a, ui *p)          { return vec_lvtlx (a,p); }
++vbs  Dllx08(long a, vbs *p)         { return vec_lvtlx (a,p); }
++vp   Dllx09(long a, vp *p)          { return vec_lvtlx (a,p); }
++vss  Dllx10(long a, vss *p)         { return vec_lvtlx (a,p); }
++vss  Dllx11(long a, ss *p)          { return vec_lvtlx (a,p); }
++vus  Dllx12(long a, vus *p)         { return vec_lvtlx (a,p); }
++vus  Dllx13(long a, us *p)          { return vec_lvtlx (a,p); }
++vbc  Dllx14(long a, vbc *p)         { return vec_lvtlx (a,p); }
++vsc  Dllx15(long a, vsc *p)         { return vec_lvtlx (a,p); }
++vsc  Dllx16(long a, sc *p)          { return vec_lvtlx (a,p); }
++vuc  Dllx17(long a, vuc *p)         { return vec_lvtlx (a,p); }
++vuc  Dllx18(long a, uc *p)          { return vec_lvtlx (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c	2014-07-17 02:38:35.054383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtlxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc2(long a, void *p)           { return __builtin_altivec_lvtlxl (a,p); }
++vsf  llxl01(long a, vsf *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsf  llxl02(long a, sf *p)          { return __builtin_vec_lvtlxl (a,p); }
++vbi  llxl03(long a, vbi *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsi  llxl04(long a, vsi *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsi  llxl05(long a, si *p)          { return __builtin_vec_lvtlxl (a,p); }
++vui  llxl06(long a, vui *p)         { return __builtin_vec_lvtlxl (a,p); }
++vui  llxl07(long a, ui *p)          { return __builtin_vec_lvtlxl (a,p); }
++vbs  llxl08(long a, vbs *p)         { return __builtin_vec_lvtlxl (a,p); }
++vp   llxl09(long a, vp *p)          { return __builtin_vec_lvtlxl (a,p); }
++vss  llxl10(long a, vss *p)         { return __builtin_vec_lvtlxl (a,p); }
++vss  llxl11(long a, ss *p)          { return __builtin_vec_lvtlxl (a,p); }
++vus  llxl12(long a, vus *p)         { return __builtin_vec_lvtlxl (a,p); }
++vus  llxl13(long a, us *p)          { return __builtin_vec_lvtlxl (a,p); }
++vbc  llxl14(long a, vbc *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsc  llxl15(long a, vsc *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsc  llxl16(long a, sc *p)          { return __builtin_vec_lvtlxl (a,p); }
++vuc  llxl17(long a, vuc *p)         { return __builtin_vec_lvtlxl (a,p); }
++vuc  llxl18(long a, uc *p)          { return __builtin_vec_lvtlxl (a,p); }
++vsf  Dllxl01(long a, vsf *p)        { return vec_lvtlxl (a,p); }
++vsf  Dllxl02(long a, sf *p)         { return vec_lvtlxl (a,p); }
++vbi  Dllxl03(long a, vbi *p)        { return vec_lvtlxl (a,p); }
++vsi  Dllxl04(long a, vsi *p)        { return vec_lvtlxl (a,p); }
++vsi  Dllxl05(long a, si *p)         { return vec_lvtlxl (a,p); }
++vui  Dllxl06(long a, vui *p)        { return vec_lvtlxl (a,p); }
++vui  Dllxl07(long a, ui *p)         { return vec_lvtlxl (a,p); }
++vbs  Dllxl08(long a, vbs *p)        { return vec_lvtlxl (a,p); }
++vp   Dllxl09(long a, vp *p)         { return vec_lvtlxl (a,p); }
++vss  Dllxl10(long a, vss *p)        { return vec_lvtlxl (a,p); }
++vss  Dllxl11(long a, ss *p)         { return vec_lvtlxl (a,p); }
++vus  Dllxl12(long a, vus *p)        { return vec_lvtlxl (a,p); }
++vus  Dllxl13(long a, us *p)         { return vec_lvtlxl (a,p); }
++vbc  Dllxl14(long a, vbc *p)        { return vec_lvtlxl (a,p); }
++vsc  Dllxl15(long a, vsc *p)        { return vec_lvtlxl (a,p); }
++vsc  Dllxl16(long a, sc *p)         { return vec_lvtlxl (a,p); }
++vuc  Dllxl17(long a, vuc *p)        { return vec_lvtlxl (a,p); }
++vuc  Dllxl18(long a, uc *p)         { return vec_lvtlxl (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c	2014-07-17 02:38:35.054383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtrx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc3(long a, void *p)           { return __builtin_altivec_lvtrx (a,p); }
++vsf  lrx01(long a, vsf *p)          { return __builtin_vec_lvtrx (a,p); }
++vsf  lrx02(long a, sf *p)           { return __builtin_vec_lvtrx (a,p); }
++vbi  lrx03(long a, vbi *p)          { return __builtin_vec_lvtrx (a,p); }
++vsi  lrx04(long a, vsi *p)          { return __builtin_vec_lvtrx (a,p); }
++vsi  lrx05(long a, si *p)           { return __builtin_vec_lvtrx (a,p); }
++vui  lrx06(long a, vui *p)          { return __builtin_vec_lvtrx (a,p); }
++vui  lrx07(long a, ui *p)           { return __builtin_vec_lvtrx (a,p); }
++vbs  lrx08(long a, vbs *p)          { return __builtin_vec_lvtrx (a,p); }
++vp   lrx09(long a, vp *p)           { return __builtin_vec_lvtrx (a,p); }
++vss  lrx10(long a, vss *p)          { return __builtin_vec_lvtrx (a,p); }
++vss  lrx11(long a, ss *p)           { return __builtin_vec_lvtrx (a,p); }
++vus  lrx12(long a, vus *p)          { return __builtin_vec_lvtrx (a,p); }
++vus  lrx13(long a, us *p)           { return __builtin_vec_lvtrx (a,p); }
++vbc  lrx14(long a, vbc *p)          { return __builtin_vec_lvtrx (a,p); }
++vsc  lrx15(long a, vsc *p)          { return __builtin_vec_lvtrx (a,p); }
++vsc  lrx16(long a, sc *p)           { return __builtin_vec_lvtrx (a,p); }
++vuc  lrx17(long a, vuc *p)          { return __builtin_vec_lvtrx (a,p); }
++vuc  lrx18(long a, uc *p)           { return __builtin_vec_lvtrx (a,p); }
++vsf  Dlrx01(long a, vsf *p)         { return vec_lvtrx (a,p); }
++vsf  Dlrx02(long a, sf *p)          { return vec_lvtrx (a,p); }
++vbi  Dlrx03(long a, vbi *p)         { return vec_lvtrx (a,p); }
++vsi  Dlrx04(long a, vsi *p)         { return vec_lvtrx (a,p); }
++vsi  Dlrx05(long a, si *p)          { return vec_lvtrx (a,p); }
++vui  Dlrx06(long a, vui *p)         { return vec_lvtrx (a,p); }
++vui  Dlrx07(long a, ui *p)          { return vec_lvtrx (a,p); }
++vbs  Dlrx08(long a, vbs *p)         { return vec_lvtrx (a,p); }
++vp   Dlrx09(long a, vp *p)          { return vec_lvtrx (a,p); }
++vss  Dlrx10(long a, vss *p)         { return vec_lvtrx (a,p); }
++vss  Dlrx11(long a, ss *p)          { return vec_lvtrx (a,p); }
++vus  Dlrx12(long a, vus *p)         { return vec_lvtrx (a,p); }
++vus  Dlrx13(long a, us *p)          { return vec_lvtrx (a,p); }
++vbc  Dlrx14(long a, vbc *p)         { return vec_lvtrx (a,p); }
++vsc  Dlrx15(long a, vsc *p)         { return vec_lvtrx (a,p); }
++vsc  Dlrx16(long a, sc *p)          { return vec_lvtrx (a,p); }
++vuc  Dlrx17(long a, vuc *p)         { return vec_lvtrx (a,p); }
++vuc  Dlrx18(long a, uc *p)          { return vec_lvtrx (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c	2014-07-17 02:38:35.054383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtrxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc4(long a, void *p)           { return __builtin_altivec_lvtrxl (a,p); }
++vsf  lrxl01(long a, vsf *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsf  lrxl02(long a, sf *p)          { return __builtin_vec_lvtrxl (a,p); }
++vbi  lrxl03(long a, vbi *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsi  lrxl04(long a, vsi *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsi  lrxl05(long a, si *p)          { return __builtin_vec_lvtrxl (a,p); }
++vui  lrxl06(long a, vui *p)         { return __builtin_vec_lvtrxl (a,p); }
++vui  lrxl07(long a, ui *p)          { return __builtin_vec_lvtrxl (a,p); }
++vbs  lrxl08(long a, vbs *p)         { return __builtin_vec_lvtrxl (a,p); }
++vp   lrxl09(long a, vp *p)          { return __builtin_vec_lvtrxl (a,p); }
++vss  lrxl10(long a, vss *p)         { return __builtin_vec_lvtrxl (a,p); }
++vss  lrxl11(long a, ss *p)          { return __builtin_vec_lvtrxl (a,p); }
++vus  lrxl12(long a, vus *p)         { return __builtin_vec_lvtrxl (a,p); }
++vus  lrxl13(long a, us *p)          { return __builtin_vec_lvtrxl (a,p); }
++vbc  lrxl14(long a, vbc *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsc  lrxl15(long a, vsc *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsc  lrxl16(long a, sc *p)          { return __builtin_vec_lvtrxl (a,p); }
++vuc  lrxl17(long a, vuc *p)         { return __builtin_vec_lvtrxl (a,p); }
++vuc  lrxl18(long a, uc *p)          { return __builtin_vec_lvtrxl (a,p); }
++vsf  Dlrxl01(long a, vsf *p)        { return vec_lvtrxl (a,p); }
++vsf  Dlrxl02(long a, sf *p)         { return vec_lvtrxl (a,p); }
++vbi  Dlrxl03(long a, vbi *p)        { return vec_lvtrxl (a,p); }
++vsi  Dlrxl04(long a, vsi *p)        { return vec_lvtrxl (a,p); }
++vsi  Dlrxl05(long a, si *p)         { return vec_lvtrxl (a,p); }
++vui  Dlrxl06(long a, vui *p)        { return vec_lvtrxl (a,p); }
++vui  Dlrxl07(long a, ui *p)         { return vec_lvtrxl (a,p); }
++vbs  Dlrxl08(long a, vbs *p)        { return vec_lvtrxl (a,p); }
++vp   Dlrxl09(long a, vp *p)         { return vec_lvtrxl (a,p); }
++vss  Dlrxl10(long a, vss *p)        { return vec_lvtrxl (a,p); }
++vss  Dlrxl11(long a, ss *p)         { return vec_lvtrxl (a,p); }
++vus  Dlrxl12(long a, vus *p)        { return vec_lvtrxl (a,p); }
++vus  Dlrxl13(long a, us *p)         { return vec_lvtrxl (a,p); }
++vbc  Dlrxl14(long a, vbc *p)        { return vec_lvtrxl (a,p); }
++vsc  Dlrxl15(long a, vsc *p)        { return vec_lvtrxl (a,p); }
++vsc  Dlrxl16(long a, sc *p)         { return vec_lvtrxl (a,p); }
++vuc  Dlrxl17(long a, vuc *p)        { return vec_lvtrxl (a,p); }
++vuc  Dlrxl18(long a, uc *p)         { return vec_lvtrxl (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c	2014-07-17 02:38:35.054383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvflx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc1(vsc v, long a, void *p)    { __builtin_altivec_stvflx (v,a,p); }
++void slx01(vsf v, long a, vsf *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx02(vsf v, long a, sf *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx03(vbi v, long a, vbi *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx04(vsi v, long a, vsi *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx05(vsi v, long a, si *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx06(vui v, long a, vui *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx07(vui v, long a, ui *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx08(vbs v, long a, vbs *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx09(vp v, long a, vp *p)     { __builtin_vec_stvflx (v,a,p); }
++void slx10(vss v, long a, vss *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx11(vss v, long a, ss *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx12(vus v, long a, vus *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx13(vus v, long a, us *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx14(vbc v, long a, vbc *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx15(vsc v, long a, vsc *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx16(vsc v, long a, sc *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx17(vuc v, long a, vuc *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx18(vuc v, long a, uc *p)    { __builtin_vec_stvflx (v,a,p); }
++void Dslx01(vsf v, long a, vsf *p)  { vec_stvflx (v,a,p); }
++void Dslx02(vsf v, long a, sf *p)   { vec_stvflx (v,a,p); }
++void Dslx03(vbi v, long a, vbi *p)  { vec_stvflx (v,a,p); }
++void Dslx04(vsi v, long a, vsi *p)  { vec_stvflx (v,a,p); }
++void Dslx05(vsi v, long a, si *p)   { vec_stvflx (v,a,p); }
++void Dslx06(vui v, long a, vui *p)  { vec_stvflx (v,a,p); }
++void Dslx07(vui v, long a, ui *p)   { vec_stvflx (v,a,p); }
++void Dslx08(vbs v, long a, vbs *p)  { vec_stvflx (v,a,p); }
++void Dslx09(vp v, long a, vp *p)    { vec_stvflx (v,a,p); }
++void Dslx10(vss v, long a, vss *p)  { vec_stvflx (v,a,p); }
++void Dslx11(vss v, long a, ss *p)   { vec_stvflx (v,a,p); }
++void Dslx12(vus v, long a, vus *p)  { vec_stvflx (v,a,p); }
++void Dslx13(vus v, long a, us *p)   { vec_stvflx (v,a,p); }
++void Dslx14(vbc v, long a, vbc *p)  { vec_stvflx (v,a,p); }
++void Dslx15(vsc v, long a, vsc *p)  { vec_stvflx (v,a,p); }
++void Dslx16(vsc v, long a, sc *p)   { vec_stvflx (v,a,p); }
++void Dslx17(vuc v, long a, vuc *p)  { vec_stvflx (v,a,p); }
++void Dslx18(vuc v, long a, uc *p)   { vec_stvflx (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c	2014-07-17 02:38:35.055383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvflxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc2(vsc v, long a, void *p)    { __builtin_altivec_stvflxl (v,a,p); }
++void slxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl02(vsf v, long a, sf *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl05(vsi v, long a, si *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl06(vui v, long a, vui *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl07(vui v, long a, ui *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl09(vp v, long a, vp *p)    { __builtin_vec_stvflxl (v,a,p); }
++void slxl10(vss v, long a, vss *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl11(vss v, long a, ss *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl12(vus v, long a, vus *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl13(vus v, long a, us *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl16(vsc v, long a, sc *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl18(vuc v, long a, uc *p)   { __builtin_vec_stvflxl (v,a,p); }
++void Dslxl01(vsf v, long a, vsf *p) { vec_stvflxl (v,a,p); }
++void Dslxl02(vsf v, long a, sf *p)  { vec_stvflxl (v,a,p); }
++void Dslxl03(vbi v, long a, vbi *p) { vec_stvflxl (v,a,p); }
++void Dslxl04(vsi v, long a, vsi *p) { vec_stvflxl (v,a,p); }
++void Dslxl05(vsi v, long a, si *p)  { vec_stvflxl (v,a,p); }
++void Dslxl06(vui v, long a, vui *p) { vec_stvflxl (v,a,p); }
++void Dslxl07(vui v, long a, ui *p)  { vec_stvflxl (v,a,p); }
++void Dslxl08(vbs v, long a, vbs *p) { vec_stvflxl (v,a,p); }
++void Dslxl09(vp v, long a, vp *p)   { vec_stvflxl (v,a,p); }
++void Dslxl10(vss v, long a, vss *p) { vec_stvflxl (v,a,p); }
++void Dslxl11(vss v, long a, ss *p)  { vec_stvflxl (v,a,p); }
++void Dslxl12(vus v, long a, vus *p) { vec_stvflxl (v,a,p); }
++void Dslxl13(vus v, long a, us *p)  { vec_stvflxl (v,a,p); }
++void Dslxl14(vbc v, long a, vbc *p) { vec_stvflxl (v,a,p); }
++void Dslxl15(vsc v, long a, vsc *p) { vec_stvflxl (v,a,p); }
++void Dslxl16(vsc v, long a, sc *p)  { vec_stvflxl (v,a,p); }
++void Dslxl17(vuc v, long a, vuc *p) { vec_stvflxl (v,a,p); }
++void Dslxl18(vuc v, long a, uc *p)  { vec_stvflxl (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c	2014-07-17 02:38:35.055383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvfrx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc3(vsc v, long a, void *p)    { __builtin_altivec_stvfrx (v,a,p); }
++void srx01(vsf v, long a, vsf *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx02(vsf v, long a, sf *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx03(vbi v, long a, vbi *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx04(vsi v, long a, vsi *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx05(vsi v, long a, si *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx06(vui v, long a, vui *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx07(vui v, long a, ui *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx08(vbs v, long a, vbs *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx09(vp v, long a, vp *p)     { __builtin_vec_stvfrx (v,a,p); }
++void srx10(vss v, long a, vss *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx11(vss v, long a, ss *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx12(vus v, long a, vus *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx13(vus v, long a, us *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx14(vbc v, long a, vbc *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx15(vsc v, long a, vsc *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx16(vsc v, long a, sc *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx17(vuc v, long a, vuc *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx18(vuc v, long a, uc *p)    { __builtin_vec_stvfrx (v,a,p); }
++void Dsrx01(vsf v, long a, vsf *p)  { vec_stvfrx (v,a,p); }
++void Dsrx02(vsf v, long a, sf *p)   { vec_stvfrx (v,a,p); }
++void Dsrx03(vbi v, long a, vbi *p)  { vec_stvfrx (v,a,p); }
++void Dsrx04(vsi v, long a, vsi *p)  { vec_stvfrx (v,a,p); }
++void Dsrx05(vsi v, long a, si *p)   { vec_stvfrx (v,a,p); }
++void Dsrx06(vui v, long a, vui *p)  { vec_stvfrx (v,a,p); }
++void Dsrx07(vui v, long a, ui *p)   { vec_stvfrx (v,a,p); }
++void Dsrx08(vbs v, long a, vbs *p)  { vec_stvfrx (v,a,p); }
++void Dsrx09(vp v, long a, vp *p)    { vec_stvfrx (v,a,p); }
++void Dsrx10(vss v, long a, vss *p)  { vec_stvfrx (v,a,p); }
++void Dsrx11(vss v, long a, ss *p)   { vec_stvfrx (v,a,p); }
++void Dsrx12(vus v, long a, vus *p)  { vec_stvfrx (v,a,p); }
++void Dsrx13(vus v, long a, us *p)   { vec_stvfrx (v,a,p); }
++void Dsrx14(vbc v, long a, vbc *p)  { vec_stvfrx (v,a,p); }
++void Dsrx15(vsc v, long a, vsc *p)  { vec_stvfrx (v,a,p); }
++void Dsrx16(vsc v, long a, sc *p)   { vec_stvfrx (v,a,p); }
++void Dsrx17(vuc v, long a, vuc *p)  { vec_stvfrx (v,a,p); }
++void Dsrx18(vuc v, long a, uc *p)   { vec_stvfrx (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c	2014-07-17 02:38:35.055383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvfrxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc4(vsc v, long a, void *p)    { __builtin_altivec_stvfrxl (v,a,p); }
++void srxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl02(vsf v, long a, sf *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl05(vsi v, long a, si *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl06(vui v, long a, vui *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl07(vui v, long a, ui *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl09(vp v, long a, vp *p)    { __builtin_vec_stvfrxl (v,a,p); }
++void srxl10(vss v, long a, vss *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl11(vss v, long a, ss *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl12(vus v, long a, vus *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl13(vus v, long a, us *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl16(vsc v, long a, sc *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl18(vuc v, long a, uc *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void Dsrxl01(vsf v, long a, vsf *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl02(vsf v, long a, sf *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl03(vbi v, long a, vbi *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl04(vsi v, long a, vsi *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl05(vsi v, long a, si *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl06(vui v, long a, vui *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl07(vui v, long a, ui *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl08(vbs v, long a, vbs *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl09(vp v, long a, vp *p)   { vec_stvfrxl (v,a,p); }
++void Dsrxl10(vss v, long a, vss *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl11(vss v, long a, ss *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl12(vus v, long a, vus *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl13(vus v, long a, us *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl14(vbc v, long a, vbc *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl15(vsc v, long a, vsc *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl16(vsc v, long a, sc *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl17(vuc v, long a, vuc *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl18(vuc v, long a, uc *p)  { vec_stvfrxl (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c	2014-07-17 02:38:35.055383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvswx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  ls1(long a, void *p)           { return __builtin_altivec_lvswx (a,p); }
++vsf  ls01(long a, vsf *p)           { return __builtin_vec_lvswx (a,p); }
++vsf  ls02(long a, sf *p)            { return __builtin_vec_lvswx (a,p); }
++vbi  ls03(long a, vbi *p)           { return __builtin_vec_lvswx (a,p); }
++vsi  ls04(long a, vsi *p)           { return __builtin_vec_lvswx (a,p); }
++vsi  ls05(long a, si *p)            { return __builtin_vec_lvswx (a,p); }
++vui  ls06(long a, vui *p)           { return __builtin_vec_lvswx (a,p); }
++vui  ls07(long a, ui *p)            { return __builtin_vec_lvswx (a,p); }
++vbs  ls08(long a, vbs *p)           { return __builtin_vec_lvswx (a,p); }
++vp   ls09(long a, vp *p)            { return __builtin_vec_lvswx (a,p); }
++vss  ls10(long a, vss *p)           { return __builtin_vec_lvswx (a,p); }
++vss  ls11(long a, ss *p)            { return __builtin_vec_lvswx (a,p); }
++vus  ls12(long a, vus *p)           { return __builtin_vec_lvswx (a,p); }
++vus  ls13(long a, us *p)            { return __builtin_vec_lvswx (a,p); }
++vbc  ls14(long a, vbc *p)           { return __builtin_vec_lvswx (a,p); }
++vsc  ls15(long a, vsc *p)           { return __builtin_vec_lvswx (a,p); }
++vsc  ls16(long a, sc *p)            { return __builtin_vec_lvswx (a,p); }
++vuc  ls17(long a, vuc *p)           { return __builtin_vec_lvswx (a,p); }
++vuc  ls18(long a, uc *p)            { return __builtin_vec_lvswx (a,p); }
++vsf  Dls01(long a, vsf *p)          { return vec_lvswx (a,p); }
++vsf  Dls02(long a, sf *p)           { return vec_lvswx (a,p); }
++vbi  Dls03(long a, vbi *p)          { return vec_lvswx (a,p); }
++vsi  Dls04(long a, vsi *p)          { return vec_lvswx (a,p); }
++vsi  Dls05(long a, si *p)           { return vec_lvswx (a,p); }
++vui  Dls06(long a, vui *p)          { return vec_lvswx (a,p); }
++vui  Dls07(long a, ui *p)           { return vec_lvswx (a,p); }
++vbs  Dls08(long a, vbs *p)          { return vec_lvswx (a,p); }
++vp   Dls09(long a, vp *p)           { return vec_lvswx (a,p); }
++vss  Dls10(long a, vss *p)          { return vec_lvswx (a,p); }
++vss  Dls11(long a, ss *p)           { return vec_lvswx (a,p); }
++vus  Dls12(long a, vus *p)          { return vec_lvswx (a,p); }
++vus  Dls13(long a, us *p)           { return vec_lvswx (a,p); }
++vbc  Dls14(long a, vbc *p)          { return vec_lvswx (a,p); }
++vsc  Dls15(long a, vsc *p)          { return vec_lvswx (a,p); }
++vsc  Dls16(long a, sc *p)           { return vec_lvswx (a,p); }
++vuc  Dls17(long a, vuc *p)          { return vec_lvswx (a,p); }
++vuc  Dls18(long a, uc *p)           { return vec_lvswx (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c	2014-07-17 02:38:35.055383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvswxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  ls2l(long a, void *p)          { return __builtin_altivec_lvswxl (a,p); }
++vsf  lsl01(long a, vsf *p)          { return __builtin_vec_lvswxl (a,p); }
++vsf  lsl02(long a, sf *p)           { return __builtin_vec_lvswxl (a,p); }
++vbi  lsl03(long a, vbi *p)          { return __builtin_vec_lvswxl (a,p); }
++vsi  lsl04(long a, vsi *p)          { return __builtin_vec_lvswxl (a,p); }
++vsi  lsl05(long a, si *p)           { return __builtin_vec_lvswxl (a,p); }
++vui  lsl06(long a, vui *p)          { return __builtin_vec_lvswxl (a,p); }
++vui  lsl07(long a, ui *p)           { return __builtin_vec_lvswxl (a,p); }
++vbs  lsl08(long a, vbs *p)          { return __builtin_vec_lvswxl (a,p); }
++vp   lsl09(long a, vp *p)           { return __builtin_vec_lvswxl (a,p); }
++vss  lsl10(long a, vss *p)          { return __builtin_vec_lvswxl (a,p); }
++vss  lsl11(long a, ss *p)           { return __builtin_vec_lvswxl (a,p); }
++vus  lsl12(long a, vus *p)          { return __builtin_vec_lvswxl (a,p); }
++vus  lsl13(long a, us *p)           { return __builtin_vec_lvswxl (a,p); }
++vbc  lsl14(long a, vbc *p)          { return __builtin_vec_lvswxl (a,p); }
++vsc  lsl15(long a, vsc *p)          { return __builtin_vec_lvswxl (a,p); }
++vsc  lsl16(long a, sc *p)           { return __builtin_vec_lvswxl (a,p); }
++vuc  lsl17(long a, vuc *p)          { return __builtin_vec_lvswxl (a,p); }
++vuc  lsl18(long a, uc *p)           { return __builtin_vec_lvswxl (a,p); }
++vsf  Dlsl01(long a, vsf *p)         { return vec_lvswxl (a,p); }
++vsf  Dlsl02(long a, sf *p)          { return vec_lvswxl (a,p); }
++vbi  Dlsl03(long a, vbi *p)         { return vec_lvswxl (a,p); }
++vsi  Dlsl04(long a, vsi *p)         { return vec_lvswxl (a,p); }
++vsi  Dlsl05(long a, si *p)          { return vec_lvswxl (a,p); }
++vui  Dlsl06(long a, vui *p)         { return vec_lvswxl (a,p); }
++vui  Dlsl07(long a, ui *p)          { return vec_lvswxl (a,p); }
++vbs  Dlsl08(long a, vbs *p)         { return vec_lvswxl (a,p); }
++vp   Dlsl09(long a, vp *p)          { return vec_lvswxl (a,p); }
++vss  Dlsl10(long a, vss *p)         { return vec_lvswxl (a,p); }
++vss  Dlsl11(long a, ss *p)          { return vec_lvswxl (a,p); }
++vus  Dlsl12(long a, vus *p)         { return vec_lvswxl (a,p); }
++vus  Dlsl13(long a, us *p)          { return vec_lvswxl (a,p); }
++vbc  Dlsl14(long a, vbc *p)         { return vec_lvswxl (a,p); }
++vsc  Dlsl15(long a, vsc *p)         { return vec_lvswxl (a,p); }
++vsc  Dlsl16(long a, sc *p)          { return vec_lvswxl (a,p); }
++vuc  Dlsl17(long a, vuc *p)         { return vec_lvswxl (a,p); }
++vuc  Dlsl18(long a, uc *p)          { return vec_lvswxl (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c	2014-07-17 02:38:35.055383000 -0500
+@@ -0,0 +1,36 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "vabsdub" 7 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vuc  fa1b(vuc a, vuc b)             { return __builtin_altivec_vabsdub (a,b); }
++vuc  ad1(vuc a, vuc b)              { return __builtin_vec_absd (a,b); }
++vuc  ad2(vbc a, vuc b)              { return __builtin_vec_absd (a,b); }
++vuc  ad3(vuc a, vbc b)              { return __builtin_vec_absd (a,b); }
++vuc  Dad1(vuc a, vuc b)             { return vec_absd (a,b); }
++vuc  Dad2(vbc a, vuc b)             { return vec_absd (a,b); }
++vuc  Dad3(vuc a, vbc b)             { return vec_absd (a,b); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c	2014-07-17 02:38:35.055383000 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvswx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void ss1(vsc v, long a, vsc *p)     { __builtin_altivec_stvswx (v,a,p); }
++void ssx01(vsf v, long a, vsf *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx02(vsf v, long a, sf  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx03(vbi v, long a, vbi *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx04(vsi v, long a, vsi *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx05(vsi v, long a, si  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx06(vui v, long a, vui *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx07(vui v, long a, ui  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx08(vbs v, long a, vbs *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx09(vp  v, long a, vp  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx10(vss v, long a, vss *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx11(vss v, long a, ss  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx12(vus v, long a, vus *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx13(vus v, long a, us  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx14(vbc v, long a, vbc *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx15(vsc v, long a, vsc *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx16(vsc v, long a, sc  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx17(vuc v, long a, vuc *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx18(vuc v, long a, uc  *p)   { __builtin_vec_stvswx (v,a,p); }
++void Dssx01(vsf v, long a, vsf *p)  { vec_stvswx (v,a,p); }
++void Dssx02(vsf v, long a, sf  *p)  { vec_stvswx (v,a,p); }
++void Dssx03(vbi v, long a, vbi *p)  { vec_stvswx (v,a,p); }
++void Dssx04(vsi v, long a, vsi *p)  { vec_stvswx (v,a,p); }
++void Dssx05(vsi v, long a, si  *p)  { vec_stvswx (v,a,p); }
++void Dssx06(vui v, long a, vui *p)  { vec_stvswx (v,a,p); }
++void Dssx07(vui v, long a, ui  *p)  { vec_stvswx (v,a,p); }
++void Dssx08(vbs v, long a, vbs *p)  { vec_stvswx (v,a,p); }
++void Dssx09(vp  v, long a, vp  *p)  { vec_stvswx (v,a,p); }
++void Dssx10(vss v, long a, vss *p)  { vec_stvswx (v,a,p); }
++void Dssx11(vss v, long a, ss  *p)  { vec_stvswx (v,a,p); }
++void Dssx12(vus v, long a, vus *p)  { vec_stvswx (v,a,p); }
++void Dssx13(vus v, long a, us  *p)  { vec_stvswx (v,a,p); }
++void Dssx14(vbc v, long a, vbc *p)  { vec_stvswx (v,a,p); }
++void Dssx15(vsc v, long a, vsc *p)  { vec_stvswx (v,a,p); }
++void Dssx16(vsc v, long a, sc  *p)  { vec_stvswx (v,a,p); }
++void Dssx17(vuc v, long a, vuc *p)  { vec_stvswx (v,a,p); }
++void Dssx18(vuc v, long a, uc  *p)  { vec_stvswx (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvswxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void ss2l(vsc v, long a, vsc *p)    { __builtin_altivec_stvswxl (v,a,p); }
++void ssxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl02(vsf v, long a, sf  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl05(vsi v, long a, si  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl06(vui v, long a, vui *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl07(vui v, long a, ui  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl09(vp  v, long a, vp  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl10(vss v, long a, vss *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl11(vss v, long a, ss  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl12(vus v, long a, vus *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl13(vus v, long a, us  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl16(vsc v, long a, sc  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl18(vuc v, long a, uc  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void Dssxl01(vsf v, long a, vsf *p) { vec_stvswxl (v,a,p); }
++void Dssxl02(vsf v, long a, sf  *p) { vec_stvswxl (v,a,p); }
++void Dssxl03(vbi v, long a, vbi *p) { vec_stvswxl (v,a,p); }
++void Dssxl04(vsi v, long a, vsi *p) { vec_stvswxl (v,a,p); }
++void Dssxl05(vsi v, long a, si  *p) { vec_stvswxl (v,a,p); }
++void Dssxl06(vui v, long a, vui *p) { vec_stvswxl (v,a,p); }
++void Dssxl07(vui v, long a, ui  *p) { vec_stvswxl (v,a,p); }
++void Dssxl08(vbs v, long a, vbs *p) { vec_stvswxl (v,a,p); }
++void Dssxl09(vp  v, long a, vp  *p) { vec_stvswxl (v,a,p); }
++void Dssxl10(vss v, long a, vss *p) { vec_stvswxl (v,a,p); }
++void Dssxl11(vss v, long a, ss  *p) { vec_stvswxl (v,a,p); }
++void Dssxl12(vus v, long a, vus *p) { vec_stvswxl (v,a,p); }
++void Dssxl13(vus v, long a, us  *p) { vec_stvswxl (v,a,p); }
++void Dssxl14(vbc v, long a, vbc *p) { vec_stvswxl (v,a,p); }
++void Dssxl15(vsc v, long a, vsc *p) { vec_stvswxl (v,a,p); }
++void Dssxl16(vsc v, long a, sc  *p) { vec_stvswxl (v,a,p); }
++void Dssxl17(vuc v, long a, vuc *p) { vec_stvswxl (v,a,p); }
++void Dssxl18(vuc v, long a, uc  *p) { vec_stvswxl (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvsm" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lsm(long a, void *p)           { return __builtin_altivec_lvsm (a,p); }
++vsf  lm01(long a, vsf *p)           { return __builtin_vec_lvsm (a,p); }
++vsf  lm02(long a, sf *p)            { return __builtin_vec_lvsm (a,p); }
++vbi  lm03(long a, vbi *p)           { return __builtin_vec_lvsm (a,p); }
++vsi  lm04(long a, vsi *p)           { return __builtin_vec_lvsm (a,p); }
++vsi  lm05(long a, si *p)            { return __builtin_vec_lvsm (a,p); }
++vui  lm06(long a, vui *p)           { return __builtin_vec_lvsm (a,p); }
++vui  lm07(long a, ui *p)            { return __builtin_vec_lvsm (a,p); }
++vbs  lm08(long a, vbs *p)           { return __builtin_vec_lvsm (a,p); }
++vp   lm09(long a, vp *p)            { return __builtin_vec_lvsm (a,p); }
++vss  lm10(long a, vss *p)           { return __builtin_vec_lvsm (a,p); }
++vss  lm11(long a, ss *p)            { return __builtin_vec_lvsm (a,p); }
++vus  lm12(long a, vus *p)           { return __builtin_vec_lvsm (a,p); }
++vus  lm13(long a, us *p)            { return __builtin_vec_lvsm (a,p); }
++vbc  lm14(long a, vbc *p)           { return __builtin_vec_lvsm (a,p); }
++vsc  lm15(long a, vsc *p)           { return __builtin_vec_lvsm (a,p); }
++vsc  lm16(long a, sc *p)            { return __builtin_vec_lvsm (a,p); }
++vuc  lm17(long a, vuc *p)           { return __builtin_vec_lvsm (a,p); }
++vuc  lm18(long a, uc *p)            { return __builtin_vec_lvsm (a,p); }
++vsf  Dlm01(long a, vsf *p)          { return vec_lvsm (a,p); }
++vsf  Dlm02(long a, sf *p)           { return vec_lvsm (a,p); }
++vbi  Dlm03(long a, vbi *p)          { return vec_lvsm (a,p); }
++vsi  Dlm04(long a, vsi *p)          { return vec_lvsm (a,p); }
++vsi  Dlm05(long a, si *p)           { return vec_lvsm (a,p); }
++vui  Dlm06(long a, vui *p)          { return vec_lvsm (a,p); }
++vui  Dlm07(long a, ui *p)           { return vec_lvsm (a,p); }
++vbs  Dlm08(long a, vbs *p)          { return vec_lvsm (a,p); }
++vp   Dlm09(long a, vp *p)           { return vec_lvsm (a,p); }
++vss  Dlm10(long a, vss *p)          { return vec_lvsm (a,p); }
++vss  Dlm11(long a, ss *p)           { return vec_lvsm (a,p); }
++vus  Dlm12(long a, vus *p)          { return vec_lvsm (a,p); }
++vus  Dlm13(long a, us *p)           { return vec_lvsm (a,p); }
++vbc  Dlm14(long a, vbc *p)          { return vec_lvsm (a,p); }
++vsc  Dlm15(long a, vsc *p)          { return vec_lvsm (a,p); }
++vsc  Dlm16(long a, sc *p)           { return vec_lvsm (a,p); }
++vuc  Dlm17(long a, vuc *p)          { return vec_lvsm (a,p); }
++vuc  Dlm18(long a, uc *p)           { return vec_lvsm (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,36 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "vabsduh" 7 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vus  fa2h(vus a, vus b)             { return __builtin_altivec_vabsduh (a,b); }
++vus  ad4(vus a, vus b)              { return __builtin_vec_absd (a,b); }
++vus  ad5(vbs a, vus b)              { return __builtin_vec_absd (a,b); }
++vus  ad6(vus a, vbs b)              { return __builtin_vec_absd (a,b); }
++vus  Dad4(vus a, vus b)             { return vec_absd (a,b); }
++vus  Dad5(vbs a, vus b)             { return vec_absd (a,b); }
++vus  Dad6(vus a, vbs b)             { return vec_absd (a,b); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,36 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "vabsduw" 7 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vui  fa3w(vui a, vui b)             { return __builtin_altivec_vabsduw (a,b); }
++vui  ad7(vui a, vui b)              { return __builtin_vec_absd (a,b); }
++vui  ad8(vbi a, vui b)              { return __builtin_vec_absd (a,b); }
++vui  ad9(vui a, vbi b)              { return __builtin_vec_absd (a,b); }
++vui  Dad7(vui a, vui b)             { return vec_absd (a,b); }
++vui  Dad8(vbi a, vui b)             { return vec_absd (a,b); }
++vui  Dad9(vui a, vbi b)             { return vec_absd (a,b); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,34 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvexbx" 5 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  le1b(long a, void *p)          { return __builtin_altivec_lvexbx (a,p); }
++vsc  leb1(long a, sc *p)            { return __builtin_vec_lvexbx (a,p); }
++vuc  leb2(long a, uc *p)            { return __builtin_vec_lvexbx (a,p); }
++vsc  Dleb1(long a, sc *p)           { return vec_lvexbx (a,p); }
++vuc  Dleb2(long a, uc *p)           { return vec_lvexbx (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,34 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvexhx" 5 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vss  le2h(long a, void *p)          { return __builtin_altivec_lvexhx (a,p); }
++vss  leh1(long a, ss *p)            { return __builtin_vec_lvexhx (a,p); }
++vus  leh2(long a, us *p)            { return __builtin_vec_lvexhx (a,p); }
++vss  Dleh1(long a, ss *p)           { return vec_lvexhx (a,p); }
++vus  Dleh2(long a, us *p)           { return vec_lvexhx (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,40 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvexwx" 11 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsi  le3w(long a, void *p)          { return __builtin_altivec_lvexwx (a,p); }
++vsf  lew1(long a, sf *p)            { return __builtin_vec_lvexwx (a,p); }
++vsi  lew2(long a, si *p)            { return __builtin_vec_lvexwx (a,p); }
++vui  lew3(long a, ui *p)            { return __builtin_vec_lvexwx (a,p); }
++vsi  lew4(long a, sl *p)            { return __builtin_vec_lvexwx (a,p); }
++vui  lew5(long a, ul *p)            { return __builtin_vec_lvexwx (a,p); }
++vsf  Dlew1(long a, sf *p)           { return vec_lvexwx (a,p); }
++vsi  Dlew2(long a, si *p)           { return vec_lvexwx (a,p); }
++vui  Dlew3(long a, ui *p)           { return vec_lvexwx (a,p); }
++vsi  Dlew4(long a, sl *p)           { return vec_lvexwx (a,p); }
++vui  Dlew5(long a, ul *p)           { return vec_lvexwx (a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,42 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvexbx" 13 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void se1b(vsc v, long a, vsc *p)    { __builtin_altivec_stvexbx (v,a,p); }
++void seb1(vsc v, long a, sc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb2(vuc v, long a, uc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb3(vbc v, long a, sc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb4(vbc v, long a, uc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb5(vsc v, long a, void *p)   { __builtin_vec_stvexbx (v,a,p); }
++void seb6(vuc v, long a, void *p)   { __builtin_vec_stvexbx (v,a,p); }
++void Dseb1(vsc v, long a, sc *p)    { vec_stvexbx (v,a,p); }
++void Dseb2(vuc v, long a, uc *p)    { vec_stvexbx (v,a,p); }
++void Dseb3(vbc v, long a, sc *p)    { vec_stvexbx (v,a,p); }
++void Dseb4(vbc v, long a, uc *p)    { vec_stvexbx (v,a,p); }
++void Dseb5(vsc v, long a, void *p)  { vec_stvexbx (v,a,p); }
++void Dseb6(vuc v, long a, void *p)  { vec_stvexbx (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c	2014-07-17 02:38:35.055383001 -0500
+@@ -0,0 +1,42 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvexhx" 13 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void se2h(vss v, long a, vss *p)    { __builtin_altivec_stvexhx (v,a,p); }
++void seh1(vss v, long a, ss *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh2(vus v, long a, us *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh3(vbs v, long a, ss *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh4(vbs v, long a, us *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh5(vss v, long a, void *p)   { __builtin_vec_stvexhx (v,a,p); }
++void seh6(vus v, long a, void *p)   { __builtin_vec_stvexhx (v,a,p); }
++void Dseh1(vss v, long a, ss *p)    { vec_stvexhx (v,a,p); }
++void Dseh2(vus v, long a, us *p)    { vec_stvexhx (v,a,p); }
++void Dseh3(vbs v, long a, ss *p)    { vec_stvexhx (v,a,p); }
++void Dseh4(vbs v, long a, us *p)    { vec_stvexhx (v,a,p); }
++void Dseh5(vss v, long a, void *p)  { vec_stvexhx (v,a,p); }
++void Dseh6(vus v, long a, void *p)  { vec_stvexhx (v,a,p); }
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-e6500-FSF/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c	2014-07-17 02:38:35.057383001 -0500
+@@ -0,0 +1,46 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvexwx" 17 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void se3w(vsi v, long a, vsi *p)    { __builtin_altivec_stvexwx (v,a,p); }
++void sew1(vsf v, long a, sf *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew2(vsi v, long a, si *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew3(vui v, long a, ui *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew4(vbi v, long a, si *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew5(vbi v, long a, ui *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew6(vsf v, long a, void *p)   { __builtin_vec_stvexwx (v,a,p); }
++void sew7(vsi v, long a, void *p)   { __builtin_vec_stvexwx (v,a,p); }
++void sew8(vui v, long a, void *p)   { __builtin_vec_stvexwx (v,a,p); }
++void Dsew1(vsf v, long a, sf *p)    { vec_stvexwx (v,a,p); }
++void Dsew2(vsi v, long a, si *p)    { vec_stvexwx (v,a,p); }
++void Dsew3(vui v, long a, ui *p)    { vec_stvexwx (v,a,p); }
++void Dsew4(vbi v, long a, si *p)    { vec_stvexwx (v,a,p); }
++void Dsew5(vbi v, long a, ui *p)    { vec_stvexwx (v,a,p); }
++void Dsew6(vsf v, long a, void *p)  { vec_stvexwx (v,a,p); }
++void Dsew7(vsi v, long a, void *p)  { vec_stvexwx (v,a,p); }
++void Dsew8(vui v, long a, void *p)  { vec_stvexwx (v,a,p); }
diff --git a/recipes-devtools/gcc/gcc-4.9/0002-uclibc-conf.patch b/recipes-devtools/gcc/gcc-4.9/0002-uclibc-conf.patch
new file mode 100644
index 0000000..dda3b10
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0002-uclibc-conf.patch
@@ -0,0 +1,53 @@
+From d030973c872c00d916921d84deee0af2c0d38081 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:38:25 +0400
+Subject: [PATCH 02/35] uclibc-conf
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ contrib/regression/objs-gcc.sh |    4 ++++
+ libjava/classpath/ltconfig     |    4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/contrib/regression/objs-gcc.sh b/contrib/regression/objs-gcc.sh
+index 60b0497..6dc7ead 100755
+--- a/contrib/regression/objs-gcc.sh
++++ b/contrib/regression/objs-gcc.sh
+@@ -106,6 +106,10 @@ if [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-gnu ]
+  then
+   make all-gdb all-dejagnu all-ld || exit 1
+   make install-gdb install-dejagnu install-ld || exit 1
++elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
++ then
++  make all-gdb all-dejagnu all-ld || exit 1
++  make install-gdb install-dejagnu install-ld || exit 1
+ elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
+   make bootstrap || exit 1
+   make install || exit 1
+diff --git a/libjava/classpath/ltconfig b/libjava/classpath/ltconfig
+index 743d951..ae4ea60 100755
+--- a/libjava/classpath/ltconfig
++++ b/libjava/classpath/ltconfig
+@@ -603,7 +603,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+ 
+ # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+ case $host_os in
+-linux-gnu*) ;;
++linux-gnu*|linux-uclibc*) ;;
+ linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+ esac
+ 
+@@ -1247,7 +1247,7 @@ linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+   ;;
+ 
+ # This must be Linux ELF.
+-linux-gnu*)
++linux*)
+   version_type=linux
+   need_lib_prefix=no
+   need_version=no
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0002.gcc.builtin_isel-49x.patch b/recipes-devtools/gcc/gcc-4.9/0002.gcc.builtin_isel-49x.patch
new file mode 100644
index 0000000..6e000e5
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0002.gcc.builtin_isel-49x.patch
@@ -0,0 +1,1112 @@
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000-builtin.def gcc-4.9.1-isel/gcc/config/rs6000/rs6000-builtin.def
+--- gcc-4.9.1/gcc/config/rs6000/rs6000-builtin.def	2014-06-13 16:56:16.000000000 -0500
++++ gcc-4.9.1-isel/gcc/config/rs6000/rs6000-builtin.def	2014-07-17 02:22:16.013383000 -0500
+@@ -1928,6 +1928,81 @@
+ BU_SPE_X (MFSPEFSCR,	      "mfspefscr",	MISC)
+ BU_SPE_X (MTSPEFSCR,	      "mtspefscr",	MISC)
+ 
++#define BU_ISEL_X(ENUM, NAME)						\
++  RS6000_BUILTIN_X (RS6000_BUILTIN_ISEL ## ENUM,	/* ENUM */	\
++		    "__builtin_isel" NAME,		/* NAME */	\
++		    RS6000_BTM_ISEL,			/* MASK */	\
++		    (RS6000_BTC_OVERLOADED | RS6000_BTC_PURE),		        /* ATTR */	\
++		    CODE_FOR_nothing)			/* ICODE */
++#define BU_ISEL_OVERLOAD_X(ENUM, NAME)				\
++  RS6000_BUILTIN_X (RS6000_BUILTIN_ISEL_ ## ENUM,	/* ENUM */	\
++		    "__builtin_isel" NAME,		/* NAME */	\
++		    RS6000_BTM_ISEL,			/* MASK */	\
++		    (RS6000_BTC_OVERLOADED		/* ATTR */	\
++		     | RS6000_BTC_PURE),				\
++		    CODE_FOR_nothing)			/* ICODE */
++/* ISEL builtins.  */
++/* Generic versions that get resolved to specific builtins.  */
++BU_ISEL_X(EQ, "eq")
++BU_ISEL_X(GT, "gt")
++BU_ISEL_X(LT, "lt")
++BU_ISEL_X(GTU, "gtu")
++BU_ISEL_X(LTU, "ltu")
++/* Same deal, but for 64-bit comparisons.  */
++BU_ISEL_X(EQD, "eqd")
++BU_ISEL_X(GTD, "gtd")
++BU_ISEL_X(LTD, "ltd")
++BU_ISEL_X(GTDU, "gtdu")
++BU_ISEL_X(LTDU, "ltdu")
++
++/* Each set of arguments is polymorphic in selected arguments and return
++   value.  */
++#undef RS6000_ISEL_BASE
++#define RS6000_ISEL_BASE(ARG, PRED, CMP, NAME)     \
++  BU_ISEL_OVERLOAD_X(PRED##CMP##_##ARG##_SS, NAME) \
++  BU_ISEL_OVERLOAD_X(PRED##CMP##_##ARG##_PP, NAME) \
++  BU_ISEL_OVERLOAD_X(PRED##CMP##_##ARG##_UU, NAME)
++
++#undef RS6000_ISEL_PTR_ARG
++#define RS6000_ISEL_PTR_ARG(PRED, CMP, NAME) RS6000_ISEL_BASE(PP, PRED, CMP, NAME)
++#undef RS6000_ISEL_SIGNED_ARG
++#define RS6000_ISEL_SIGNED_ARG(PRED, CMP, NAME) RS6000_ISEL_BASE(SS, PRED, CMP, NAME)
++#undef RS6000_ISEL_UNSIGNED_ARG
++#define RS6000_ISEL_UNSIGNED_ARG(PRED, CMP, NAME) RS6000_ISEL_BASE(UU, PRED, CMP, NAME)
++
++#undef RS6000_ISEL_EQ
++#define RS6000_ISEL_EQ(CMP, NAME)          \
++  RS6000_ISEL_PTR_ARG(EQ, CMP, NAME)       \
++  RS6000_ISEL_SIGNED_ARG(EQ, CMP, NAME)    \
++  RS6000_ISEL_UNSIGNED_ARG(EQ, CMP, NAME)
++
++#undef RS6000_ISEL_LT
++#define RS6000_ISEL_LT(CMP, NAME) RS6000_ISEL_SIGNED_ARG(LT, CMP, NAME)
++
++#undef RS6000_ISEL_GT
++#define RS6000_ISEL_GT(CMP, NAME) RS6000_ISEL_SIGNED_ARG(GT, CMP, NAME)
++
++#undef RS6000_ISEL_LTU
++#define RS6000_ISEL_LTU(CMP, NAME)         \
++  RS6000_ISEL_PTR_ARG(LTU, CMP, NAME)      \
++  RS6000_ISEL_UNSIGNED_ARG(LTU, CMP, NAME)
++
++#undef RS6000_ISEL_GTU
++#define RS6000_ISEL_GTU(CMP, NAME)         \
++  RS6000_ISEL_PTR_ARG(GTU, CMP, NAME)      \
++  RS6000_ISEL_UNSIGNED_ARG(GTU, CMP, NAME)
++
++RS6000_ISEL_EQ(CMPW, "eq")
++RS6000_ISEL_LT(CMPW, "lt")
++RS6000_ISEL_GT(CMPW, "gt")
++RS6000_ISEL_LTU(CMPW, "ltu")
++RS6000_ISEL_GTU(CMPW, "gtu")
++RS6000_ISEL_EQ(CMPD, "eqd")
++RS6000_ISEL_LT(CMPD, "ltd")
++RS6000_ISEL_GT(CMPD, "gtd")
++RS6000_ISEL_LTU(CMPD, "ltdu")
++RS6000_ISEL_GTU(CMPD, "gtdu")
++
+ \f
+ /* Power7 builtins, that aren't VSX instructions.  */
+ BU_SPECIAL_X (POWER7_BUILTIN_BPERMD, "__builtin_bpermd", RS6000_BTM_POPCNTD,
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.c gcc-4.9.1-isel/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.c	2014-06-13 16:56:16.000000000 -0500
++++ gcc-4.9.1-isel/gcc/config/rs6000/rs6000.c	2014-07-17 02:36:19.310382993 -0500
+@@ -3033,6 +3033,7 @@
+ 	  | ((TARGET_FRSQRTES)		    ? RS6000_BTM_FRSQRTES  : 0)
+ 	  | ((TARGET_POPCNTD)		    ? RS6000_BTM_POPCNTD   : 0)
+ 	  | ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL      : 0)
++	  | ((TARGET_ISEL) 		    ? RS6000_BTM_ISEL      : 0)
+ 	  | ((TARGET_P8_VECTOR)		    ? RS6000_BTM_P8_VECTOR : 0)
+ 	  | ((TARGET_CRYPTO)		    ? RS6000_BTM_CRYPTO	   : 0)
+ 	  | ((TARGET_HTM)		    ? RS6000_BTM_HTM	   : 0)
+@@ -13602,11 +13603,296 @@
+ 	   " -mlong-double-128 options", name);
+   else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
+     error ("Builtin function %s requires the -mhard-float option", name);
++  else if ((fnmask & RS6000_BTM_ISEL) != 0)
++    error ("Builtin function %s requires the -misel option", name);
+   else
+     error ("Builtin function %s is not supported with the current options",
+ 	   name);
+ }
+ 
++/* isel builtins are a bit funny, because we want the user to be able to do:
++ *
++ *    char *p, *q, *r;
++ *       int x, y, z;
++ *          unsigned int a, b, c;
++ *             ...
++ *                p = __builtin_iseleq (i, j, q, r);
++ *                   x = __builtin_iseleq (i, j, y, z);
++ *                      a = __builtin_iseleq (i, j, b, c);
++ *
++ *                         and, of course, i and j may be of several different types depending on the
++ *                            condition.
++ *
++ *                               We handle this by having generic builtins that
++ *                                  TARGET_RESOLVE_OVERLOADED_BUILTIN takes and turns into calls to our
++ *                                     specific builtins.  */
++
++/* Macros to help constructing the isel_builtin_desc arrays.
++ *    These closely mirror the macros in rs6000-builtins.def.  */
++/* HACK: Use VOIDmode here as a constant approximation to Pmode and fix
++ *    at runtime.  We can't use Pmode because in biarch its definition is
++ *       not constant.  */
++#define ISEL_Pmode VOIDmode
++#define ISEL_BASE(FLAGS, ARG, RESULT, PRED, CMP, MODE, RMODE)          \
++  { NULL, FLAGS, RS6000_BUILTIN_ISEL_##PRED##CMP##_##ARG##_##RESULT,   \
++      PRED, MODE, RMODE },
++#define ISEL_P_RESULT(FLAGS, ARG, PRED, CMP, MODE, RMODE)              \
++  ISEL_BASE (FLAGS | ISEL_FLAG_SEL_PTR, ARG, PP, PRED,         \
++            CMP, MODE, ISEL_Pmode)
++#define ISEL_S_RESULT(FLAGS, ARG, PRED, CMP, MODE, RMODE)              \
++  ISEL_BASE (FLAGS | ISEL_FLAG_SEL_SIGNED, ARG, SS, PRED,              \
++            CMP, MODE, RMODE)
++#define ISEL_U_RESULT(FLAGS, ARG, PRED, CMP, MODE, RMODE)              \
++  ISEL_BASE (FLAGS | ISEL_FLAG_SEL_UNSIGNED, ARG, UU, PRED,            \
++            CMP, MODE, RMODE)
++
++#define ISEL_EXPAND_ARG(FLAG, ARG, PRED, CMP, MODE, RMODE)             \
++  ISEL_P_RESULT (FLAG, ARG, PRED, CMP, MODE, RMODE)            \
++  ISEL_S_RESULT (FLAG, ARG, PRED, CMP, MODE, RMODE)            \
++  ISEL_U_RESULT (FLAG, ARG, PRED, CMP, MODE, RMODE)
++#define ISEL_PTR_ARG(PRED, CMP, MODE)                          \
++  ISEL_EXPAND_ARG (ISEL_FLAG_CMP_PTR, PP, PRED, CMP, ISEL_Pmode, MODE)
++#define ISEL_SIGNED_ARG(PRED, CMP, MODE)                       \
++  ISEL_EXPAND_ARG (ISEL_FLAG_CMP_SIGNED, SS, PRED, CMP, MODE, MODE)
++#define ISEL_UNSIGNED_ARG(PRED, CMP, MODE)                     \
++  ISEL_EXPAND_ARG (ISEL_FLAG_CMP_UNSIGNED, UU, PRED, CMP, MODE, MODE)
++
++#define ISEL_EQ(CMP, MODE)                                     \
++  ISEL_PTR_ARG (EQ, CMP, MODE)                                 \
++  ISEL_SIGNED_ARG (EQ, CMP, MODE)                              \
++  ISEL_UNSIGNED_ARG (EQ, CMP, MODE)
++#define ISEL_LT(CMP, MODE) ISEL_SIGNED_ARG (LT, CMP, MODE)
++#define ISEL_GT(CMP, MODE) ISEL_SIGNED_ARG (GT, CMP, MODE)
++#define ISEL_LTU(CMP, MODE)                                    \
++  ISEL_PTR_ARG (LTU, CMP, MODE)                                        \
++  ISEL_UNSIGNED_ARG (LTU, CMP, MODE)
++#define ISEL_GTU(CMP, MODE)                                    \
++  ISEL_PTR_ARG (GTU, CMP, MODE)                                        \
++  ISEL_UNSIGNED_ARG (GTU, CMP, MODE)
++
++const struct isel_builtin_desc builtin_iselw[32] = {
++  ISEL_EQ (CMPW, SImode)
++  ISEL_LT (CMPW, SImode)
++  ISEL_GT (CMPW, SImode)
++  ISEL_LTU (CMPW, SImode)
++  ISEL_GTU (CMPW, SImode)
++  { "__builtin_iseleq", 0, RS6000_BUILTIN_ISELEQ, EQ, SImode, SImode },
++  { "__builtin_isellt", 0, RS6000_BUILTIN_ISELLT, LT, SImode, SImode },
++  { "__builtin_iselgt", 0, RS6000_BUILTIN_ISELGT, GT, SImode, SImode },
++  { "__builtin_iselltu", 0, RS6000_BUILTIN_ISELLTU, LTU, SImode, SImode },
++  { "__builtin_iselgtu", 0, RS6000_BUILTIN_ISELGTU, GTU, SImode, SImode }
++};
++
++const struct isel_builtin_desc builtin_iseld[32] = {
++  ISEL_EQ (CMPD, DImode)
++  ISEL_LT (CMPD, DImode)
++  ISEL_GT (CMPD, DImode)
++  ISEL_LTU (CMPD, DImode)
++  ISEL_GTU (CMPD, DImode)
++  { "__builtin_isel64eq", 0, RS6000_BUILTIN_ISELEQD, EQ, DImode, DImode },
++  { "__builtin_isel64lt", 0, RS6000_BUILTIN_ISELLTD, LT, DImode, DImode },
++  { "__builtin_isel64gt", 0, RS6000_BUILTIN_ISELGTD, GT, DImode, DImode },
++  { "__builtin_isel64ltu", 0, RS6000_BUILTIN_ISELLTDU, LTU, DImode, DImode },
++  { "__builtin_isel64gtu", 0, RS6000_BUILTIN_ISELGTDU, GTU, DImode, DImode }
++};
++
++/* Return the mode which DESC uses for comparisons.  */
++
++static enum machine_mode
++isel_cmp_mode (const struct isel_builtin_desc *desc)
++{
++  enum machine_mode mode = (enum machine_mode) desc->cmp_mode;
++
++  return (mode == VOIDmode ? Pmode : mode);
++}
++
++/* Return the mode in which DESC selects arguments.  */
++
++static enum machine_mode
++isel_sel_mode (const struct isel_builtin_desc *desc)
++{
++  enum machine_mode mode = (enum machine_mode) desc->sel_mode;
++
++  return (mode == VOIDmode ? Pmode : mode);
++}
++
++/* Return a tree describing the arguments for DESC according to CMPP:
++ *    true for comparison arguments, false for select arguments.  */
++
++static tree
++isel_argtype (const struct isel_builtin_desc *desc, bool cmpp)
++{
++  switch (desc->arg_flags & (cmpp
++                            ? ISEL_FLAG_CMP_MASK
++                            : ISEL_FLAG_SEL_MASK))
++    {
++    case ISEL_FLAG_CMP_PTR:
++    case ISEL_FLAG_SEL_PTR:
++      return ptr_type_node;
++    case ISEL_FLAG_CMP_SIGNED:
++      return (isel_cmp_mode (desc) == SImode
++             ? integer_type_node
++             : long_integer_type_node);
++    case ISEL_FLAG_SEL_SIGNED:
++      return (isel_sel_mode (desc) == SImode
++             ? integer_type_node
++             : long_integer_type_node);
++    case ISEL_FLAG_CMP_UNSIGNED:
++      return (isel_cmp_mode (desc) == SImode
++             ? unsigned_type_node
++             : long_unsigned_type_node);
++    case ISEL_FLAG_SEL_UNSIGNED:
++    default:
++      return (isel_sel_mode (desc) == SImode
++             ? unsigned_type_node
++             : long_unsigned_type_node);
++    }
++}
++
++/* Return a mnemonic string describing the argument or result of FLAGS
++ *    depending on CMPP.  */
++
++static const char *
++isel_strdesc (int flags, bool cmpp)
++{
++  switch (flags & (cmpp ? ISEL_FLAG_CMP_MASK : ISEL_FLAG_SEL_MASK))
++    {
++    case ISEL_FLAG_CMP_PTR:
++    case ISEL_FLAG_SEL_PTR:
++      return "p";
++    case ISEL_FLAG_CMP_SIGNED:
++    case ISEL_FLAG_SEL_SIGNED:
++      return "s";
++    case ISEL_FLAG_CMP_UNSIGNED:
++    case ISEL_FLAG_SEL_UNSIGNED:
++      return "u";
++    default:
++      gcc_unreachable ();
++    }
++}
++
++/* Initialize N_DESC isel builtins from DESC.  SIGNED_TYPE holds the
++ *    basic type for signed variants of isel, UNSIGNED_TYPE the type for
++ *       unsigned variants.  */
++
++static void
++rs6000_init_isel_builtins (const struct isel_builtin_desc *desc, int n_descs)
++{
++  int i;
++  const char *is64 = (desc == &builtin_iselw[0] ? "32" : "64");
++
++  for (i = 0; i < n_descs; i++)
++    {
++      const struct isel_builtin_desc *d = &desc[i];
++      tree cmptype, seltype, ftype;
++
++      cmptype = isel_argtype (d, true);
++      seltype = isel_argtype (d, false);
++
++      ftype = build_function_type_list (seltype, cmptype, cmptype,
++                                       seltype, seltype, NULL_TREE);
++
++      if (d->name)
++       def_builtin (d->name, ftype, d->code);
++      else
++       {
++         char builtin_name[40];
++
++         sprintf (builtin_name, "__builtin_isel%s%s%s%s%s%s",
++                  is64,
++                  GET_RTX_NAME (d->cmp_code),
++                  GET_MODE_NAME (isel_cmp_mode (d)),
++                  isel_strdesc (d->arg_flags, true),
++                  isel_strdesc (d->arg_flags, false),
++                  GET_MODE_NAME (isel_sel_mode (d)));
++
++         def_builtin (ggc_strdup (builtin_name), ftype, d->code);
++       }
++    }
++}
++
++static rtx
++rs6000_expand_isel_builtin (const struct isel_builtin_desc *desc,
++                           int n_descs, tree exp, rtx target, int fcode)
++{
++  int i;
++
++  for (i = 0; i < n_descs; i++)
++    {
++      const struct isel_builtin_desc *d = &desc[i];
++
++      if (fcode == (int) d->code)
++       {
++         int opidx;
++         unsigned int j;
++         rtx cmp;
++         rtx operands[4];
++         enum insn_code icode;
++         enum machine_mode opmode;
++         enum machine_mode cmpmode = isel_cmp_mode (d);
++         enum machine_mode selmode = isel_sel_mode (d);
++
++         /* Determine underlying isel insn.  */
++         switch (d->cmp_code)
++           {
++           case GTU:
++           case LTU:
++             icode = (Pmode == SImode
++                      ? CODE_FOR_isel_unsigned_si
++                      : CODE_FOR_isel_unsigned_di);
++             break;
++           default:
++             icode = (Pmode == SImode
++                      ? CODE_FOR_isel_signed_si
++                      : CODE_FOR_isel_signed_di);
++             break;
++           }
++
++         for (j = 0; j < ARRAY_SIZE (operands); j++)
++           {
++             tree arg = CALL_EXPR_ARG (exp, j);
++
++             /* If we got invalid arguments, bail out before generating
++ *                 bad rtl.  */
++             if (arg == error_mark_node)
++               return const0_rtx;
++
++             operands[j] = expand_normal (arg);
++
++             /* Validate.  */
++             /* HACK: The isel pattern doesn't actually consume all the
++                operands to the builtin; it only consumes 2 and 3.  The
++                other two will be handed off to a compare
++                insn. Unfortunately, said insn is not named, so we
++                can't directly access its insn_data here.  Fake it by
++                validating operands 0 and 1 with the isel pattern; that
++                should be good enough.  */
++             opidx = (j < 2 ? 2 : j);
++             opmode = (j < 2 ? cmpmode : selmode);
++             if (! (*insn_data[icode].operand[opidx].predicate) (operands[j],
++                                                                 opmode))
++               operands[j] = copy_to_mode_reg (opmode, operands[j]);
++           }
++
++         /* Validate target.  */
++         if (target == NULL_RTX
++             || GET_MODE (target) != selmode
++             || ! (*insn_data[icode].operand[0].predicate) (target, selmode))
++           target = gen_reg_rtx (selmode);
++
++         /* Generate comparison.  */
++         cmp = gen_rtx_fmt_ee ((enum rtx_code)d->cmp_code, cmpmode,
++                               operands[0], operands[1]);
++
++         rs6000_emit_int_cmove (target, cmp, operands[2], operands[3]);
++
++         return target;
++       }
++    }
++
++  return NULL_RTX;
++}
++
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+@@ -14019,6 +14305,10 @@
+     paired_init_builtins ();
+   if (TARGET_SPE)
+     spe_init_builtins ();
++  if (TARGET_ISEL)
++    rs6000_init_isel_builtins (builtin_iselw, ARRAY_SIZE (builtin_iselw));
++  if (TARGET_ISEL64)
++    rs6000_init_isel_builtins (builtin_iseld, ARRAY_SIZE (builtin_iseld));
+   if (TARGET_EXTRA_BUILTINS)
+     altivec_init_builtins ();
+   if (TARGET_HTM)
+@@ -31344,6 +31634,7 @@
+   { "frsqrtes",		 RS6000_BTM_FRSQRTES,	false, false },
+   { "popcntd",		 RS6000_BTM_POPCNTD,	false, false },
+   { "cell",		 RS6000_BTM_CELL,	false, false },
++  { "isel",              RS6000_BTM_ISEL,       false, false },
+   { "power8-vector",	 RS6000_BTM_P8_VECTOR,	false, false },
+   { "crypto",		 RS6000_BTM_CRYPTO,	false, false },
+   { "htm",		 RS6000_BTM_HTM,	false, false },
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000-c.c gcc-4.9.1-isel/gcc/config/rs6000/rs6000-c.c
+--- gcc-4.9.1/gcc/config/rs6000/rs6000-c.c	2014-03-27 15:07:16.000000000 -0500
++++ gcc-4.9.1-isel/gcc/config/rs6000/rs6000-c.c	2014-07-17 02:22:16.027383000 -0500
+@@ -4167,7 +4167,7 @@
+ /* Implementation of the resolve_overloaded_builtin target hook, to
+    support Altivec's overloaded builtins.  */
+ 
+-tree
++static tree
+ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
+ 				    void *passed_arglist)
+ {
+@@ -4561,3 +4561,147 @@
+   error ("invalid parameter combination for AltiVec intrinsic");
+   return error_mark_node;
+ }
++
++/* Return true if the pair of arguments in ARGS is acceptable according
++   to DECLTYPES and FLAGS.  CMPP determines whether this is for the
++   comparison arguments.  */
++
++static bool
++isel_arguments_valid (tree *args, tree *decltypes, int flags, bool cmpp)
++{
++  tree type0 = TREE_TYPE (args[0]);
++  tree type1 = TREE_TYPE (args[1]);
++  tree decltype0 = decltypes[0];
++  tree decltype1 = decltypes[1];
++
++  switch (flags & (cmpp ? ISEL_FLAG_CMP_MASK : ISEL_FLAG_SEL_MASK))
++    {
++      /* For pointer arguments and results, we just need to make sure
++        we're receiving pointers, and they can be freely converted to
++        and from void *.  For pointer results, we also need to ensure
++        that the types of the passed arguments are compatible: this is
++        similar to what the ?: construct would need to ensure.  */
++    case ISEL_FLAG_CMP_PTR:
++    case ISEL_FLAG_SEL_PTR:
++      {
++       /* Results compatible with each other?  */
++       if (!lang_hooks.types_compatible_p (type0, type1))
++         return false;
++
++       return (POINTER_TYPE_P (type0)
++               && POINTER_TYPE_P (type1));
++      }
++      break;
++      /* For signed and unsigned arguments and results, we just need to
++        make sure that the argument types are compatible with the
++        declared types; we can insert conversions to make everything
++        match up.  */
++    case ISEL_FLAG_CMP_SIGNED:
++    case ISEL_FLAG_SEL_SIGNED:
++    case ISEL_FLAG_CMP_UNSIGNED:
++    case ISEL_FLAG_SEL_UNSIGNED:
++      return (lang_hooks.types_compatible_p (type0, decltype0)
++             && lang_hooks.types_compatible_p (type1, decltype1));
++    default:
++      ;
++    }
++
++  gcc_unreachable ();
++}
++
++/* Determine if FNDECL is a generic isel intrinsic and if it can be
++   resolved to a non-generic version with a proper type using the
++   descriptions found in DESC.  Return a call to the non-generic builtin
++   if so.  */
++
++static tree
++rs6000_resolve_isel_builtin (location_t loc, tree fndecl,
++                            void *passed_arglist,
++                            const struct isel_builtin_desc *desc,
++                            int n_descs)
++{
++  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
++  unsigned int nargs = vec_safe_length (arglist);
++  int i;
++  enum rs6000_builtins fcode
++    = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
++  const struct isel_builtin_desc *generic = NULL;
++
++  /* Is this even a builtin we care about?  */
++  if (!rs6000_overloaded_builtin_p (fcode))
++    return NULL_TREE;
++
++  if (nargs != 4)
++    {
++      return NULL_TREE;
++    }
++
++  /* Find the generic builtin we're resolving.  */
++  for (i = 0; i < n_descs; i++)
++    if (desc[i].code == fcode)
++      {
++       generic = &desc[i];
++       break;
++      }
++
++  /* Happens if we're looking for a 64-bit builtin in the 32-bit
++     descriptors.  */
++  if (generic == NULL)
++    return NULL_TREE;
++
++  /* Try all the builtins whose comparison matches the generic one.  */
++  for (i = 0; i < n_descs; i++)
++    {
++      const struct isel_builtin_desc *d = &desc[i];
++      int j;
++      tree *argp = vec_safe_address (arglist);
++      tree impl_fndecl;
++      tree decltypes[4], t;
++      tree converted_args[4];
++
++      if (d == generic || d->cmp_code != generic->cmp_code)
++       continue;
++
++      impl_fndecl = rs6000_builtin_decls[d->code];
++      t = TYPE_ARG_TYPES (TREE_TYPE (impl_fndecl));
++      for (j = 0 ; t != void_list_node; j++, t = TREE_CHAIN (t))
++       decltypes[j] = TREE_VALUE (t);
++
++      if (!isel_arguments_valid (argp, decltypes, d->arg_flags, true)
++         || !isel_arguments_valid (argp+2, decltypes+2, d->arg_flags, false))
++       continue;
++
++      /* We got here, we're ok.  Build a new, resolved CALL_EXPR.  */
++      for (j = 0; j < 4; j++)
++       converted_args[j] = fold_convert (decltypes[j], argp[j]);
++
++      return build_call_expr_loc (loc, impl_fndecl, 4,
++                                 converted_args[0], converted_args[1],
++                                 converted_args[2], converted_args[3]);
++    }
++
++  error ("invalid parameter combination for isel intrinsic");
++  return error_mark_node;
++}
++
++tree
++rs6000_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
++{
++  tree t;
++
++  t = rs6000_resolve_isel_builtin (loc, fndecl, arglist,
++                                  builtin_iselw, ARRAY_SIZE (builtin_iselw));
++  if (t)
++    return t;
++
++  t = rs6000_resolve_isel_builtin (loc, fndecl, arglist,
++                                  builtin_iseld, ARRAY_SIZE (builtin_iseld));
++  if (t)
++    return t;
++
++  t = altivec_resolve_overloaded_builtin (loc, fndecl, arglist);
++  if (t)
++    return t;
++
++  return NULL_TREE;
++}
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.h gcc-4.9.1-isel/gcc/config/rs6000/rs6000.h
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.h	2014-06-13 16:56:16.000000000 -0500
++++ gcc-4.9.1-isel/gcc/config/rs6000/rs6000.h	2014-07-17 02:25:23.949383003 -0500
+@@ -695,7 +695,7 @@
+ #define REGISTER_TARGET_PRAGMAS() do {				\
+   c_register_pragma (0, "longcall", rs6000_pragma_longcall);	\
+   targetm.target_option.pragma_parse = rs6000_pragma_target_parse; \
+-  targetm.resolve_overloaded_builtin = altivec_resolve_overloaded_builtin; \
++  targetm.resolve_overloaded_builtin = rs6000_resolve_overloaded_builtin; \
+   rs6000_target_modify_macros_ptr = rs6000_target_modify_macros; \
+ } while (0)
+ 
+@@ -2527,6 +2527,7 @@
+ #define RS6000_BTM_DFP		MASK_DFP	/* Decimal floating point.  */
+ #define RS6000_BTM_HARD_FLOAT	MASK_SOFT_FLOAT	/* Hardware floating point.  */
+ #define RS6000_BTM_LDBL128	MASK_MULTIPLE	/* 128-bit long double.  */
++#define RS6000_BTM_ISEL		MASK_ISEL	/* Target supports isel instruction */
+ 
+ #define RS6000_BTM_COMMON	(RS6000_BTM_ALTIVEC			\
+ 				 | RS6000_BTM_VSX			\
+@@ -2541,7 +2542,8 @@
+ 				 | RS6000_BTM_CELL			\
+ 				 | RS6000_BTM_DFP			\
+ 				 | RS6000_BTM_HARD_FLOAT		\
+-				 | RS6000_BTM_LDBL128)
++				 | RS6000_BTM_LDBL128			\
++				 | RS6000_BTM_ISEL)
+ 
+ /* Define builtin enum index.  */
+ 
+@@ -2698,3 +2700,41 @@
+ extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
+ extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
+ 
++/* Values for struct isel_builtin_desc.arg_flags.  */
++enum {
++  ISEL_FLAG_CMP_PTR = 0x1,
++  ISEL_FLAG_CMP_SIGNED = 0x2,
++  ISEL_FLAG_CMP_UNSIGNED = 0x4,
++  ISEL_FLAG_CMP_MASK = 0x7,
++  ISEL_FLAG_SEL_PTR = 0x10,
++  ISEL_FLAG_SEL_SIGNED = 0x20,
++  ISEL_FLAG_SEL_UNSIGNED = 0x40,
++  ISEL_FLAG_SEL_MASK = 0x70
++};
++
++struct isel_builtin_desc {
++  /* Name of this builtin.  NULL if we should construct it.  */
++  const char *name;
++
++  /* Flags for argument combinations accepted by the builtin.
++     Zero if this builtin is a generic builtin, to be resolved later.  */
++  int arg_flags;
++
++  /* The code of the builtin.  */
++  enum rs6000_builtins code;
++
++  /* rtx_code and machine_mode are not available here; use ints instead.  */
++  /* The comparison code the builtin uses.  */
++  int cmp_code;
++
++  /* The mode the builtin does comparisons in.  */
++  int cmp_mode;
++
++  /* The mode the builtin's selected arguments are in.
++     Also happens to be its result mode.  */
++  int sel_mode;
++};
++
++/* Arrays describing isel builtins.  */
++extern const struct isel_builtin_desc builtin_iselw[32];
++extern const struct isel_builtin_desc builtin_iseld[32];
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000-protos.h gcc-4.9.1-isel/gcc/config/rs6000/rs6000-protos.h
+--- gcc-4.9.1/gcc/config/rs6000/rs6000-protos.h	2014-06-11 18:49:49.000000000 -0500
++++ gcc-4.9.1-isel/gcc/config/rs6000/rs6000-protos.h	2014-07-17 02:22:16.029383000 -0500
+@@ -159,7 +159,7 @@
+ 						     unsigned int);
+ extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int,
+ 							    unsigned int);
+-extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *);
++extern tree rs6000_resolve_overloaded_builtin (location_t, tree, void *);
+ extern rtx rs6000_libcall_value (enum machine_mode);
+ extern rtx rs6000_va_arg (tree, tree);
+ extern int function_ok_for_sibcall (tree);
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c	2014-07-17 02:22:16.029383000 -0500
+@@ -0,0 +1,75 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-mcpu=e5500" } */
++
++#include "builtin-isel.h"
++
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64eq
++
++SIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  L = ISEL_BUILTIN (p, q, a, b);
++  /* Equality checks explicitly permit unsigned comparison operands.  */
++  L = ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, a, b);
++  r = ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, p, q);
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64lt
++
++SIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gt
++
++SIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64ltu
++
++UNSIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  L = ISEL_BUILTIN (p, q, a, b);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gtu
++
++UNSIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  L = ISEL_BUILTIN (p, q, a, b);
++}
++
++/* Don't use bare isel, as that'll match function names and the like.  */
++/* { dg-final { scan-assembler-times "isel " 25 } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c	2014-07-17 02:22:16.029383000 -0500
+@@ -0,0 +1,110 @@
++/* Test rejection of invalid parameter combinations in isel builtins.  */
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-mcpu=e5500" } */
++
++#include "builtin-isel.h"
++
++\f
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64eq
++
++SIGNED64_PROTO
++{
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64lt
++
++SIGNED64_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gt
++
++SIGNED64_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64ltu
++
++UNSIGNED64_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((long) x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gtu
++
++UNSIGNED64_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((long) x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel.c gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel.c	2014-07-17 02:22:16.029383000 -0500
+@@ -0,0 +1,81 @@
++/* { dg-do compile } */
++/* { dg-options "-mcpu=e500mc" } */
++
++#include "builtin-isel.h"
++
++/* We're not being clever with the preprocessor here because DejaGNU
++   will get confused.  We do try to use it to eliminate what duplication
++   we can.  */
++
++/* We check to see that the resolution permits polymorphic results.  */
++\f
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iseleq
++
++SIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  i = ISEL_BUILTIN (p, q, a, b);
++  /* Equality checks explicitly permit unsigned comparison operands.  */
++  i = ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, a, b);
++  r = ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, p, q);
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isellt
++
++SIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgt
++
++SIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselltu
++
++UNSIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  i = ISEL_BUILTIN (p, q, a, b);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgtu
++
++UNSIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  i = ISEL_BUILTIN (p, q, a, b);
++}
++
++/* Don't use bare isel, as that'll match function names and the like.  */
++/* { dg-final { scan-assembler-times "isel " 25 } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c	2014-07-17 02:22:16.030383000 -0500
+@@ -0,0 +1,117 @@
++/* Test rejection of invalid parameter combinations in isel builtins.  */
++/* { dg-do compile } */
++/* { dg-options "-mcpu=e500mc" } */
++
++#include "builtin-isel.h"
++
++/* We're not being clever with the preprocessor here because DejaGNU
++   will get confused.  We do try to use it to eliminate what duplication
++   we can.  */
++
++/* We check basic resolution of each builtin.  We also check to see that
++   the resolution permits polymorphic results.  Argument type mismatches
++   and result type mismatches are not permitted, except where noted.  */
++\f
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iseleq
++
++SIGNED_PROTO
++{
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isellt
++
++SIGNED_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgt
++
++SIGNED_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselltu
++
++UNSIGNED_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((int) x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgtu
++
++UNSIGNED_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((int) x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel.h gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel.h
+--- gcc-4.9.1/gcc/testsuite/gcc.target/powerpc/builtin-isel.h	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-isel/gcc/testsuite/gcc.target/powerpc/builtin-isel.h	2014-07-17 02:22:16.030383000 -0500
+@@ -0,0 +1,25 @@
++/* Common definitions for builtin isel testing.  */
++
++#define SIGNED_ARGLIST (int x, int y, int a, int b, void *p, void *q)
++#define UNSIGNED_ARGLIST (unsigned int x, unsigned int y, \
++			  int a, int b, void *p, void *q)
++
++#define SIGNED_PROTO void FUNCTION_NAME SIGNED_ARGLIST
++#define UNSIGNED_PROTO void FUNCTION_NAME UNSIGNED_ARGLIST
++
++#define SIGNED64_ARGLIST (long x, long y, long a, long b, void *p, void *q)
++#define UNSIGNED64_ARGLIST (unsigned long x, unsigned long y, \
++			    long a, long b, void *p, void *q)
++
++#define SIGNED64_PROTO void FUNCTION_NAME SIGNED64_ARGLIST
++#define UNSIGNED64_PROTO void FUNCTION_NAME UNSIGNED64_ARGLIST
++
++#define CONCAT2(X,Y) X##Y
++#define CONCAT(X,Y) CONCAT2(X, Y)
++#define ISEL_BUILTIN CONCAT(__builtin_, FUNCTION_NAME)
++
++volatile int i;
++volatile unsigned int u;
++volatile void *r;
++volatile long L;
++volatile unsigned long U;
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.c gcc-4.9.1-isel/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.c	2014-09-05 05:24:16.267412011 -0500
++++ gcc-4.9.1-isel/gcc/config/rs6000/rs6000.c	2014-09-05 05:35:48.430413515 -0500
+@@ -14047,6 +14047,24 @@
+       break;
+     }
+ 
++  if (TARGET_ISEL)
++    {
++      ret = rs6000_expand_isel_builtin (builtin_iselw,
++                                       ARRAY_SIZE (builtin_iselw),
++                                       exp, target, fcode);
++
++      if (ret != NULL_RTX)
++       return ret;
++    }
++  if (TARGET_ISEL64)
++    {
++      ret = rs6000_expand_isel_builtin (builtin_iseld,
++                                       ARRAY_SIZE (builtin_iseld),
++                                       exp, target, fcode);
++
++      if (ret != NULL_RTX)
++       return ret;
++    }
+   if (TARGET_ALTIVEC)
+     {
+       ret = altivec_expand_builtin (exp, target, &success);
diff --git a/recipes-devtools/gcc/gcc-4.9/0003-gcc-uclibc-locale-ctype_touplow_t.patch b/recipes-devtools/gcc/gcc-4.9/0003-gcc-uclibc-locale-ctype_touplow_t.patch
new file mode 100644
index 0000000..7098e99
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0003-gcc-uclibc-locale-ctype_touplow_t.patch
@@ -0,0 +1,87 @@
+From d2d9dd756c4356d14dd7ae003856344cb4f37985 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:40:12 +0400
+Subject: [PATCH 03/35] gcc-uclibc-locale-ctype_touplow_t
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ libstdc++-v3/config/locale/generic/c_locale.cc |    5 +++++
+ libstdc++-v3/config/locale/generic/c_locale.h  |    9 +++++++++
+ libstdc++-v3/config/os/gnu-linux/ctype_base.h  |    9 +++++++++
+ 3 files changed, 23 insertions(+)
+
+diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc
+index 0d309a5..f2f1e1f 100644
+--- a/libstdc++-v3/config/locale/generic/c_locale.cc
++++ b/libstdc++-v3/config/locale/generic/c_locale.cc
+@@ -263,5 +263,10 @@ _GLIBCXX_END_NAMESPACE_VERSION
+ #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
+ #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
+   extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
++#ifdef __UCLIBC__
++// This is because __c_locale is of type __ctype_touplow_t* which is short on uclibc. for glibc its int*
++_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPs, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPs);
++#else
+ _GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
++#endif
+ #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+diff --git a/libstdc++-v3/config/locale/generic/c_locale.h b/libstdc++-v3/config/locale/generic/c_locale.h
+index b5fd989..3da9a5d 100644
+--- a/libstdc++-v3/config/locale/generic/c_locale.h
++++ b/libstdc++-v3/config/locale/generic/c_locale.h
+@@ -40,13 +40,22 @@
+ 
+ #include <clocale>
+ 
++#ifdef __UCLIBC__
++#include <features.h>
++#include <ctype.h>
++#endif
++
+ #define _GLIBCXX_NUM_CATEGORIES 0
+ 
+ namespace std _GLIBCXX_VISIBILITY(default)
+ {
+ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+ 
++#ifdef __UCLIBC__
++  typedef __ctype_touplow_t*	__c_locale;
++#else
+   typedef int*			__c_locale;
++#endif
+ 
+   // Convert numeric value of type double and long double to string and
+   // return length of string.  If vsnprintf is available use it, otherwise
+diff --git a/libstdc++-v3/config/os/gnu-linux/ctype_base.h b/libstdc++-v3/config/os/gnu-linux/ctype_base.h
+index 2d8e978..14eb08f 100644
+--- a/libstdc++-v3/config/os/gnu-linux/ctype_base.h
++++ b/libstdc++-v3/config/os/gnu-linux/ctype_base.h
+@@ -33,6 +33,11 @@
+ 
+ // Information as gleaned from /usr/include/ctype.h
+ 
++#ifdef __UCLIBC__
++#include <features.h>
++#include <ctype.h>
++#endif
++
+ namespace std _GLIBCXX_VISIBILITY(default)
+ {
+ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+@@ -41,7 +46,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+   struct ctype_base
+   {
+     // Non-standard typedefs.
++#ifdef __UCLIBC__
++    typedef const __ctype_touplow_t*	__to_type;
++#else
+     typedef const int* 		__to_type;
++#endif
+ 
+     // NB: Offsets into ctype<char>::_M_table force a particular size
+     // on the mask type. Because of this, we don't use an enum.
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0003.gcc.widen_types-49x.patch b/recipes-devtools/gcc/gcc-4.9/0003.gcc.widen_types-49x.patch
new file mode 100644
index 0000000..53bc8ef
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0003.gcc.widen_types-49x.patch
@@ -0,0 +1,1531 @@
+# Problem Statement:
+  Locals and temporaries having signed integral types, whose address has
+  not been taken, are not volatile qualified, and having type precision
+  less than that of type long are widened to type long (with any other
+  qualifiers retained).
+
+  Changes under flag '-fwiden-types'
+
+# Owned by:
+  Edmar Wienskoski
+
+diff -Naur gcc-4.9.1/gcc/common.opt gcc-4.9.1-widen-types/gcc/common.opt
+--- gcc-4.9.1/gcc/common.opt	2014-04-07 08:27:39.000000000 -0500
++++ gcc-4.9.1-widen-types/gcc/common.opt	2014-09-13 07:20:52.659455039 -0500
+@@ -2014,6 +2014,10 @@
+ Common Joined RejectNegative Enum(tls_model) Var(flag_tls_default) Init(TLS_MODEL_GLOBAL_DYNAMIC)
+ -ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec]	Set the default thread-local storage code generation model
+ 
++fwiden-types
++Common Report Var(flag_widen_types)
++Widen signed integral variables (local, whose address has not been taken, non-volatile and having precision less than that of long) to long (retaining original qualifiers)
++
+ Enum
+ Name(tls_model) Type(enum tls_model) UnknownError(unknown TLS model %qs)
+ 
+diff -Naur gcc-4.9.1/gcc/Makefile.in gcc-4.9.1-widen-types/gcc/Makefile.in
+--- gcc-4.9.1/gcc/Makefile.in	2014-04-15 03:04:17.000000000 -0500
++++ gcc-4.9.1-widen-types/gcc/Makefile.in	2014-09-13 07:20:52.667454976 -0500
+@@ -1465,6 +1465,7 @@
+ 	vmsdbgout.o \
+ 	vtable-verify.o \
+ 	web.o \
++	widen-types.o \
+ 	xcoffout.o \
+ 	$(out_object_file) \
+ 	$(EXTRA_OBJS) \
+diff -Naur gcc-4.9.1/gcc/passes.def gcc-4.9.1-widen-types/gcc/passes.def
+--- gcc-4.9.1/gcc/passes.def	2014-01-17 11:50:10.000000000 -0600
++++ gcc-4.9.1-widen-types/gcc/passes.def	2014-09-13 07:20:52.667454976 -0500
+@@ -31,6 +31,7 @@
+     backend might produce already lowered functions that are not processed
+     by these passes.  */
+   INSERT_PASSES_AFTER (all_lowering_passes)
++  NEXT_PASS (pass_widen_types_stmts);
+   NEXT_PASS (pass_warn_unused_result);
+   NEXT_PASS (pass_diagnose_omp_blocks);
+   NEXT_PASS (pass_diagnose_tm_blocks);
+@@ -53,6 +54,7 @@
+   PUSH_INSERT_PASSES_WITHIN (pass_early_local_passes)
+       NEXT_PASS (pass_fixup_cfg);
+       NEXT_PASS (pass_init_datastructures);
++      NEXT_PASS (pass_widen_types_bbs);
+ 
+       NEXT_PASS (pass_build_ssa);
+       NEXT_PASS (pass_ubsan);
+diff -Naur gcc-4.9.1/gcc/tree-pass.h gcc-4.9.1-widen-types/gcc/tree-pass.h
+--- gcc-4.9.1/gcc/tree-pass.h	2014-01-02 16:23:26.000000000 -0600
++++ gcc-4.9.1-widen-types/gcc/tree-pass.h	2014-09-13 07:20:52.668454979 -0500
+@@ -343,6 +343,7 @@
+ extern void register_pass (opt_pass* pass, pass_positioning_ops pos,
+ 			   const char* ref_pass_name, int ref_pass_inst_number);
+ 
++extern gimple_opt_pass *make_pass_widen_types_stmts (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_asan (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_asan_O0 (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_tsan (gcc::context *ctxt);
+@@ -404,6 +405,7 @@
+ extern gimple_opt_pass *make_pass_lower_vector_ssa (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_lower_omp (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_diagnose_omp_blocks (gcc::context *ctxt);
++extern gimple_opt_pass *make_pass_widen_types_bbs (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_expand_omp (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_object_sizes (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_strlen (gcc::context *ctxt);
+diff -Naur gcc-4.9.1/gcc/widen-types.c gcc-4.9.1-widen-types/gcc/widen-types.c
+--- gcc-4.9.1/gcc/widen-types.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-widen-types/gcc/widen-types.c	2014-09-13 07:55:01.565455390 -0500
+@@ -0,0 +1,1453 @@
++/*
++ Type Widening:
++  
++ Locals and temporaries having signed integral types, whose address has
++ not been taken, are not volatile qualified, and having type precision
++ less than that of type long are widened to type long (with any other
++ qualifiers retained).
++ 
++   Copyright (C) 2011
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC 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, or (at your option) any later
++version.
++
++GCC 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 GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++
++#include "tree.h"
++#include "stor-layout.h"
++#include "basic-block.h"
++#include "tree-ssa-alias.h"
++#include "internal-fn.h"
++#include "gimple-expr.h"
++#include "is-a.h"
++#include "gimple.h"
++#include "gimple-iterator.h"
++#include "tree-cfg.h"
++#include "langhooks.h"
++#include "tree-pass.h"
++#include "diagnostic-core.h"
++#include "pointer-set.h"
++
++/* define TW_FINALIZE_STMTS to 1, if you want to run the widening
++ * pass just after gimplification - over the sequence of statements.
++ */
++#define TW_FINALIZE_STMTS 1
++
++#define TW_DEBUG 0
++#if TW_DEBUG
++
++#define TWDBG_STMT(stmt) fprintf (stderr, "%s: ", __FUNCTION__); \
++                         debug_gimple_stmt (stmt);
++
++#define TWDBG_TREE(tree)            \
++{                                   \
++  fprintf (stderr, "%s:\n", #tree); \
++  debug_tree (tree);                \
++  fprintf (stderr, "\n");           \
++}
++
++#define TWDBG_MSG(fmt) \
++fprintf (stderr, "%s: ", __FUNCTION__); \
++fprintf (stderr, fmt)
++
++#define TWDBG_MSG1(fmt, msg) \
++fprintf (stderr, "%s: ", __FUNCTION__); \
++fprintf (stderr, fmt, msg)
++
++#else
++#define TWDBG_STMT(stmt)
++#define TWDBG_TREE(tree)
++#define TWDBG_MSG(fmt)
++#define TWDBG_MSG1(fmt, msg)
++#endif
++
++#if TW_DEBUG
++static void tw_dump_candidate_list (void);
++static bool tw_debug_candidate (const void *t, void **candidacy, void *data);
++#endif
++static void tw_init (void);
++static void tw_reset (void);
++static long tw_candidate (tree node);
++static long tw_candidate_const (tree node);
++static long *tw_log_candidate (tree node);
++static long tw_candidacy_valid (tree node);
++static void tw_candidacy (tree node, long value);
++static long tw_in_candidate_list (tree node);
++static tree tw_widen_constant (tree node);
++static tree tw_widen_variable (tree node);
++#ifdef TW_FINALIZE_STMTS
++static long tw_fn_has_openmp (gimple_seq stmts);
++#endif
++static void tw_log_parms (tree fndecl);
++#ifdef TW_FINALIZE_STMTS
++static void tw_log_vars (gimple_seq stmts);
++#endif
++static void tw_log_local_decls (void);
++#ifdef TW_FINALIZE_STMTS
++static bool gate_tw_stmts (void);
++static unsigned int tw_finalize_stmts (void);
++#endif
++static bool gate_tw_bbs (void);
++static unsigned int tw_finalize_bbs (void);
++static long tw_gimple_in_seq (gimple_seq stmts, long widen);
++static long tw_gimple_in_bb (basic_block bb, long widen);
++static long tw_switch (gimple stmt, long widen);
++static long tw_gimple_stmt (gimple stmt, long widen);
++static long tw_gimple_assign (gimple stmt, long widen);
++static long tw_gimple_assign_single (gimple stmt, long widen);
++static long tw_gimple_assign_unary (gimple stmt, long widen);
++static long tw_gimple_assign_binary (gimple stmt, long widen);
++static long tw_gimple_assign_ternary (gimple stmt, long widen);
++static bool is_formatted_IO_fn (tree decl);
++static long tw_gimple_call (gimple stmt, long widen);
++static long tw_gimple_comparison (gimple stmt, long widen);
++static long tw_gimple_switch (gimple stmt, long widen);
++static long tw_gimple_return (gimple stmt, long widen);
++static long tw_gimple_asm (gimple stmt, long widen);
++static long tw_gimple_debug (gimple stmt, long widen);
++
++static struct pointer_map_t *tw_candidate_list;
++
++#if TW_DEBUG
++static void
++tw_dump_candidate_list (void)
++{
++  TWDBG_MSG ("Dumping candidate list:\n"); 
++  pointer_map_traverse (tw_candidate_list, tw_debug_candidate, NULL);
++  TWDBG_MSG ("Done dumping candidate list\n"); 
++}
++
++static
++bool tw_debug_candidate (const void *t, void **candidacy, void *data)
++{
++  debug_tree (t);
++  fprintf(stderr, "candidacy: %ld\n data (ignore): %p", *((long *) candidacy), data);
++  return true;
++}
++#endif
++
++static void
++tw_init (void)
++{
++  gcc_assert (tw_candidate_list == NULL);
++  tw_candidate_list = pointer_map_create ();
++}
++
++static void
++tw_reset (void)
++{
++  if (tw_candidate_list)
++    {
++      pointer_map_destroy (tw_candidate_list);
++      tw_candidate_list = NULL;
++    }
++}
++
++/* gcc.dg/torture/pr43879_[12].c
++ * Initialized statics should not be widened:
++ *
++ * void bar(int c)
++ * {
++ *  static int x = 1; // if widened, x gets initialized to (2^32)
++ *  if (c != x) __builtin_abort();
++ *   x--;
++ * }
++ *
++ *  int main()
++ *  {
++ *   int c = 1;
++ *   bar (1);
++ *   return 0;
++ *  }
++ *
++ * Likely, the initial value is laid out/translated to RTL way before
++ * the rest of the code is translated to GIMPLE; so when we widen the
++ * type, it's already too late.
++ */
++
++/* tw_candidate() has no way to tell if it was passed a local variable
++ * (or not) - so make sure it is passed local variables or parameters only.
++ */
++static long
++tw_candidate (tree node)
++{
++  long rv = 0;
++
++  if (!node || TREE_TYPE (node) == error_mark_node)
++    return 0;
++
++  if (node && TREE_TYPE (node) != error_mark_node &&
++      ((TREE_CODE (node) == VAR_DECL &&
++        /* See note: Initialized statics should not be widened. */
++        (!TREE_STATIC (node) || !DECL_INITIAL (node))) ||
++       TREE_CODE (node) == PARM_DECL ||
++       TREE_CODE (node) == DEBUG_EXPR_DECL) &&
++      !TYPE_VOLATILE (TREE_TYPE (node)) &&
++      !TREE_ADDRESSABLE (node) &&
++      !POINTER_TYPE_P (TREE_TYPE (node)) &&
++      INTEGRAL_TYPE_P (TREE_TYPE (node)) &&
++      !TYPE_UNSIGNED (TREE_TYPE (node))  &&
++      (TYPE_PRECISION (TREE_TYPE (node)) < TYPE_PRECISION (long_integer_type_node)))
++    rv = 1;
++  return rv;
++}
++
++static long
++tw_candidate_const (tree node)
++{
++  long rv = 0;
++
++  if (node && TREE_TYPE (node) != error_mark_node &&
++      INTEGRAL_TYPE_P (TREE_TYPE (node)) &&
++      TREE_CONSTANT (node) &&
++      (TYPE_PRECISION (TREE_TYPE (node)) < TYPE_PRECISION (long_integer_type_node)))
++    rv = 1;
++  return rv;
++}
++
++static long *
++tw_log_candidate (tree node)
++{
++  long *pval = NULL;
++
++  if (tw_candidate_list && node && TREE_TYPE (node) != error_mark_node)
++    {
++      pval = (long *) pointer_map_contains (tw_candidate_list, node);
++      if (!pval)
++        {
++          pval = (long *) pointer_map_insert (tw_candidate_list, node);
++          *pval = 1;
++          TWDBG_MSG ("Logged variable:\n");
++          TWDBG_TREE (node);
++        }
++    }
++  return pval; 
++}
++
++static long
++tw_candidacy_valid (tree node)
++{
++  long rval = 0;
++  long *pval = NULL;
++
++  if (tw_candidate_list && node && TREE_TYPE (node) != error_mark_node)
++    pval = (long *) pointer_map_contains (tw_candidate_list, node); 
++  if (pval)
++    rval = *pval ? 1 : 0;
++  return rval;
++}
++
++static void
++tw_candidacy (tree node, long value)
++{
++  long *pval;
++
++  if (tw_candidate_list && node)
++    {
++      pval = (long *) pointer_map_contains (tw_candidate_list, node);
++      if (pval)
++        {
++          *pval = value;
++#if TW_DEBUG
++          fprintf (stderr, "Setting candidacy of node:\n");
++          TWDBG_TREE (node);
++          fprintf (stderr, "to: %ld\n", value);
++#endif
++        }
++    }
++}
++
++static long
++tw_in_candidate_list (tree node)
++{
++  long *pval;
++  long rval = 0;
++
++  if (tw_candidate_list && node && TREE_TYPE (node) != error_mark_node)
++    {
++     pval = (long *) pointer_map_contains (tw_candidate_list, node);
++     rval = pval ? 1 : 0;
++    }
++  return rval;
++}
++
++static tree
++tw_widen_constant (tree node)
++{
++  if (node && tw_candidate_const (node))
++    node = build_int_cst (long_integer_type_node, TREE_INT_CST_LOW (node));
++
++  return node;
++}
++
++static tree
++tw_widen_variable (tree node)
++{
++  if (node && tw_candidacy_valid (node))
++  {
++    TWDBG_MSG ("Widening:\n");
++    TWDBG_TREE(node);
++
++    TREE_TYPE (node) = build_qualified_type (long_integer_type_node,
++                                             TYPE_QUALS (TREE_TYPE (node)));
++
++    if (TREE_CODE (node) != DEBUG_EXPR_DECL)
++      relayout_decl (node);
++  }
++  return node;
++}
++
++#ifdef TW_FINALIZE_STMTS
++static long
++tw_fn_has_openmp (gimple_seq stmts)
++{
++  gimple_stmt_iterator ittr;
++  long found_openmp = 0;
++
++  for (ittr = gsi_start (stmts); !gsi_end_p (ittr) && !found_openmp; gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++
++      switch (gimple_code (stmt))
++        {
++	case GIMPLE_BIND:
++	  found_openmp = tw_fn_has_openmp (gimple_bind_body (stmt));
++	  break;
++
++	case GIMPLE_TRY:
++	  found_openmp = tw_fn_has_openmp (gimple_try_eval (stmt));
++	  found_openmp = tw_fn_has_openmp (gimple_try_cleanup (stmt));
++	  break;
++
++	case GIMPLE_EH_FILTER:
++	  found_openmp = tw_fn_has_openmp (gimple_eh_filter_failure (stmt));
++	  break;
++
++	case GIMPLE_CATCH:
++	  found_openmp = tw_fn_has_openmp (gimple_catch_handler (stmt));
++	  break;
++
++	default:
++          switch (gimple_code (stmt))
++            {
++            CASE_GIMPLE_OMP:
++            found_openmp = 1;
++            break;
++            default:
++            break;
++            }
++	}
++    }
++  return found_openmp;  
++}
++#endif
++
++static
++void
++tw_log_parms (tree fndecl)
++{
++  tree parm;
++
++  if (!fndecl)
++    return;
++  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
++    if (tw_candidate (parm))
++      tw_log_candidate (parm);
++  return;
++}
++
++#ifdef TW_FINALIZE_STMTS
++static
++void
++tw_log_vars (gimple_seq stmts)
++{
++  gimple_stmt_iterator ittr;
++  tree vars, vindex;
++
++  if (!stmts)
++    return;
++
++  gcc_assert (tw_candidate_list != NULL);
++
++  for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++
++      switch (gimple_code (stmt))
++        {
++	case GIMPLE_BIND:
++          vars = gimple_bind_vars (stmt);
++          for (vindex = vars; vindex; vindex = DECL_CHAIN (vindex))
++            if (tw_candidate (vindex))
++              tw_log_candidate (vindex);
++          tw_log_vars (gimple_bind_body (stmt));
++	  break;
++
++	case GIMPLE_TRY:
++	  tw_log_vars (gimple_try_eval (stmt));
++	  tw_log_vars (gimple_try_cleanup (stmt));
++	  break;
++
++	case GIMPLE_EH_FILTER:
++	  tw_log_vars (gimple_eh_filter_failure (stmt));
++	  break;
++
++	case GIMPLE_CATCH:
++	  tw_log_vars (gimple_catch_handler (stmt));
++	  break;
++
++	default:
++          break;
++	}
++    }
++
++  return;
++}
++#endif
++
++static
++void
++tw_log_local_decls (void)
++{
++  tree decl;
++  unsigned ix;
++
++  FOR_EACH_LOCAL_DECL (cfun, ix, decl)
++    {
++      TWDBG_MSG ("Testing decl:\n");
++      TWDBG_TREE (decl);
++      if (tw_candidate (decl))
++        tw_log_candidate (decl);
++    }
++}
++
++/* Assumes that we have run verify_gimple_in_seq (stmts)
++ * i.e. that we have valid gimple.
++ */
++static long
++tw_gimple_in_seq (gimple_seq stmts, long widen)
++{
++  gimple_stmt_iterator ittr;
++  long iv = 0;
++
++  for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++      iv += tw_switch (stmt, widen);
++    }
++  return iv;  
++}
++
++static long
++tw_gimple_in_bb (basic_block bb, long widen)
++{
++  gimple_stmt_iterator ittr;
++  long iv = 0;
++
++#if TW_DEBUG
++  fprintf (stderr, "Dumping basic block (widen = %ld):\n", widen);
++  debug_bb (bb);
++  fprintf (stderr, "Done dumping basic block (widen = %ld)\n", widen);
++#endif
++  for (ittr = gsi_start_bb (bb); !gsi_end_p (ittr); gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++      iv += tw_switch (stmt, widen);
++    }
++  return iv;  
++}
++
++static long
++tw_switch (gimple stmt, long widen)
++{
++  long iv = 0;
++
++  switch (gimple_code (stmt))
++    {
++    case GIMPLE_BIND:
++      iv += tw_gimple_in_seq (gimple_bind_body (stmt), widen);
++      break;
++
++    case GIMPLE_TRY:
++      iv += tw_gimple_in_seq (gimple_try_eval (stmt), widen);
++      iv += tw_gimple_in_seq (gimple_try_cleanup (stmt), widen);
++      break;
++
++    case GIMPLE_EH_FILTER:
++      iv += tw_gimple_in_seq (gimple_eh_filter_failure (stmt), widen);
++      break;
++
++    case GIMPLE_CATCH:
++      iv += tw_gimple_in_seq (gimple_catch_handler (stmt), widen);
++      break;
++
++    default:
++      iv += tw_gimple_stmt (stmt, widen);
++      break;
++    }
++  return iv;  
++}
++
++/* tw_gimple_stmt () mimics verify_gimple_stmt ()
++ */
++static long
++tw_gimple_stmt (gimple stmt, long widen)
++{
++  long iv = 0;
++
++  switch (gimple_code (stmt))
++    {
++    case GIMPLE_ASSIGN:
++      iv = tw_gimple_assign (stmt, widen);
++      break;
++
++    case GIMPLE_CALL:
++      iv = tw_gimple_call (stmt, widen);
++      break;
++
++    case GIMPLE_COND:
++      iv = tw_gimple_comparison (stmt, widen);
++      break;
++
++    case GIMPLE_SWITCH:
++      iv = tw_gimple_switch (stmt, widen);
++      break;
++
++    case GIMPLE_RETURN:
++      iv = tw_gimple_return (stmt, widen);
++      break;
++
++    case GIMPLE_LABEL:
++      TWDBG_STMT(stmt);
++      break;
++
++    case GIMPLE_GOTO:
++      TWDBG_STMT(stmt);
++      break;
++
++    case GIMPLE_ASM:
++      iv = tw_gimple_asm (stmt, widen);
++      break;
++
++    /* Tuples that do not have tree operands.  */
++    case GIMPLE_NOP:
++    case GIMPLE_PREDICT:
++    case GIMPLE_RESX:
++    case GIMPLE_EH_DISPATCH:
++    case GIMPLE_EH_MUST_NOT_THROW:
++      TWDBG_STMT(stmt);
++      break;
++
++    CASE_GIMPLE_OMP:
++      TWDBG_STMT(stmt);
++      break;
++
++    case GIMPLE_DEBUG:
++      iv = tw_gimple_debug (stmt, widen);
++      break;
++
++    default:
++      gcc_unreachable ();
++    }
++  return iv;  
++}
++
++static long
++tw_gimple_assign (gimple stmt, long widen)
++{
++  long iv = 0;
++
++  switch (gimple_assign_rhs_class (stmt))
++    {
++    case GIMPLE_SINGLE_RHS:
++      iv = tw_gimple_assign_single (stmt, widen);
++      break;
++
++    case GIMPLE_UNARY_RHS:
++      iv = tw_gimple_assign_unary (stmt, widen);
++      break;
++
++    case GIMPLE_BINARY_RHS:
++      iv = tw_gimple_assign_binary (stmt, widen);
++      break;
++
++    case GIMPLE_TERNARY_RHS:
++      iv = tw_gimple_assign_ternary (stmt, widen);
++      break;
++
++    default:
++      gcc_unreachable ();
++    }
++  return iv;  
++}
++
++static long
++tw_gimple_assign_single (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  tree value;
++  long iv = 0;
++  unsigned int idx;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (TREE_CODE (rhs1) == ARRAY_REF &&
++          tw_candidacy_valid (TREE_OPERAND (rhs1, 1)))
++        {
++          /* Note that we are widening the array index, hence no 
++           * gimple_assign_set_rhs1 () */
++          tw_widen_variable (TREE_OPERAND (rhs1, 1));
++        }
++      else if (TREE_CODE (lhs) == ARRAY_REF &&
++          tw_candidacy_valid (TREE_OPERAND (lhs, 1)))
++        {
++          /* Note that we are widening the array index, hence no 
++           * gimple_assign_set_lhs () */
++          tw_widen_variable (TREE_OPERAND (lhs, 1));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs1))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_constant (rhs1));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs1))
++        return iv;
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1))
++        return iv;
++      if (TREE_CODE (lhs) == VAR_DECL && TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE &&
++          TREE_CODE (rhs1) == CONSTRUCTOR && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
++        { 
++          FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs1), idx, value)
++            {
++              if (tw_candidacy_valid (value))
++                {
++                  TWDBG_MSG ("Invalidating candidacy of constructor element:\n");
++                  TWDBG_TREE (value);
++                  tw_candidacy (value, 0);
++                  iv++;
++                }
++            }
++        }
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs1))
++        {
++          tw_candidacy (rhs1, 0);
++          iv++;
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_assign_unary (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++  
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (gimple_assign_rhs_code (stmt) == NOP_EXPR &&
++          tw_candidacy_valid (rhs1) &&
++          (TREE_TYPE (lhs) == long_unsigned_type_node ||
++           TREE_TYPE (lhs) == long_integer_type_node))
++        gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (gimple_assign_rhs_code (stmt) == NOP_EXPR &&
++          tw_candidacy_valid (rhs1) &&
++          (TREE_TYPE (lhs) == long_unsigned_type_node ||
++           TREE_TYPE (lhs) == long_integer_type_node))
++        return iv;
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs1))
++        {
++          tw_candidacy (rhs1, 0);
++          iv++;
++        }
++    }
++    return iv;
++}
++
++static long
++tw_gimple_assign_binary (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  tree rhs2 = gimple_assign_rhs2 (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++  TWDBG_TREE(rhs2);
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidate_const (rhs2))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++          gimple_assign_set_rhs2 (stmt, tw_widen_constant (rhs2));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidacy_valid (rhs2))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++          gimple_assign_set_rhs2 (stmt, tw_widen_variable (rhs2));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidate_const (rhs2))
++        return iv;
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidacy_valid (rhs2))
++        return iv;
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs1))
++        {
++          tw_candidacy (rhs1, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs2))
++        {
++          tw_candidacy (rhs2, 0);
++          iv++;
++        }
++    }
++    return iv;
++}
++
++static long
++tw_gimple_assign_ternary (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  tree rhs2 = gimple_assign_rhs2 (stmt);
++  tree rhs3 = gimple_assign_rhs3 (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++  TWDBG_TREE(rhs2);
++  TWDBG_TREE(rhs3);
++
++  if (widen)
++    {
++     TWDBG_MSG ("Widening run.\n");
++     return iv;
++    }
++
++  TWDBG_MSG ("Validating run.\n");
++  if (tw_candidacy_valid (lhs))
++    {
++      tw_candidacy (lhs, 0);
++      iv++;
++    }
++  if (tw_candidacy_valid (rhs1))
++    {
++      tw_candidacy (rhs1, 0);
++      iv++;
++    }
++  if (tw_candidacy_valid (rhs2))
++    {
++      tw_candidacy (rhs2, 0);
++      iv++;
++    }
++  if (tw_candidacy_valid (rhs3))
++    {
++      tw_candidacy (rhs3, 0);
++      iv++;
++    }
++  return iv;
++}
++
++/* Ref. WG14/N1256 Committee Draft - September 7, 2007 ISO/IEC 9899:TC3
++ * 7.19.6 Formatted input/output functions
++ * Sec. 17.19.6.[1 ... 14]
++ */
++#define IO_FN_COUNT 14
++static const char *IO_fn_names[IO_FN_COUNT] =
++{
++  "fprintf", "fscanf",
++  "printf",  "scanf",
++  "snprintf",
++  "sprintf", "sscanf",
++  "vfprintf", "vfscanf",
++  "vprintf", "vscanf",
++  "vsnprintf",
++  "vsprintf", "vsscanf",
++};
++
++static bool
++is_formatted_IO_fn (tree decl)
++{
++  const char *fn_name;
++  long i;
++
++  if (decl && TREE_CODE (decl) == FUNCTION_DECL &&
++      DECL_NAME (decl) /* TREE_CODE (decl) == IDENTIFIER_NODE */ &&
++      (fn_name = IDENTIFIER_POINTER (DECL_NAME (decl))))
++    {
++      for (i = 0; i < IO_FN_COUNT; i++)
++        if (strcmp (IO_fn_names[i], fn_name) == 0)
++          return true;
++    }
++  return false;
++}
++
++/* TODO: If you have:
++ * 
++ *  int i, n, f();
++ *
++ *  n = f();
++ *
++ *  for (i = 0; i < n; i++) 
++ *    // stuff
++ *
++ *  then (after the candidate set stabilizes) do:
++ *
++ *  int n, f();
++ *  long twl.n;
++ *
++ *  n = f();
++ *  twl.n = (long) n;
++ *
++ *  for (i = 0; i < twl.n; i++) 
++ *    // stuff
++ *
++ *  only if adding twl.n does not decrease the size of the stabilized
++ *  candidate set or "cause any other damage".
++ *
++ * This should help in benchmarks where parameters are set via function
++ * calls to prevent them from being optimized away.
++ *
++ */
++static long
++tw_gimple_call (gimple stmt, long widen)
++{
++#if TW_DEBUG
++  tree fn = gimple_call_fn (stmt);
++#endif
++  long iv = 0;
++  unsigned i;
++  tree arg;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(fn);
++  TWDBG_TREE(gimple_call_fndecl (stmt));
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      for (i = 0; i < gimple_call_num_args (stmt); i++)
++        {
++          arg = gimple_call_arg (stmt, i);
++          if (arg && tw_candidacy_valid (arg))
++            gimple_call_set_arg (stmt, i, tw_widen_variable (arg));
++        }
++      return iv;
++    }
++
++  TWDBG_MSG ("Validating run.\n");
++  if (gimple_call_lhs (stmt) && tw_candidacy_valid (gimple_call_lhs (stmt)))
++    {
++      tw_candidacy (gimple_call_lhs (stmt), 0);
++      iv++;
++    }
++  if (gimple_call_fndecl (stmt) &&
++      (is_builtin_fn (gimple_call_fndecl (stmt)) ||
++       is_formatted_IO_fn (gimple_call_fndecl (stmt))))
++    {
++      /* Certain types of function (printf-scanf family,
++       * formatted IO functions, builtin functions) ought
++       * not to have their args widened.
++       *
++       * e.g. A call to printf () such as:
++       * int x;
++       * printf ("%d", x);
++       * because, we cannot change the %d to a %ld.
++       *
++       * or e.g. in:
++       *
++       * int D.2852;
++       * int si;
++       *
++       * si = 2;
++       * __builtin_altivec_dst (&vi, si, 0);
++       * D.2852 = 0;
++       *
++       * si should not be widened.
++       *
++       * PS: We could generate code for casts to their original types in the
++       *     call, but that would slow-down performance and we do not expect
++       *     a loop index to be used in a call to a formatted IO function.
++       */
++      for (i = 0; i < gimple_call_num_args (stmt); i++)
++        {
++          arg = gimple_call_arg (stmt, i);
++          if (arg && tw_candidacy_valid (arg))
++            {
++              tw_candidacy (arg, 0);
++              iv++;
++            }
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_comparison (gimple stmt, long widen)
++{
++  tree lhs = gimple_cond_lhs (stmt);
++  tree rhs = gimple_cond_rhs (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs); 
++  TWDBG_TREE(rhs); 
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs))
++        {
++          gimple_cond_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_cond_set_rhs (stmt, tw_widen_constant (rhs));
++        }
++      else if (tw_candidate_const (lhs) && tw_candidacy_valid (rhs))
++        {
++          gimple_cond_set_lhs (stmt, tw_widen_constant (lhs));
++          gimple_cond_set_rhs (stmt, tw_widen_variable (rhs));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs))
++        {
++          gimple_cond_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_cond_set_rhs (stmt, tw_widen_variable (rhs));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs))
++        return iv;
++      if (tw_candidate_const (lhs) && tw_candidacy_valid (rhs))
++        return iv;
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs))
++        return iv;
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs))
++        {
++          tw_candidacy (rhs, 0);
++          iv++;
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_switch (gimple stmt, long widen)
++{
++  tree index = gimple_switch_index (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(index); 
++
++  if (widen && tw_candidacy_valid (index))
++    {
++      TWDBG_MSG ("Widening run.\n");
++      gimple_switch_set_index (stmt, tw_widen_variable (index));
++      return iv;
++    }
++   
++  TWDBG_MSG ("Validating run.\n");
++  return iv;
++}
++
++static long
++tw_gimple_return (gimple stmt, long widen)
++{
++  tree op = gimple_return_retval (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(op); 
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      return iv;
++    }
++
++  TWDBG_MSG ("Validating run.\n");
++  if (tw_candidacy_valid (op))
++    {
++      tw_candidacy (op, 0);
++      iv++;
++    }
++  return iv;
++}
++
++static long
++tw_gimple_asm (gimple stmt, long widen)
++{
++  long iv = 0;
++  unsigned int ninputs = gimple_asm_ninputs (stmt);
++  unsigned int noutputs = gimple_asm_noutputs (stmt);
++  unsigned int nclobbers = gimple_asm_nclobbers (stmt);
++  unsigned int i;
++
++  TWDBG_STMT(stmt);
++  TWDBG_MSG("Inputs:\n");
++  for (i = 0; i < ninputs; i++)
++    {
++      TWDBG_MSG1 ("input %d\n", i);
++      TWDBG_TREE (gimple_asm_input_op (stmt, i));
++    }
++  TWDBG_MSG("Outputs:\n");
++  for (i = 0; i < noutputs; i++)
++    {
++      TWDBG_MSG1 ("output %d\n", i);
++      TWDBG_TREE (gimple_asm_output_op (stmt, i));
++    }
++  TWDBG_MSG("Clobbers:\n");
++  for (i = 0; i < nclobbers; i++)
++    {
++      TWDBG_MSG1 ("clobber %d\n", i);
++      TWDBG_TREE (gimple_asm_clobber_op (stmt, i));
++    }
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      return iv;
++    }
++  TWDBG_MSG ("Validating run.\n");
++  for (i = 0; i < ninputs; i++)
++    {
++      if (tw_candidacy_valid (gimple_asm_input_op (stmt, i)))
++        {
++          tw_candidacy (gimple_asm_input_op (stmt, i), 0);
++          iv++;
++        }
++    }
++  for (i = 0; i < noutputs; i++)
++    {
++      if (tw_candidacy_valid (gimple_asm_output_op (stmt, i)))
++        {
++          tw_candidacy (gimple_asm_output_op (stmt, i), 0);
++          iv++;
++        }
++    }
++  for (i = 0; i < nclobbers; i++)
++    {
++      if (tw_candidacy_valid (gimple_asm_clobber_op (stmt, i)))
++        {
++          tw_candidacy (gimple_asm_clobber_op (stmt, i), 0);
++          iv++;
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_debug (gimple stmt, long widen)
++{
++  long iv = 0;
++  tree var, value;
++
++  var = gimple_debug_bind_get_var (stmt);
++  value = gimple_debug_bind_get_value (stmt);
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(var);
++  TWDBG_TREE(value);
++
++  /* TODO: What if the value is a constant? */
++ 
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (tw_candidacy_valid (var) && tw_candidacy_valid (value))
++        {
++          gimple_debug_bind_set_var (stmt, tw_widen_variable (var));
++          gimple_debug_bind_set_value (stmt, tw_widen_variable (value));
++        }
++      else if (tw_candidacy_valid (var) && tw_candidate_const (value))
++        {
++          gimple_debug_bind_set_var (stmt, tw_widen_variable (var));
++          gimple_debug_bind_set_value (stmt, tw_widen_constant (value));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++
++      if (var && !tw_in_candidate_list (var) && tw_candidate (var))
++        tw_log_candidate (var);
++      if (value && !tw_in_candidate_list (value) && tw_candidate (value))
++        tw_log_candidate (value);
++      if (tw_candidacy_valid (var) && tw_candidacy_valid (value))
++        return iv;
++      if (tw_candidacy_valid (var))
++        {
++          tw_candidacy (var, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (value))
++        {
++          tw_candidacy (value, 0);
++          iv++;
++        }
++    }
++   
++  return iv;
++}
++
++namespace {
++
++#ifdef TW_FINALIZE_STMTS
++const pass_data pass_data_widen_types_stmts =
++{
++  GIMPLE_PASS,				/* type */
++  "tw-stmts",				/* name */
++  OPTGROUP_NONE,			/* optinfo_flags */
++  true,					/* has_gate */
++  true,					/* has_execute */
++  TV_NONE,				/* tv_id */
++  PROP_gimple_any,			/* properties_required */
++  0,					/* properties_provided */
++  0,					/* properties_destroyed */
++  0,					/* todo_flags_start */
++  0,					/* todo_flags_finish */
++};
++
++class pass_widen_types_stmts : public gimple_opt_pass
++{
++public:
++  pass_widen_types_stmts (gcc::context *ctxt)
++    : gimple_opt_pass (pass_data_widen_types_stmts, ctxt)
++  {}
++
++  bool gate () { return gate_tw_stmts (); }
++  unsigned int execute () { return tw_finalize_stmts (); }
++
++}; // class pass_widen_types_stmts
++#endif
++
++const pass_data pass_data_widen_types_bbs =
++{
++  GIMPLE_PASS,				/* type */
++  "tw-bbs",				/* name */
++  OPTGROUP_NONE,			/* optinfo_flags */
++  true,					/* has_gate */
++  true,					/* has_execute */
++  TV_NONE,				/* tv_id */
++  PROP_gimple_any,			/* properties_required */
++  0,					/* properties_provided */
++  0,					/* properties_destroyed */
++  0,					/* todo_flags_start */
++  0,					/* todo_flags_finish */
++};
++
++class pass_widen_types_bbs : public gimple_opt_pass
++{
++public:
++  pass_widen_types_bbs (gcc::context *ctxt)
++    : gimple_opt_pass (pass_data_widen_types_bbs, ctxt)
++  {}
++
++  bool gate () { return gate_tw_bbs (); }
++  unsigned int execute () { return tw_finalize_bbs (); }
++
++}; // class pass_widen_types_bbs
++
++} // anon namespace
++
++/* Widen types. tw_finalize_stmts () can be run anytime immediately after
++ * gimplification but before the CFG pass (see comment * accompanying
++ * gimple_body ()).
++ *
++ * After gimplification has occurred, the emitted GIMPLE is
++ * scanned to check if these variables are only used among
++ * themselves (with the exception of being cast to unsigned long);
++ * invalidating the candidacy of any variable that is used with
++ * another outside this set (and so on recursively). The variables
++ * that remain after this process all occur in operations with other
++ * such candidate variables, (or with constants) - the type of all
++ * such residual candidate variables (and of constants that appear
++ * with these in operations) is changed to long (along with the
++ * original accompannying qualifiers on the type).
++ *
++ * void
++ * init_optimization_passes (void)
++ *
++ * p = &all_lowering_passes;
++ * NEXT_PASS (pass_widen_types_stmts);
++ * NEXT_PASS (pass_warn_unused_result);
++ */
++#ifdef TW_FINALIZE_STMTS
++static bool
++gate_tw_stmts (void)
++{
++  /* Skip if: Language not C or seen error or -fno-strict-overflow
++   * or -fno-widen-types or -fwrapv (gcc.dg/pr23518.c execution test */
++  return !(strcmp (lang_hooks.name, "GNU C") != 0 ||
++      seen_error () ||
++      !flag_strict_overflow ||
++      !flag_widen_types ||
++      flag_wrapv || flag_trapv);
++}
++
++static unsigned int
++tw_finalize_stmts ()
++{
++  long iv = 0;
++  gimple_seq stmts;
++  tree fndecl = current_function_decl; 
++
++  if (debug_info_level == DINFO_LEVEL_NONE)
++    {
++      /* PS: That we cannot call relayout_decl () on DEBUG_EXPR_DECL is an
++      * issue: Debug information is generated after lowering from tree to 
++      * GIMPLE; unless we widen before debug information is generated, the
++      * debug information will record pre-widening information - and that
++      * cannot be changed because relayout_decl () cannot be invoked on 
++      * DEBUG_EXPR_DECL. expand_debug_locations () during cfgexpand will
++      * fail gcc_assert ()'s on the DEBUG_INSN's since e.g. the modes will
++      * not agree, etc. So if we are compiling -g, we ought to run the 
++      * pass_widen_types_stmts.
++      *
++      * In short: pass_widen_types_stmts runs iff we're generating debug
++      *           information.
++      */
++      TWDBG_MSG ("Skipping: Debug level none.\n");
++      return 0;
++    }
++  gcc_assert (debug_info_level != DINFO_LEVEL_NONE);
++
++  if (!fndecl)
++    {
++      TWDBG_MSG ("Skipping: !fndecl.\n");
++      return 0;
++    }
++
++  TWDBG_MSG ("Widening function:\n");
++  TWDBG_TREE (fndecl);
++
++  stmts = gimple_body (fndecl);
++
++  if (!stmts)
++    {
++      TWDBG_MSG ("Skipping: !stmts.\n");
++      return 0;
++    }
++
++  if (tw_fn_has_openmp (stmts))
++    {
++      TWDBG_MSG ("Skipping: OpenMP stmts found.\n");
++      return 0;
++    }
++
++  /* Assume for now that we do not need to check for nested functions:
++   * (cgraph_get_node (fndecl) && cgraph_get_node (fndecl)->nested != NULL) ||
++   * TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL ||
++   * Well, turns out that a nested function is processed only if it is 
++   * actually invoked from within the function, so we are in good shape.
++   */
++
++  tw_init ();
++  tw_log_parms (fndecl);
++  tw_log_vars (stmts);
++#if TW_DEBUG
++  tw_dump_candidate_list ();
++#endif
++
++  do
++    {
++      iv = tw_gimple_in_seq (stmts, 0);
++    } while (iv);
++  tw_gimple_in_seq (stmts, 1);
++  verify_gimple_in_seq (stmts);
++
++  tw_reset ();
++
++  return 0;
++}
++#endif
++
++static bool
++gate_tw_bbs (void)
++{
++  /* Skip if: Language not C or seen error or -fno-strict-overflow
++   * or -fno-widen-types or -fwrapv (gcc.dg/pr23518.c execution test */
++  return !(strcmp (lang_hooks.name, "GNU C") != 0 ||
++      seen_error () ||
++      !flag_strict_overflow ||
++      !flag_widen_types ||
++      flag_wrapv || flag_trapv);
++}
++
++static unsigned int
++tw_finalize_bbs ()
++{
++  long iv = 0;
++  basic_block bb;
++  tree fndecl;
++
++  if (debug_info_level != DINFO_LEVEL_NONE && flag_openmp)
++    {
++      /* Cannot run this pass as the debug information has already
++       * been recorded; If we type widen now, it'll lead to assert
++       * failures during RTL expansion in expandcfg.c since the
++       * debug information would all be prewidening and would
++       * mismatch with the postwidening information for the variables
++       * that got widened (but whoose debug information was already
++       * generated). This is all because we cannot call relayout_decl ()
++       * on DEBUG_EXPR_DECL's - see note elsewhere.
++       */
++      TWDBG_MSG ("Skipping: Non-zero debug level and -fopenmp specified.\n");
++      return 0;
++    }
++
++  if (!cfun || !(fndecl = cfun->decl) || !(cfun->cfg))
++    {
++      TWDBG_MSG ("Skipping: !cfun or !fndecl or !(cfun->cfg).\n");
++      return 0;
++    }
++
++  TWDBG_MSG ("Widening function:\n");
++  TWDBG_TREE (fndecl);
++
++  /* Assume for now that we do not need to check for nested functions:
++   * (cgraph_get_node (fndecl) && cgraph_get_node (fndecl)->nested != NULL) ||
++   * TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL ||
++   * Well, turns out that a nested function is processed only if it is 
++   * actually invoked from within the function, so we are in good shape.
++   */
++
++  tw_init ();
++  tw_log_parms (fndecl);
++  tw_log_local_decls (); 
++#if TW_DEBUG
++  tw_dump_candidate_list ();
++#endif
++
++  do
++    {
++      iv = 0;
++      FOR_EACH_BB_FN (bb, cfun)
++        iv += tw_gimple_in_bb (bb, 0);
++    } while (iv);
++  FOR_EACH_BB_FN (bb, cfun)
++    tw_gimple_in_bb (bb, 1);
++  FOR_EACH_BB_FN (bb, cfun)
++    verify_gimple_in_seq (bb_seq (bb));
++
++  tw_reset ();
++
++  return 0;
++}
++
++/* Originally, we implemented type widening over the emitted GIMPLE
++ *  * sequence. Later on, we discovered that we needed to wait till
++ *   * after OpenMP expansion, so we implemented type widening over the
++ *    * CFG-BB form.
++ *     */
++#ifdef TW_FINALIZE_STMTS
++gimple_opt_pass *
++make_pass_widen_types_stmts (gcc::context *ctxt)
++{
++  return new pass_widen_types_stmts (ctxt);
++}
++#endif
++
++gimple_opt_pass *
++make_pass_widen_types_bbs (gcc::context *ctxt)
++{
++  return new pass_widen_types_bbs (ctxt);
++}
++
++/* Notes:
++ * ------
++ *
++ * Limitations to be documented:
++ * 0. -g -fopenmp not supported.
++ *
++ * Known DejaGNU failures:
++ * 0. FAIL: gcc.dg/pr38245-2.c scan-tree-dump-not optimized "link_error"
++ *    This failure is because the optimization is dependent on the type of the variable;
++ *    once the type of the variable has changed from int to long, the inequalities in
++ *    this test case no longer hold and the code cannot be optimized anymore, consequently,
++ *    the test fails.
++ *
++ * DejaGNU failures that are not due to type-widening:
++ * 0. gcc.dg/vect/vect-120.c scan-tree-dump-times vect "vectorized 1 loops" 1
++ * 1.gcc.dg/vect/vect-120.c -flto scan-tree-dump-times vect "vectorized 1 loops" 1
++ *
++ * DejaGNU PASS'es with -fwiden-types (but FAIL's in the baseline - the baseline needs
++ * to be fixed - it just so happens that the debug information happens to be better in
++ * the type-converted case. We have verified that the generated assembly is the same in
++ * either case (or has extsw eliminated)):
++ * gcc.dg/guality/pr45882.c
++ * gcc.dg/guality/pr43177.c
++ *
++ */
diff --git a/recipes-devtools/gcc/gcc-4.9/0004-uclibc-locale.patch b/recipes-devtools/gcc/gcc-4.9/0004-uclibc-locale.patch
new file mode 100644
index 0000000..49f5f33
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0004-uclibc-locale.patch
@@ -0,0 +1,2862 @@
+From a55c751a449c2cbf0b3fcc07aab1b86bf9661510 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:41:39 +0400
+Subject: [PATCH 04/35] uclibc-locale
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ libstdc++-v3/acinclude.m4                          |   37 ++
+ .../config/locale/uclibc/c++locale_internal.h      |   63 ++
+ libstdc++-v3/config/locale/uclibc/c_locale.cc      |  160 +++++
+ libstdc++-v3/config/locale/uclibc/c_locale.h       |  117 ++++
+ .../config/locale/uclibc/codecvt_members.cc        |  308 +++++++++
+ .../config/locale/uclibc/collate_members.cc        |   80 +++
+ libstdc++-v3/config/locale/uclibc/ctype_members.cc |  300 +++++++++
+ .../config/locale/uclibc/messages_members.cc       |  100 +++
+ .../config/locale/uclibc/messages_members.h        |  118 ++++
+ .../config/locale/uclibc/monetary_members.cc       |  692 ++++++++++++++++++++
+ .../config/locale/uclibc/numeric_members.cc        |  160 +++++
+ libstdc++-v3/config/locale/uclibc/time_members.cc  |  406 ++++++++++++
+ libstdc++-v3/config/locale/uclibc/time_members.h   |   68 ++
+ libstdc++-v3/configure                             |   75 +++
+ libstdc++-v3/include/c_compatibility/wchar.h       |    2 +
+ libstdc++-v3/include/c_std/cwchar                  |    2 +
+ 16 files changed, 2688 insertions(+)
+ create mode 100644 libstdc++-v3/config/locale/uclibc/c++locale_internal.h
+ create mode 100644 libstdc++-v3/config/locale/uclibc/c_locale.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/c_locale.h
+ create mode 100644 libstdc++-v3/config/locale/uclibc/codecvt_members.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/collate_members.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/ctype_members.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/messages_members.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/messages_members.h
+ create mode 100644 libstdc++-v3/config/locale/uclibc/monetary_members.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/numeric_members.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/time_members.cc
+ create mode 100644 libstdc++-v3/config/locale/uclibc/time_members.h
+
+diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
+index 0871a6a..326d7ef 100644
+--- a/libstdc++-v3/acinclude.m4
++++ b/libstdc++-v3/acinclude.m4
+@@ -1905,6 +1905,9 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
+   # Default to "generic".
+   if test $enable_clocale_flag = auto; then
+     case ${target_os} in
++      *-uclibc*)
++        enable_clocale_flag=uclibc
++        ;;
+       linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu)
+ 	enable_clocale_flag=gnu
+ 	;;
+@@ -2069,6 +2072,40 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
+       CTIME_CC=config/locale/generic/time_members.cc
+       CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
+       ;;
++    uclibc)
++      AC_MSG_RESULT(uclibc)
++
++      # Declare intention to use gettext, and add support for specific
++      # languages.
++      # For some reason, ALL_LINGUAS has to be before AM-GNU-GETTEXT
++      ALL_LINGUAS="de fr"
++
++      # Don't call AM-GNU-GETTEXT here. Instead, assume glibc.
++      AC_CHECK_PROG(check_msgfmt, msgfmt, yes, no)
++      if test x"$check_msgfmt" = x"yes" && test x"$enable_nls" = x"yes"; then
++        USE_NLS=yes
++      fi
++      # Export the build objects.
++      for ling in $ALL_LINGUAS; do \
++        glibcxx_MOFILES="$glibcxx_MOFILES $ling.mo"; \
++        glibcxx_POFILES="$glibcxx_POFILES $ling.po"; \
++      done
++      AC_SUBST(glibcxx_MOFILES)
++      AC_SUBST(glibcxx_POFILES)
++
++      CLOCALE_H=config/locale/uclibc/c_locale.h
++      CLOCALE_CC=config/locale/uclibc/c_locale.cc
++      CCODECVT_CC=config/locale/uclibc/codecvt_members.cc
++      CCOLLATE_CC=config/locale/uclibc/collate_members.cc
++      CCTYPE_CC=config/locale/uclibc/ctype_members.cc
++      CMESSAGES_H=config/locale/uclibc/messages_members.h
++      CMESSAGES_CC=config/locale/uclibc/messages_members.cc
++      CMONEY_CC=config/locale/uclibc/monetary_members.cc
++      CNUMERIC_CC=config/locale/uclibc/numeric_members.cc
++      CTIME_H=config/locale/uclibc/time_members.h
++      CTIME_CC=config/locale/uclibc/time_members.cc
++      CLOCALE_INTERNAL_H=config/locale/uclibc/c++locale_internal.h
++      ;;
+   esac
+ 
+   # This is where the testsuite looks for locale catalogs, using the
+diff --git a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
+new file mode 100644
+index 0000000..2ae3e4a
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
+@@ -0,0 +1,63 @@
++// Prototypes for GLIBC thread locale __-prefixed functions -*- C++ -*-
++
++// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++// Written by Jakub Jelinek <jakub@redhat.com>
++
++#include <bits/c++config.h>
++#include <clocale>
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning clean this up
++#endif
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++
++extern "C" __typeof(nl_langinfo_l) __nl_langinfo_l;
++extern "C" __typeof(strcoll_l) __strcoll_l;
++extern "C" __typeof(strftime_l) __strftime_l;
++extern "C" __typeof(strtod_l) __strtod_l;
++extern "C" __typeof(strtof_l) __strtof_l;
++extern "C" __typeof(strtold_l) __strtold_l;
++extern "C" __typeof(strxfrm_l) __strxfrm_l;
++extern "C" __typeof(newlocale) __newlocale;
++extern "C" __typeof(freelocale) __freelocale;
++extern "C" __typeof(duplocale) __duplocale;
++extern "C" __typeof(uselocale) __uselocale;
++
++#ifdef _GLIBCXX_USE_WCHAR_T
++extern "C" __typeof(iswctype_l) __iswctype_l;
++extern "C" __typeof(towlower_l) __towlower_l;
++extern "C" __typeof(towupper_l) __towupper_l;
++extern "C" __typeof(wcscoll_l) __wcscoll_l;
++extern "C" __typeof(wcsftime_l) __wcsftime_l;
++extern "C" __typeof(wcsxfrm_l) __wcsxfrm_l;
++extern "C" __typeof(wctype_l) __wctype_l;
++#endif
++
++#endif // GLIBC 2.3 and later
+diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.cc b/libstdc++-v3/config/locale/uclibc/c_locale.cc
+new file mode 100644
+index 0000000..5081dc1
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/c_locale.cc
+@@ -0,0 +1,160 @@
++// Wrapper for underlying C-language localization -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.8  Standard locale categories.
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#include <cerrno>  // For errno
++#include <locale>
++#include <stdexcept>
++#include <langinfo.h>
++#include <bits/c++locale_internal.h>
++
++#ifndef __UCLIBC_HAS_XLOCALE__
++#define __strtol_l(S, E, B, L)      strtol((S), (E), (B))
++#define __strtoul_l(S, E, B, L)     strtoul((S), (E), (B))
++#define __strtoll_l(S, E, B, L)     strtoll((S), (E), (B))
++#define __strtoull_l(S, E, B, L)    strtoull((S), (E), (B))
++#define __strtof_l(S, E, L)         strtof((S), (E))
++#define __strtod_l(S, E, L)         strtod((S), (E))
++#define __strtold_l(S, E, L)        strtold((S), (E))
++#warning should dummy __newlocale check for C|POSIX ?
++#define __newlocale(a, b, c)        NULL
++#define __freelocale(a)             ((void)0)
++#define __duplocale(a)              __c_locale()
++#endif
++
++namespace std
++{
++  template<>
++    void
++    __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
++		   const __c_locale& __cloc)
++    {
++      if (!(__err & ios_base::failbit))
++	{
++	  char* __sanity;
++	  errno = 0;
++	  float __f = __strtof_l(__s, &__sanity, __cloc);
++          if (__sanity != __s && errno != ERANGE)
++	    __v = __f;
++	  else
++	    __err |= ios_base::failbit;
++	}
++    }
++
++  template<>
++    void
++    __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
++		   const __c_locale& __cloc)
++    {
++      if (!(__err & ios_base::failbit))
++	{
++	  char* __sanity;
++	  errno = 0;
++	  double __d = __strtod_l(__s, &__sanity, __cloc);
++          if (__sanity != __s && errno != ERANGE)
++	    __v = __d;
++	  else
++	    __err |= ios_base::failbit;
++	}
++    }
++
++  template<>
++    void
++    __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
++		   const __c_locale& __cloc)
++    {
++      if (!(__err & ios_base::failbit))
++	{
++	  char* __sanity;
++	  errno = 0;
++	  long double __ld = __strtold_l(__s, &__sanity, __cloc);
++          if (__sanity != __s && errno != ERANGE)
++	    __v = __ld;
++	  else
++	    __err |= ios_base::failbit;
++	}
++    }
++
++  void
++  locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
++				    __c_locale __old)
++  {
++    __cloc = __newlocale(1 << LC_ALL, __s, __old);
++#ifdef __UCLIBC_HAS_XLOCALE__
++    if (!__cloc)
++      {
++	// This named locale is not supported by the underlying OS.
++	__throw_runtime_error(__N("locale::facet::_S_create_c_locale "
++			      "name not valid"));
++      }
++#endif
++  }
++
++  void
++  locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
++  {
++    if (_S_get_c_locale() != __cloc)
++      __freelocale(__cloc);
++  }
++
++  __c_locale
++  locale::facet::_S_clone_c_locale(__c_locale& __cloc)
++  { return __duplocale(__cloc); }
++} // namespace std
++
++namespace __gnu_cxx
++{
++  const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
++    {
++      "LC_CTYPE",
++      "LC_NUMERIC",
++      "LC_TIME",
++      "LC_COLLATE",
++      "LC_MONETARY",
++      "LC_MESSAGES",
++#if _GLIBCXX_NUM_CATEGORIES != 0
++      "LC_PAPER",
++      "LC_NAME",
++      "LC_ADDRESS",
++      "LC_TELEPHONE",
++      "LC_MEASUREMENT",
++      "LC_IDENTIFICATION"
++#endif
++    };
++}
++
++namespace std
++{
++  const char* const* const locale::_S_categories = __gnu_cxx::category_names;
++}  // namespace std
+diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.h b/libstdc++-v3/config/locale/uclibc/c_locale.h
+new file mode 100644
+index 0000000..da07c1f
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/c_locale.h
+@@ -0,0 +1,117 @@
++// Wrapper for underlying C-language localization -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.8  Standard locale categories.
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#ifndef _C_LOCALE_H
++#define _C_LOCALE_H 1
++
++#pragma GCC system_header
++
++#include <cstring>              // get std::strlen
++#include <cstdio>               // get std::snprintf or std::sprintf
++#include <clocale>
++#include <langinfo.h>		// For codecvt
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning fix this
++#endif
++#ifdef __UCLIBC_HAS_LOCALE__
++#include <iconv.h>		// For codecvt using iconv, iconv_t
++#endif
++#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
++#include <libintl.h> 		// For messages
++#endif
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning what is _GLIBCXX_C_LOCALE_GNU for
++#endif
++#define _GLIBCXX_C_LOCALE_GNU 1
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning fix categories
++#endif
++// #define _GLIBCXX_NUM_CATEGORIES 6
++#define _GLIBCXX_NUM_CATEGORIES 0
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++namespace __gnu_cxx
++{
++  extern "C" __typeof(uselocale) __uselocale;
++}
++#endif
++
++namespace std
++{
++#ifdef __UCLIBC_HAS_XLOCALE__
++  typedef __locale_t		__c_locale;
++#else
++  typedef int*			__c_locale;
++#endif
++
++  // Convert numeric value of type _Tv to string and return length of
++  // string.  If snprintf is available use it, otherwise fall back to
++  // the unsafe sprintf which, in general, can be dangerous and should
++  // be avoided.
++  template<typename _Tv>
++    int
++    __convert_from_v(char* __out,
++		     const int __size __attribute__ ((__unused__)),
++		     const char* __fmt,
++#ifdef __UCLIBC_HAS_XCLOCALE__
++		     _Tv __v, const __c_locale& __cloc, int __prec)
++    {
++      __c_locale __old = __gnu_cxx::__uselocale(__cloc);
++#else
++		     _Tv __v, const __c_locale&, int __prec)
++    {
++# ifdef __UCLIBC_HAS_LOCALE__
++      char* __old = std::setlocale(LC_ALL, NULL);
++      char* __sav = new char[std::strlen(__old) + 1];
++      std::strcpy(__sav, __old);
++      std::setlocale(LC_ALL, "C");
++# endif
++#endif
++
++      const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
++
++#ifdef __UCLIBC_HAS_XCLOCALE__
++      __gnu_cxx::__uselocale(__old);
++#elif defined __UCLIBC_HAS_LOCALE__
++      std::setlocale(LC_ALL, __sav);
++      delete [] __sav;
++#endif
++      return __ret;
++    }
++}
++
++#endif
+diff --git a/libstdc++-v3/config/locale/uclibc/codecvt_members.cc b/libstdc++-v3/config/locale/uclibc/codecvt_members.cc
+new file mode 100644
+index 0000000..64aa962
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/codecvt_members.cc
+@@ -0,0 +1,308 @@
++// std::codecvt implementation details, GNU version -*- C++ -*-
++
++// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.1.5 - Template class codecvt
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#include <locale>
++#include <cstdlib>  // For MB_CUR_MAX
++#include <climits>  // For MB_LEN_MAX
++#include <bits/c++locale_internal.h>
++
++namespace std
++{
++  // Specializations.
++#ifdef _GLIBCXX_USE_WCHAR_T
++  codecvt_base::result
++  codecvt<wchar_t, char, mbstate_t>::
++  do_out(state_type& __state, const intern_type* __from,
++	 const intern_type* __from_end, const intern_type*& __from_next,
++	 extern_type* __to, extern_type* __to_end,
++	 extern_type*& __to_next) const
++  {
++    result __ret = ok;
++    state_type __tmp_state(__state);
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_codecvt);
++#endif
++
++    // wcsnrtombs is *very* fast but stops if encounters NUL characters:
++    // in case we fall back to wcrtomb and then continue, in a loop.
++    // NB: wcsnrtombs is a GNU extension
++    for (__from_next = __from, __to_next = __to;
++	 __from_next < __from_end && __to_next < __to_end
++	 && __ret == ok;)
++      {
++	const intern_type* __from_chunk_end = wmemchr(__from_next, L'\0',
++						      __from_end - __from_next);
++	if (!__from_chunk_end)
++	  __from_chunk_end = __from_end;
++
++	__from = __from_next;
++	const size_t __conv = wcsnrtombs(__to_next, &__from_next,
++					 __from_chunk_end - __from_next,
++					 __to_end - __to_next, &__state);
++	if (__conv == static_cast<size_t>(-1))
++	  {
++	    // In case of error, in order to stop at the exact place we
++	    // have to start again from the beginning with a series of
++	    // wcrtomb.
++	    for (; __from < __from_next; ++__from)
++	      __to_next += wcrtomb(__to_next, *__from, &__tmp_state);
++	    __state = __tmp_state;
++	    __ret = error;
++	  }
++	else if (__from_next && __from_next < __from_chunk_end)
++	  {
++	    __to_next += __conv;
++	    __ret = partial;
++	  }
++	else
++	  {
++	    __from_next = __from_chunk_end;
++	    __to_next += __conv;
++	  }
++
++	if (__from_next < __from_end && __ret == ok)
++	  {
++	    extern_type __buf[MB_LEN_MAX];
++	    __tmp_state = __state;
++	    const size_t __conv = wcrtomb(__buf, *__from_next, &__tmp_state);
++	    if (__conv > static_cast<size_t>(__to_end - __to_next))
++	      __ret = partial;
++	    else
++	      {
++		memcpy(__to_next, __buf, __conv);
++		__state = __tmp_state;
++		__to_next += __conv;
++		++__from_next;
++	      }
++	  }
++      }
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++
++    return __ret;
++  }
++
++  codecvt_base::result
++  codecvt<wchar_t, char, mbstate_t>::
++  do_in(state_type& __state, const extern_type* __from,
++	const extern_type* __from_end, const extern_type*& __from_next,
++	intern_type* __to, intern_type* __to_end,
++	intern_type*& __to_next) const
++  {
++    result __ret = ok;
++    state_type __tmp_state(__state);
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_codecvt);
++#endif
++
++    // mbsnrtowcs is *very* fast but stops if encounters NUL characters:
++    // in case we store a L'\0' and then continue, in a loop.
++    // NB: mbsnrtowcs is a GNU extension
++    for (__from_next = __from, __to_next = __to;
++	 __from_next < __from_end && __to_next < __to_end
++	 && __ret == ok;)
++      {
++	const extern_type* __from_chunk_end;
++	__from_chunk_end = static_cast<const extern_type*>(memchr(__from_next, '\0',
++								  __from_end
++								  - __from_next));
++	if (!__from_chunk_end)
++	  __from_chunk_end = __from_end;
++
++	__from = __from_next;
++	size_t __conv = mbsnrtowcs(__to_next, &__from_next,
++				   __from_chunk_end - __from_next,
++				   __to_end - __to_next, &__state);
++	if (__conv == static_cast<size_t>(-1))
++	  {
++	    // In case of error, in order to stop at the exact place we
++	    // have to start again from the beginning with a series of
++	    // mbrtowc.
++	    for (;; ++__to_next, __from += __conv)
++	      {
++		__conv = mbrtowc(__to_next, __from, __from_end - __from,
++				 &__tmp_state);
++		if (__conv == static_cast<size_t>(-1)
++		    || __conv == static_cast<size_t>(-2))
++		  break;
++	      }
++	    __from_next = __from;
++	    __state = __tmp_state;
++	    __ret = error;
++	  }
++	else if (__from_next && __from_next < __from_chunk_end)
++	  {
++	    // It is unclear what to return in this case (see DR 382).
++	    __to_next += __conv;
++	    __ret = partial;
++	  }
++	else
++	  {
++	    __from_next = __from_chunk_end;
++	    __to_next += __conv;
++	  }
++
++	if (__from_next < __from_end && __ret == ok)
++	  {
++	    if (__to_next < __to_end)
++	      {
++		// XXX Probably wrong for stateful encodings
++		__tmp_state = __state;
++		++__from_next;
++		*__to_next++ = L'\0';
++	      }
++	    else
++	      __ret = partial;
++	  }
++      }
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++
++    return __ret;
++  }
++
++  int
++  codecvt<wchar_t, char, mbstate_t>::
++  do_encoding() const throw()
++  {
++    // XXX This implementation assumes that the encoding is
++    // stateless and is either single-byte or variable-width.
++    int __ret = 0;
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_codecvt);
++#endif
++    if (MB_CUR_MAX == 1)
++      __ret = 1;
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++    return __ret;
++  }
++
++  int
++  codecvt<wchar_t, char, mbstate_t>::
++  do_max_length() const throw()
++  {
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_codecvt);
++#endif
++    // XXX Probably wrong for stateful encodings.
++    int __ret = MB_CUR_MAX;
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++    return __ret;
++  }
++
++  int
++  codecvt<wchar_t, char, mbstate_t>::
++  do_length(state_type& __state, const extern_type* __from,
++	    const extern_type* __end, size_t __max) const
++  {
++    int __ret = 0;
++    state_type __tmp_state(__state);
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_codecvt);
++#endif
++
++    // mbsnrtowcs is *very* fast but stops if encounters NUL characters:
++    // in case we advance past it and then continue, in a loop.
++    // NB: mbsnrtowcs is a GNU extension
++
++    // A dummy internal buffer is needed in order for mbsnrtocws to consider
++    // its fourth parameter (it wouldn't with NULL as first parameter).
++    wchar_t* __to = static_cast<wchar_t*>(__builtin_alloca(sizeof(wchar_t)
++							   * __max));
++    while (__from < __end && __max)
++      {
++	const extern_type* __from_chunk_end;
++	__from_chunk_end = static_cast<const extern_type*>(memchr(__from, '\0',
++								  __end
++								  - __from));
++	if (!__from_chunk_end)
++	  __from_chunk_end = __end;
++
++	const extern_type* __tmp_from = __from;
++	size_t __conv = mbsnrtowcs(__to, &__from,
++				   __from_chunk_end - __from,
++				   __max, &__state);
++	if (__conv == static_cast<size_t>(-1))
++	  {
++	    // In case of error, in order to stop at the exact place we
++	    // have to start again from the beginning with a series of
++	    // mbrtowc.
++	    for (__from = __tmp_from;; __from += __conv)
++	      {
++		__conv = mbrtowc(NULL, __from, __end - __from,
++				 &__tmp_state);
++		if (__conv == static_cast<size_t>(-1)
++		    || __conv == static_cast<size_t>(-2))
++		  break;
++	      }
++	    __state = __tmp_state;
++	    __ret += __from - __tmp_from;
++	    break;
++	  }
++	if (!__from)
++	  __from = __from_chunk_end;
++
++	__ret += __from - __tmp_from;
++	__max -= __conv;
++
++	if (__from < __end && __max)
++	  {
++	    // XXX Probably wrong for stateful encodings
++	    __tmp_state = __state;
++	    ++__from;
++	    ++__ret;
++	    --__max;
++	  }
++      }
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++
++    return __ret;
++  }
++#endif
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/collate_members.cc b/libstdc++-v3/config/locale/uclibc/collate_members.cc
+new file mode 100644
+index 0000000..c2664a7
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/collate_members.cc
+@@ -0,0 +1,80 @@
++// std::collate implementation details, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.4.1.2  collate virtual functions
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#include <locale>
++#include <bits/c++locale_internal.h>
++
++#ifndef __UCLIBC_HAS_XLOCALE__
++#define __strcoll_l(S1, S2, L)      strcoll((S1), (S2))
++#define __strxfrm_l(S1, S2, N, L)   strxfrm((S1), (S2), (N))
++#define __wcscoll_l(S1, S2, L)      wcscoll((S1), (S2))
++#define __wcsxfrm_l(S1, S2, N, L)   wcsxfrm((S1), (S2), (N))
++#endif
++
++namespace std
++{
++  // These are basically extensions to char_traits, and perhaps should
++  // be put there instead of here.
++  template<>
++    int
++    collate<char>::_M_compare(const char* __one, const char* __two) const
++    {
++      int __cmp = __strcoll_l(__one, __two, _M_c_locale_collate);
++      return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
++    }
++
++  template<>
++    size_t
++    collate<char>::_M_transform(char* __to, const char* __from,
++				size_t __n) const
++    { return __strxfrm_l(__to, __from, __n, _M_c_locale_collate); }
++
++#ifdef _GLIBCXX_USE_WCHAR_T
++  template<>
++    int
++    collate<wchar_t>::_M_compare(const wchar_t* __one,
++				 const wchar_t* __two) const
++    {
++      int __cmp = __wcscoll_l(__one, __two, _M_c_locale_collate);
++      return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0);
++    }
++
++  template<>
++    size_t
++    collate<wchar_t>::_M_transform(wchar_t* __to, const wchar_t* __from,
++				   size_t __n) const
++    { return __wcsxfrm_l(__to, __from, __n, _M_c_locale_collate); }
++#endif
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/ctype_members.cc b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
+new file mode 100644
+index 0000000..7294e3a
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
+@@ -0,0 +1,300 @@
++// std::ctype implementation details, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.1.1.2  ctype virtual functions.
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#define _LIBC
++#include <locale>
++#undef _LIBC
++#include <bits/c++locale_internal.h>
++
++#ifndef __UCLIBC_HAS_XLOCALE__
++#define __wctype_l(S, L)           wctype((S))
++#define __towupper_l(C, L)         towupper((C))
++#define __towlower_l(C, L)         towlower((C))
++#define __iswctype_l(C, M, L)      iswctype((C), (M))
++#endif
++
++namespace std
++{
++  // NB: The other ctype<char> specializations are in src/locale.cc and
++  // various /config/os/* files.
++  template<>
++    ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
++    : ctype<char>(0, false, __refs)
++    {
++      if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
++	{
++	  this->_S_destroy_c_locale(this->_M_c_locale_ctype);
++	  this->_S_create_c_locale(this->_M_c_locale_ctype, __s);
++#ifdef __UCLIBC_HAS_XLOCALE__
++	  this->_M_toupper = this->_M_c_locale_ctype->__ctype_toupper;
++	  this->_M_tolower = this->_M_c_locale_ctype->__ctype_tolower;
++	  this->_M_table = this->_M_c_locale_ctype->__ctype_b;
++#endif
++	}
++    }
++
++#ifdef _GLIBCXX_USE_WCHAR_T
++  ctype<wchar_t>::__wmask_type
++  ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const
++  {
++    __wmask_type __ret;
++    switch (__m)
++      {
++      case space:
++	__ret = __wctype_l("space", _M_c_locale_ctype);
++	break;
++      case print:
++	__ret = __wctype_l("print", _M_c_locale_ctype);
++	break;
++      case cntrl:
++	__ret = __wctype_l("cntrl", _M_c_locale_ctype);
++	break;
++      case upper:
++	__ret = __wctype_l("upper", _M_c_locale_ctype);
++	break;
++      case lower:
++	__ret = __wctype_l("lower", _M_c_locale_ctype);
++	break;
++      case alpha:
++	__ret = __wctype_l("alpha", _M_c_locale_ctype);
++	break;
++      case digit:
++	__ret = __wctype_l("digit", _M_c_locale_ctype);
++	break;
++      case punct:
++	__ret = __wctype_l("punct", _M_c_locale_ctype);
++	break;
++      case xdigit:
++	__ret = __wctype_l("xdigit", _M_c_locale_ctype);
++	break;
++      case alnum:
++	__ret = __wctype_l("alnum", _M_c_locale_ctype);
++	break;
++      case graph:
++	__ret = __wctype_l("graph", _M_c_locale_ctype);
++	break;
++      default:
++	__ret = __wmask_type();
++      }
++    return __ret;
++  }
++
++  wchar_t
++  ctype<wchar_t>::do_toupper(wchar_t __c) const
++  { return __towupper_l(__c, _M_c_locale_ctype); }
++
++  const wchar_t*
++  ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const
++  {
++    while (__lo < __hi)
++      {
++        *__lo = __towupper_l(*__lo, _M_c_locale_ctype);
++        ++__lo;
++      }
++    return __hi;
++  }
++
++  wchar_t
++  ctype<wchar_t>::do_tolower(wchar_t __c) const
++  { return __towlower_l(__c, _M_c_locale_ctype); }
++
++  const wchar_t*
++  ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const
++  {
++    while (__lo < __hi)
++      {
++        *__lo = __towlower_l(*__lo, _M_c_locale_ctype);
++        ++__lo;
++      }
++    return __hi;
++  }
++
++  bool
++  ctype<wchar_t>::
++  do_is(mask __m, wchar_t __c) const
++  {
++    // Highest bitmask in ctype_base == 10, but extra in "C"
++    // library for blank.
++    bool __ret = false;
++    const size_t __bitmasksize = 11;
++    for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
++      if (__m & _M_bit[__bitcur]
++	  && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
++	{
++	  __ret = true;
++	  break;
++	}
++    return __ret;
++  }
++
++  const wchar_t*
++  ctype<wchar_t>::
++  do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const
++  {
++    for (; __lo < __hi; ++__vec, ++__lo)
++      {
++	// Highest bitmask in ctype_base == 10, but extra in "C"
++	// library for blank.
++	const size_t __bitmasksize = 11;
++	mask __m = 0;
++	for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
++	  if (__iswctype_l(*__lo, _M_wmask[__bitcur], _M_c_locale_ctype))
++	    __m |= _M_bit[__bitcur];
++	*__vec = __m;
++      }
++    return __hi;
++  }
++
++  const wchar_t*
++  ctype<wchar_t>::
++  do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const
++  {
++    while (__lo < __hi && !this->do_is(__m, *__lo))
++      ++__lo;
++    return __lo;
++  }
++
++  const wchar_t*
++  ctype<wchar_t>::
++  do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
++  {
++    while (__lo < __hi && this->do_is(__m, *__lo) != 0)
++      ++__lo;
++    return __lo;
++  }
++
++  wchar_t
++  ctype<wchar_t>::
++  do_widen(char __c) const
++  { return _M_widen[static_cast<unsigned char>(__c)]; }
++
++  const char*
++  ctype<wchar_t>::
++  do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
++  {
++    while (__lo < __hi)
++      {
++	*__dest = _M_widen[static_cast<unsigned char>(*__lo)];
++	++__lo;
++	++__dest;
++      }
++    return __hi;
++  }
++
++  char
++  ctype<wchar_t>::
++  do_narrow(wchar_t __wc, char __dfault) const
++  {
++    if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
++      return _M_narrow[__wc];
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_ctype);
++#endif
++    const int __c = wctob(__wc);
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++    return (__c == EOF ? __dfault : static_cast<char>(__c));
++  }
++
++  const wchar_t*
++  ctype<wchar_t>::
++  do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault,
++	    char* __dest) const
++  {
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_ctype);
++#endif
++    if (_M_narrow_ok)
++      while (__lo < __hi)
++	{
++	  if (*__lo >= 0 && *__lo < 128)
++	    *__dest = _M_narrow[*__lo];
++	  else
++	    {
++	      const int __c = wctob(*__lo);
++	      *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
++	    }
++	  ++__lo;
++	  ++__dest;
++	}
++    else
++      while (__lo < __hi)
++	{
++	  const int __c = wctob(*__lo);
++	  *__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
++	  ++__lo;
++	  ++__dest;
++	}
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++    return __hi;
++  }
++
++  void
++  ctype<wchar_t>::_M_initialize_ctype()
++  {
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __c_locale __old = __uselocale(_M_c_locale_ctype);
++#endif
++    wint_t __i;
++    for (__i = 0; __i < 128; ++__i)
++      {
++	const int __c = wctob(__i);
++	if (__c == EOF)
++	  break;
++	else
++	  _M_narrow[__i] = static_cast<char>(__c);
++      }
++    if (__i == 128)
++      _M_narrow_ok = true;
++    else
++      _M_narrow_ok = false;
++    for (size_t __j = 0;
++	 __j < sizeof(_M_widen) / sizeof(wint_t); ++__j)
++      _M_widen[__j] = btowc(__j);
++
++    for (size_t __k = 0; __k <= 11; ++__k)
++      {
++	_M_bit[__k] = static_cast<mask>(_ISbit(__k));
++	_M_wmask[__k] = _M_convert_to_wmask(_M_bit[__k]);
++      }
++#ifdef __UCLIBC_HAS_XLOCALE__
++    __uselocale(__old);
++#endif
++  }
++#endif //  _GLIBCXX_USE_WCHAR_T
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.cc b/libstdc++-v3/config/locale/uclibc/messages_members.cc
+new file mode 100644
+index 0000000..13594d9
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/messages_members.cc
+@@ -0,0 +1,100 @@
++// std::messages implementation details, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.7.1.2  messages virtual functions
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#include <locale>
++#include <bits/c++locale_internal.h>
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning fix gettext stuff
++#endif
++#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
++extern "C" char *__dcgettext(const char *domainname,
++			     const char *msgid, int category);
++#undef gettext
++#define gettext(msgid) __dcgettext(NULL, msgid, LC_MESSAGES)
++#else
++#undef gettext
++#define gettext(msgid) (msgid)
++#endif
++
++namespace std
++{
++  // Specializations.
++  template<>
++    string
++    messages<char>::do_get(catalog, int, int, const string& __dfault) const
++    {
++#ifdef __UCLIBC_HAS_XLOCALE__
++      __c_locale __old = __uselocale(_M_c_locale_messages);
++      const char* __msg = const_cast<const char*>(gettext(__dfault.c_str()));
++      __uselocale(__old);
++      return string(__msg);
++#elif defined __UCLIBC_HAS_LOCALE__
++      char* __old = strdup(setlocale(LC_ALL, NULL));
++      setlocale(LC_ALL, _M_name_messages);
++      const char* __msg = gettext(__dfault.c_str());
++      setlocale(LC_ALL, __old);
++      free(__old);
++      return string(__msg);
++#else
++      const char* __msg = gettext(__dfault.c_str());
++      return string(__msg);
++#endif
++    }
++
++#ifdef _GLIBCXX_USE_WCHAR_T
++  template<>
++    wstring
++    messages<wchar_t>::do_get(catalog, int, int, const wstring& __dfault) const
++    {
++# ifdef __UCLIBC_HAS_XLOCALE__
++      __c_locale __old = __uselocale(_M_c_locale_messages);
++      char* __msg = gettext(_M_convert_to_char(__dfault));
++      __uselocale(__old);
++      return _M_convert_from_char(__msg);
++# elif defined __UCLIBC_HAS_LOCALE__
++      char* __old = strdup(setlocale(LC_ALL, NULL));
++      setlocale(LC_ALL, _M_name_messages);
++      char* __msg = gettext(_M_convert_to_char(__dfault));
++      setlocale(LC_ALL, __old);
++      free(__old);
++      return _M_convert_from_char(__msg);
++# else
++      char* __msg = gettext(_M_convert_to_char(__dfault));
++      return _M_convert_from_char(__msg);
++# endif
++    }
++#endif
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.h b/libstdc++-v3/config/locale/uclibc/messages_members.h
+new file mode 100644
+index 0000000..1424078
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/messages_members.h
+@@ -0,0 +1,118 @@
++// std::messages implementation details, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.7.1.2  messages functions
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning fix prototypes for *textdomain funcs
++#endif
++#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
++extern "C" char *__textdomain(const char *domainname);
++extern "C" char *__bindtextdomain(const char *domainname,
++				  const char *dirname);
++#else
++#undef __textdomain
++#undef __bindtextdomain
++#define __textdomain(D)           ((void)0)
++#define __bindtextdomain(D,P)     ((void)0)
++#endif
++
++  // Non-virtual member functions.
++  template<typename _CharT>
++     messages<_CharT>::messages(size_t __refs)
++     : facet(__refs), _M_c_locale_messages(_S_get_c_locale()),
++     _M_name_messages(_S_get_c_name())
++     { }
++
++  template<typename _CharT>
++     messages<_CharT>::messages(__c_locale __cloc, const char* __s,
++				size_t __refs)
++     : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)),
++     _M_name_messages(__s)
++     {
++       char* __tmp = new char[std::strlen(__s) + 1];
++       std::strcpy(__tmp, __s);
++       _M_name_messages = __tmp;
++     }
++
++  template<typename _CharT>
++    typename messages<_CharT>::catalog
++    messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc,
++			   const char* __dir) const
++    {
++      __bindtextdomain(__s.c_str(), __dir);
++      return this->do_open(__s, __loc);
++    }
++
++  // Virtual member functions.
++  template<typename _CharT>
++    messages<_CharT>::~messages()
++    {
++      if (_M_name_messages != _S_get_c_name())
++	delete [] _M_name_messages;
++      _S_destroy_c_locale(_M_c_locale_messages);
++    }
++
++  template<typename _CharT>
++    typename messages<_CharT>::catalog
++    messages<_CharT>::do_open(const basic_string<char>& __s,
++			      const locale&) const
++    {
++      // No error checking is done, assume the catalog exists and can
++      // be used.
++      __textdomain(__s.c_str());
++      return 0;
++    }
++
++  template<typename _CharT>
++    void
++    messages<_CharT>::do_close(catalog) const
++    { }
++
++   // messages_byname
++   template<typename _CharT>
++     messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs)
++     : messages<_CharT>(__refs)
++     {
++       if (this->_M_name_messages != locale::facet::_S_get_c_name())
++	 delete [] this->_M_name_messages;
++       char* __tmp = new char[std::strlen(__s) + 1];
++       std::strcpy(__tmp, __s);
++       this->_M_name_messages = __tmp;
++
++       if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
++	 {
++	   this->_S_destroy_c_locale(this->_M_c_locale_messages);
++	   this->_S_create_c_locale(this->_M_c_locale_messages, __s);
++	 }
++     }
+diff --git a/libstdc++-v3/config/locale/uclibc/monetary_members.cc b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+new file mode 100644
+index 0000000..aa52731
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+@@ -0,0 +1,692 @@
++// std::moneypunct implementation details, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.6.3.2  moneypunct virtual functions
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#define _LIBC
++#include <locale>
++#undef _LIBC
++#include <bits/c++locale_internal.h>
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning optimize this for uclibc
++#warning tailor for stub locale support
++#endif
++
++#ifndef __UCLIBC_HAS_XLOCALE__
++#define __nl_langinfo_l(N, L)         nl_langinfo((N))
++#endif
++
++namespace std
++{
++  // Construct and return valid pattern consisting of some combination of:
++  // space none symbol sign value
++  money_base::pattern
++  money_base::_S_construct_pattern(char __precedes, char __space, char __posn)
++  {
++    pattern __ret;
++
++    // This insanely complicated routine attempts to construct a valid
++    // pattern for use with monyepunct. A couple of invariants:
++
++    // if (__precedes) symbol -> value
++    // else value -> symbol
++
++    // if (__space) space
++    // else none
++
++    // none == never first
++    // space never first or last
++
++    // Any elegant implementations of this are welcome.
++    switch (__posn)
++      {
++      case 0:
++      case 1:
++	// 1 The sign precedes the value and symbol.
++	__ret.field[0] = sign;
++	if (__space)
++	  {
++	    // Pattern starts with sign.
++	    if (__precedes)
++	      {
++		__ret.field[1] = symbol;
++		__ret.field[3] = value;
++	      }
++	    else
++	      {
++		__ret.field[1] = value;
++		__ret.field[3] = symbol;
++	      }
++	    __ret.field[2] = space;
++	  }
++	else
++	  {
++	    // Pattern starts with sign and ends with none.
++	    if (__precedes)
++	      {
++		__ret.field[1] = symbol;
++		__ret.field[2] = value;
++	      }
++	    else
++	      {
++		__ret.field[1] = value;
++		__ret.field[2] = symbol;
++	      }
++	    __ret.field[3] = none;
++	  }
++	break;
++      case 2:
++	// 2 The sign follows the value and symbol.
++	if (__space)
++	  {
++	    // Pattern either ends with sign.
++	    if (__precedes)
++	      {
++		__ret.field[0] = symbol;
++		__ret.field[2] = value;
++	      }
++	    else
++	      {
++		__ret.field[0] = value;
++		__ret.field[2] = symbol;
++	      }
++	    __ret.field[1] = space;
++	    __ret.field[3] = sign;
++	  }
++	else
++	  {
++	    // Pattern ends with sign then none.
++	    if (__precedes)
++	      {
++		__ret.field[0] = symbol;
++		__ret.field[1] = value;
++	      }
++	    else
++	      {
++		__ret.field[0] = value;
++		__ret.field[1] = symbol;
++	      }
++	    __ret.field[2] = sign;
++	    __ret.field[3] = none;
++	  }
++	break;
++      case 3:
++	// 3 The sign immediately precedes the symbol.
++	if (__precedes)
++	  {
++	    __ret.field[0] = sign;
++	    __ret.field[1] = symbol;
++	    if (__space)
++	      {
++		__ret.field[2] = space;
++		__ret.field[3] = value;
++	      }
++	    else
++	      {
++		__ret.field[2] = value;
++		__ret.field[3] = none;
++	      }
++	  }
++	else
++	  {
++	    __ret.field[0] = value;
++	    if (__space)
++	      {
++		__ret.field[1] = space;
++		__ret.field[2] = sign;
++		__ret.field[3] = symbol;
++	      }
++	    else
++	      {
++		__ret.field[1] = sign;
++		__ret.field[2] = symbol;
++		__ret.field[3] = none;
++	      }
++	  }
++	break;
++      case 4:
++	// 4 The sign immediately follows the symbol.
++	if (__precedes)
++	  {
++	    __ret.field[0] = symbol;
++	    __ret.field[1] = sign;
++	    if (__space)
++	      {
++		__ret.field[2] = space;
++		__ret.field[3] = value;
++	      }
++	    else
++	      {
++		__ret.field[2] = value;
++		__ret.field[3] = none;
++	      }
++	  }
++	else
++	  {
++	    __ret.field[0] = value;
++	    if (__space)
++	      {
++		__ret.field[1] = space;
++		__ret.field[2] = symbol;
++		__ret.field[3] = sign;
++	      }
++	    else
++	      {
++		__ret.field[1] = symbol;
++		__ret.field[2] = sign;
++		__ret.field[3] = none;
++	      }
++	  }
++	break;
++      default:
++	;
++      }
++    return __ret;
++  }
++
++  template<>
++    void
++    moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
++						     const char*)
++    {
++      if (!_M_data)
++	_M_data = new __moneypunct_cache<char, true>;
++
++      if (!__cloc)
++	{
++	  // "C" locale
++	  _M_data->_M_decimal_point = '.';
++	  _M_data->_M_thousands_sep = ',';
++	  _M_data->_M_grouping = "";
++	  _M_data->_M_grouping_size = 0;
++	  _M_data->_M_curr_symbol = "";
++	  _M_data->_M_curr_symbol_size = 0;
++	  _M_data->_M_positive_sign = "";
++	  _M_data->_M_positive_sign_size = 0;
++	  _M_data->_M_negative_sign = "";
++	  _M_data->_M_negative_sign_size = 0;
++	  _M_data->_M_frac_digits = 0;
++	  _M_data->_M_pos_format = money_base::_S_default_pattern;
++	  _M_data->_M_neg_format = money_base::_S_default_pattern;
++
++	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
++	    _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
++	}
++      else
++	{
++	  // Named locale.
++	  _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT,
++							__cloc));
++	  _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP,
++							__cloc));
++	  _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
++	  _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
++	  _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
++	  _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
++
++	  char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
++	  if (!__nposn)
++	    _M_data->_M_negative_sign = "()";
++	  else
++	    _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN,
++							__cloc);
++	  _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign);
++
++	  // _Intl == true
++	  _M_data->_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
++	  _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
++	  _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
++						      __cloc));
++	  char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
++	  char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
++	  char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
++	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
++							__pposn);
++	  char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
++	  char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
++	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
++							__nposn);
++	}
++    }
++
++  template<>
++    void
++    moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
++						      const char*)
++    {
++      if (!_M_data)
++	_M_data = new __moneypunct_cache<char, false>;
++
++      if (!__cloc)
++	{
++	  // "C" locale
++	  _M_data->_M_decimal_point = '.';
++	  _M_data->_M_thousands_sep = ',';
++	  _M_data->_M_grouping = "";
++	  _M_data->_M_grouping_size = 0;
++	  _M_data->_M_curr_symbol = "";
++	  _M_data->_M_curr_symbol_size = 0;
++	  _M_data->_M_positive_sign = "";
++	  _M_data->_M_positive_sign_size = 0;
++	  _M_data->_M_negative_sign = "";
++	  _M_data->_M_negative_sign_size = 0;
++	  _M_data->_M_frac_digits = 0;
++	  _M_data->_M_pos_format = money_base::_S_default_pattern;
++	  _M_data->_M_neg_format = money_base::_S_default_pattern;
++
++	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
++	    _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
++	}
++      else
++	{
++	  // Named locale.
++	  _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT,
++							__cloc));
++	  _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP,
++							__cloc));
++	  _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
++	  _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
++	  _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
++	  _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
++
++	  char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
++	  if (!__nposn)
++	    _M_data->_M_negative_sign = "()";
++	  else
++	    _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN,
++							__cloc);
++	  _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign);
++
++	  // _Intl == false
++	  _M_data->_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
++	  _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
++	  _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
++	  char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
++	  char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
++	  char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
++	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
++							__pposn);
++	  char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
++	  char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
++	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
++							__nposn);
++	}
++    }
++
++  template<>
++    moneypunct<char, true>::~moneypunct()
++    { delete _M_data; }
++
++  template<>
++    moneypunct<char, false>::~moneypunct()
++    { delete _M_data; }
++
++#ifdef _GLIBCXX_USE_WCHAR_T
++  template<>
++    void
++    moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
++#ifdef __UCLIBC_HAS_XLOCALE__
++							const char*)
++#else
++							const char* __name)
++#endif
++    {
++      if (!_M_data)
++	_M_data = new __moneypunct_cache<wchar_t, true>;
++
++      if (!__cloc)
++	{
++	  // "C" locale
++	  _M_data->_M_decimal_point = L'.';
++	  _M_data->_M_thousands_sep = L',';
++	  _M_data->_M_grouping = "";
++	  _M_data->_M_grouping_size = 0;
++	  _M_data->_M_curr_symbol = L"";
++	  _M_data->_M_curr_symbol_size = 0;
++	  _M_data->_M_positive_sign = L"";
++	  _M_data->_M_positive_sign_size = 0;
++	  _M_data->_M_negative_sign = L"";
++	  _M_data->_M_negative_sign_size = 0;
++	  _M_data->_M_frac_digits = 0;
++	  _M_data->_M_pos_format = money_base::_S_default_pattern;
++	  _M_data->_M_neg_format = money_base::_S_default_pattern;
++
++	  // Use ctype::widen code without the facet...
++	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
++	    _M_data->_M_atoms[__i] =
++	      static_cast<wchar_t>(money_base::_S_atoms[__i]);
++	}
++      else
++	{
++	  // Named locale.
++#ifdef __UCLIBC_HAS_XLOCALE__
++	  __c_locale __old = __uselocale(__cloc);
++#else
++	  // Switch to named locale so that mbsrtowcs will work.
++	  char* __old = strdup(setlocale(LC_ALL, NULL));
++	  setlocale(LC_ALL, __name);
++#endif
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning fix this... should be monetary
++#endif
++#ifdef __UCLIBC__
++# ifdef __UCLIBC_HAS_XLOCALE__
++	  _M_data->_M_decimal_point = __cloc->decimal_point_wc;
++	  _M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
++# else
++	  _M_data->_M_decimal_point = __global_locale->decimal_point_wc;
++	  _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
++# endif
++#else
++	  union { char *__s; wchar_t __w; } __u;
++	  __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
++	  _M_data->_M_decimal_point = __u.__w;
++
++	  __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
++	  _M_data->_M_thousands_sep = __u.__w;
++#endif
++	  _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
++	  _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
++
++	  const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
++	  const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
++	  const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
++
++	  wchar_t* __wcs_ps = 0;
++	  wchar_t* __wcs_ns = 0;
++	  const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
++	  try
++	    {
++	      mbstate_t __state;
++	      size_t __len = strlen(__cpossign);
++	      if (__len)
++		{
++		  ++__len;
++		  memset(&__state, 0, sizeof(mbstate_t));
++		  __wcs_ps = new wchar_t[__len];
++		  mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
++		  _M_data->_M_positive_sign = __wcs_ps;
++		}
++	      else
++		_M_data->_M_positive_sign = L"";
++	      _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
++
++	      __len = strlen(__cnegsign);
++	      if (!__nposn)
++		_M_data->_M_negative_sign = L"()";
++	      else if (__len)
++		{
++		  ++__len;
++		  memset(&__state, 0, sizeof(mbstate_t));
++		  __wcs_ns = new wchar_t[__len];
++		  mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
++		  _M_data->_M_negative_sign = __wcs_ns;
++		}
++	      else
++		_M_data->_M_negative_sign = L"";
++	      _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
++
++	      // _Intl == true.
++	      __len = strlen(__ccurr);
++	      if (__len)
++		{
++		  ++__len;
++		  memset(&__state, 0, sizeof(mbstate_t));
++		  wchar_t* __wcs = new wchar_t[__len];
++		  mbsrtowcs(__wcs, &__ccurr, __len, &__state);
++		  _M_data->_M_curr_symbol = __wcs;
++		}
++	      else
++		_M_data->_M_curr_symbol = L"";
++	      _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
++	    }
++	  catch (...)
++	    {
++	      delete _M_data;
++	      _M_data = 0;
++	      delete __wcs_ps;
++	      delete __wcs_ns;
++#ifdef __UCLIBC_HAS_XLOCALE__
++	      __uselocale(__old);
++#else
++	      setlocale(LC_ALL, __old);
++	      free(__old);
++#endif
++	      __throw_exception_again;
++	    }
++
++	  _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
++						      __cloc));
++	  char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
++	  char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
++	  char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
++	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
++							__pposn);
++	  char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
++	  char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
++	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
++							__nposn);
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++	  __uselocale(__old);
++#else
++	  setlocale(LC_ALL, __old);
++	  free(__old);
++#endif
++	}
++    }
++
++  template<>
++  void
++  moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
++#ifdef __UCLIBC_HAS_XLOCALE__
++						       const char*)
++#else
++                                                       const char* __name)
++#endif
++  {
++    if (!_M_data)
++      _M_data = new __moneypunct_cache<wchar_t, false>;
++
++    if (!__cloc)
++	{
++	  // "C" locale
++	  _M_data->_M_decimal_point = L'.';
++	  _M_data->_M_thousands_sep = L',';
++	  _M_data->_M_grouping = "";
++          _M_data->_M_grouping_size = 0;
++	  _M_data->_M_curr_symbol = L"";
++	  _M_data->_M_curr_symbol_size = 0;
++	  _M_data->_M_positive_sign = L"";
++	  _M_data->_M_positive_sign_size = 0;
++	  _M_data->_M_negative_sign = L"";
++	  _M_data->_M_negative_sign_size = 0;
++	  _M_data->_M_frac_digits = 0;
++	  _M_data->_M_pos_format = money_base::_S_default_pattern;
++	  _M_data->_M_neg_format = money_base::_S_default_pattern;
++
++	  // Use ctype::widen code without the facet...
++	  for (size_t __i = 0; __i < money_base::_S_end; ++__i)
++	    _M_data->_M_atoms[__i] =
++	      static_cast<wchar_t>(money_base::_S_atoms[__i]);
++	}
++      else
++	{
++	  // Named locale.
++#ifdef __UCLIBC_HAS_XLOCALE__
++	  __c_locale __old = __uselocale(__cloc);
++#else
++	  // Switch to named locale so that mbsrtowcs will work.
++	  char* __old = strdup(setlocale(LC_ALL, NULL));
++	  setlocale(LC_ALL, __name);
++#endif
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning fix this... should be monetary
++#endif
++#ifdef __UCLIBC__
++# ifdef __UCLIBC_HAS_XLOCALE__
++	  _M_data->_M_decimal_point = __cloc->decimal_point_wc;
++	  _M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
++# else
++	  _M_data->_M_decimal_point = __global_locale->decimal_point_wc;
++	  _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
++# endif
++#else
++          union { char *__s; wchar_t __w; } __u;
++	  __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
++	  _M_data->_M_decimal_point = __u.__w;
++
++	  __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
++	  _M_data->_M_thousands_sep = __u.__w;
++#endif
++	  _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
++          _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
++
++	  const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
++	  const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
++	  const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
++
++	  wchar_t* __wcs_ps = 0;
++	  wchar_t* __wcs_ns = 0;
++	  const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
++	  try
++            {
++              mbstate_t __state;
++              size_t __len;
++              __len = strlen(__cpossign);
++              if (__len)
++                {
++		  ++__len;
++		  memset(&__state, 0, sizeof(mbstate_t));
++		  __wcs_ps = new wchar_t[__len];
++		  mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
++		  _M_data->_M_positive_sign = __wcs_ps;
++		}
++	      else
++		_M_data->_M_positive_sign = L"";
++              _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
++
++	      __len = strlen(__cnegsign);
++	      if (!__nposn)
++		_M_data->_M_negative_sign = L"()";
++	      else if (__len)
++		{
++		  ++__len;
++		  memset(&__state, 0, sizeof(mbstate_t));
++		  __wcs_ns = new wchar_t[__len];
++		  mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
++		  _M_data->_M_negative_sign = __wcs_ns;
++		}
++	      else
++		_M_data->_M_negative_sign = L"";
++              _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
++
++	      // _Intl == true.
++	      __len = strlen(__ccurr);
++	      if (__len)
++		{
++		  ++__len;
++		  memset(&__state, 0, sizeof(mbstate_t));
++		  wchar_t* __wcs = new wchar_t[__len];
++		  mbsrtowcs(__wcs, &__ccurr, __len, &__state);
++		  _M_data->_M_curr_symbol = __wcs;
++		}
++	      else
++		_M_data->_M_curr_symbol = L"";
++              _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
++	    }
++          catch (...)
++	    {
++	      delete _M_data;
++              _M_data = 0;
++	      delete __wcs_ps;
++	      delete __wcs_ns;
++#ifdef __UCLIBC_HAS_XLOCALE__
++	      __uselocale(__old);
++#else
++	      setlocale(LC_ALL, __old);
++	      free(__old);
++#endif
++              __throw_exception_again;
++	    }
++
++	  _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
++	  char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
++	  char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
++	  char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
++	  _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
++	                                                __pposn);
++	  char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
++	  char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
++	  _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
++	                                                __nposn);
++
++#ifdef __UCLIBC_HAS_XLOCALE__
++	  __uselocale(__old);
++#else
++	  setlocale(LC_ALL, __old);
++	  free(__old);
++#endif
++	}
++    }
++
++  template<>
++    moneypunct<wchar_t, true>::~moneypunct()
++    {
++      if (_M_data->_M_positive_sign_size)
++	delete [] _M_data->_M_positive_sign;
++      if (_M_data->_M_negative_sign_size
++          && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
++	delete [] _M_data->_M_negative_sign;
++      if (_M_data->_M_curr_symbol_size)
++	delete [] _M_data->_M_curr_symbol;
++      delete _M_data;
++    }
++
++  template<>
++    moneypunct<wchar_t, false>::~moneypunct()
++    {
++      if (_M_data->_M_positive_sign_size)
++	delete [] _M_data->_M_positive_sign;
++      if (_M_data->_M_negative_sign_size
++          && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
++	delete [] _M_data->_M_negative_sign;
++      if (_M_data->_M_curr_symbol_size)
++	delete [] _M_data->_M_curr_symbol;
++      delete _M_data;
++    }
++#endif
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/numeric_members.cc b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+new file mode 100644
+index 0000000..883ec1a
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+@@ -0,0 +1,160 @@
++// std::numpunct implementation details, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.3.1.2  numpunct virtual functions
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#define _LIBC
++#include <locale>
++#undef _LIBC
++#include <bits/c++locale_internal.h>
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning tailor for stub locale support
++#endif
++#ifndef __UCLIBC_HAS_XLOCALE__
++#define __nl_langinfo_l(N, L)         nl_langinfo((N))
++#endif
++
++namespace std
++{
++  template<>
++    void
++    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
++    {
++      if (!_M_data)
++	_M_data = new __numpunct_cache<char>;
++
++      if (!__cloc)
++	{
++	  // "C" locale
++	  _M_data->_M_grouping = "";
++	  _M_data->_M_grouping_size = 0;
++	  _M_data->_M_use_grouping = false;
++
++	  _M_data->_M_decimal_point = '.';
++	  _M_data->_M_thousands_sep = ',';
++
++	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
++	    _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i];
++
++	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
++	    _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j];
++	}
++      else
++	{
++	  // Named locale.
++	  _M_data->_M_decimal_point = *(__nl_langinfo_l(DECIMAL_POINT,
++							__cloc));
++	  _M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSANDS_SEP,
++							__cloc));
++
++	  // Check for NULL, which implies no grouping.
++	  if (_M_data->_M_thousands_sep == '\0')
++	    _M_data->_M_grouping = "";
++	  else
++	    _M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
++	  _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
++	}
++
++      // NB: There is no way to extact this info from posix locales.
++      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
++      _M_data->_M_truename = "true";
++      _M_data->_M_truename_size = 4;
++      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
++      _M_data->_M_falsename = "false";
++      _M_data->_M_falsename_size = 5;
++    }
++
++  template<>
++    numpunct<char>::~numpunct()
++    { delete _M_data; }
++
++#ifdef _GLIBCXX_USE_WCHAR_T
++  template<>
++    void
++    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
++    {
++      if (!_M_data)
++	_M_data = new __numpunct_cache<wchar_t>;
++
++      if (!__cloc)
++	{
++	  // "C" locale
++	  _M_data->_M_grouping = "";
++	  _M_data->_M_grouping_size = 0;
++	  _M_data->_M_use_grouping = false;
++
++	  _M_data->_M_decimal_point = L'.';
++	  _M_data->_M_thousands_sep = L',';
++
++	  // Use ctype::widen code without the facet...
++	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
++	    _M_data->_M_atoms_out[__i] =
++	      static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
++
++	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
++	    _M_data->_M_atoms_in[__j] =
++	      static_cast<wchar_t>(__num_base::_S_atoms_in[__j]);
++	}
++      else
++	{
++	  // Named locale.
++	  // NB: In the GNU model wchar_t is always 32 bit wide.
++	  union { char *__s; wchar_t __w; } __u;
++	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc);
++	  _M_data->_M_decimal_point = __u.__w;
++
++	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc);
++	  _M_data->_M_thousands_sep = __u.__w;
++
++	  if (_M_data->_M_thousands_sep == L'\0')
++	    _M_data->_M_grouping = "";
++	  else
++	    _M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
++	  _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
++	}
++
++      // NB: There is no way to extact this info from posix locales.
++      // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
++      _M_data->_M_truename = L"true";
++      _M_data->_M_truename_size = 4;
++      // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
++      _M_data->_M_falsename = L"false";
++      _M_data->_M_falsename_size = 5;
++    }
++
++  template<>
++    numpunct<wchar_t>::~numpunct()
++    { delete _M_data; }
++ #endif
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/time_members.cc b/libstdc++-v3/config/locale/uclibc/time_members.cc
+new file mode 100644
+index 0000000..e0707d7
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/time_members.cc
+@@ -0,0 +1,406 @@
++// std::time_get, std::time_put implementation, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.5.1.2 - time_get virtual functions
++// ISO C++ 14882: 22.2.5.3.2 - time_put virtual functions
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++#include <locale>
++#include <bits/c++locale_internal.h>
++
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning tailor for stub locale support
++#endif
++#ifndef __UCLIBC_HAS_XLOCALE__
++#define __nl_langinfo_l(N, L)         nl_langinfo((N))
++#endif
++
++namespace std
++{
++  template<>
++    void
++    __timepunct<char>::
++    _M_put(char* __s, size_t __maxlen, const char* __format,
++	   const tm* __tm) const
++    {
++#ifdef __UCLIBC_HAS_XLOCALE__
++      const size_t __len = __strftime_l(__s, __maxlen, __format, __tm,
++					_M_c_locale_timepunct);
++#else
++      char* __old = strdup(setlocale(LC_ALL, NULL));
++      setlocale(LC_ALL, _M_name_timepunct);
++      const size_t __len = strftime(__s, __maxlen, __format, __tm);
++      setlocale(LC_ALL, __old);
++      free(__old);
++#endif
++      // Make sure __s is null terminated.
++      if (__len == 0)
++	__s[0] = '\0';
++    }
++
++  template<>
++    void
++    __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc)
++    {
++      if (!_M_data)
++	_M_data = new __timepunct_cache<char>;
++
++      if (!__cloc)
++	{
++	  // "C" locale
++	  _M_c_locale_timepunct = _S_get_c_locale();
++
++	  _M_data->_M_date_format = "%m/%d/%y";
++	  _M_data->_M_date_era_format = "%m/%d/%y";
++	  _M_data->_M_time_format = "%H:%M:%S";
++	  _M_data->_M_time_era_format = "%H:%M:%S";
++	  _M_data->_M_date_time_format = "";
++	  _M_data->_M_date_time_era_format = "";
++	  _M_data->_M_am = "AM";
++	  _M_data->_M_pm = "PM";
++	  _M_data->_M_am_pm_format = "";
++
++	  // Day names, starting with "C"'s Sunday.
++	  _M_data->_M_day1 = "Sunday";
++	  _M_data->_M_day2 = "Monday";
++	  _M_data->_M_day3 = "Tuesday";
++	  _M_data->_M_day4 = "Wednesday";
++	  _M_data->_M_day5 = "Thursday";
++	  _M_data->_M_day6 = "Friday";
++	  _M_data->_M_day7 = "Saturday";
++
++	  // Abbreviated day names, starting with "C"'s Sun.
++	  _M_data->_M_aday1 = "Sun";
++	  _M_data->_M_aday2 = "Mon";
++	  _M_data->_M_aday3 = "Tue";
++	  _M_data->_M_aday4 = "Wed";
++	  _M_data->_M_aday5 = "Thu";
++	  _M_data->_M_aday6 = "Fri";
++	  _M_data->_M_aday7 = "Sat";
++
++	  // Month names, starting with "C"'s January.
++	  _M_data->_M_month01 = "January";
++	  _M_data->_M_month02 = "February";
++	  _M_data->_M_month03 = "March";
++	  _M_data->_M_month04 = "April";
++	  _M_data->_M_month05 = "May";
++	  _M_data->_M_month06 = "June";
++	  _M_data->_M_month07 = "July";
++	  _M_data->_M_month08 = "August";
++	  _M_data->_M_month09 = "September";
++	  _M_data->_M_month10 = "October";
++	  _M_data->_M_month11 = "November";
++	  _M_data->_M_month12 = "December";
++
++	  // Abbreviated month names, starting with "C"'s Jan.
++	  _M_data->_M_amonth01 = "Jan";
++	  _M_data->_M_amonth02 = "Feb";
++	  _M_data->_M_amonth03 = "Mar";
++	  _M_data->_M_amonth04 = "Apr";
++	  _M_data->_M_amonth05 = "May";
++	  _M_data->_M_amonth06 = "Jun";
++	  _M_data->_M_amonth07 = "Jul";
++	  _M_data->_M_amonth08 = "Aug";
++	  _M_data->_M_amonth09 = "Sep";
++	  _M_data->_M_amonth10 = "Oct";
++	  _M_data->_M_amonth11 = "Nov";
++	  _M_data->_M_amonth12 = "Dec";
++	}
++      else
++	{
++	  _M_c_locale_timepunct = _S_clone_c_locale(__cloc);
++
++	  _M_data->_M_date_format = __nl_langinfo_l(D_FMT, __cloc);
++	  _M_data->_M_date_era_format = __nl_langinfo_l(ERA_D_FMT, __cloc);
++	  _M_data->_M_time_format = __nl_langinfo_l(T_FMT, __cloc);
++	  _M_data->_M_time_era_format = __nl_langinfo_l(ERA_T_FMT, __cloc);
++	  _M_data->_M_date_time_format = __nl_langinfo_l(D_T_FMT, __cloc);
++	  _M_data->_M_date_time_era_format = __nl_langinfo_l(ERA_D_T_FMT,
++							     __cloc);
++	  _M_data->_M_am = __nl_langinfo_l(AM_STR, __cloc);
++	  _M_data->_M_pm = __nl_langinfo_l(PM_STR, __cloc);
++	  _M_data->_M_am_pm_format = __nl_langinfo_l(T_FMT_AMPM, __cloc);
++
++	  // Day names, starting with "C"'s Sunday.
++	  _M_data->_M_day1 = __nl_langinfo_l(DAY_1, __cloc);
++	  _M_data->_M_day2 = __nl_langinfo_l(DAY_2, __cloc);
++	  _M_data->_M_day3 = __nl_langinfo_l(DAY_3, __cloc);
++	  _M_data->_M_day4 = __nl_langinfo_l(DAY_4, __cloc);
++	  _M_data->_M_day5 = __nl_langinfo_l(DAY_5, __cloc);
++	  _M_data->_M_day6 = __nl_langinfo_l(DAY_6, __cloc);
++	  _M_data->_M_day7 = __nl_langinfo_l(DAY_7, __cloc);
++
++	  // Abbreviated day names, starting with "C"'s Sun.
++	  _M_data->_M_aday1 = __nl_langinfo_l(ABDAY_1, __cloc);
++	  _M_data->_M_aday2 = __nl_langinfo_l(ABDAY_2, __cloc);
++	  _M_data->_M_aday3 = __nl_langinfo_l(ABDAY_3, __cloc);
++	  _M_data->_M_aday4 = __nl_langinfo_l(ABDAY_4, __cloc);
++	  _M_data->_M_aday5 = __nl_langinfo_l(ABDAY_5, __cloc);
++	  _M_data->_M_aday6 = __nl_langinfo_l(ABDAY_6, __cloc);
++	  _M_data->_M_aday7 = __nl_langinfo_l(ABDAY_7, __cloc);
++
++	  // Month names, starting with "C"'s January.
++	  _M_data->_M_month01 = __nl_langinfo_l(MON_1, __cloc);
++	  _M_data->_M_month02 = __nl_langinfo_l(MON_2, __cloc);
++	  _M_data->_M_month03 = __nl_langinfo_l(MON_3, __cloc);
++	  _M_data->_M_month04 = __nl_langinfo_l(MON_4, __cloc);
++	  _M_data->_M_month05 = __nl_langinfo_l(MON_5, __cloc);
++	  _M_data->_M_month06 = __nl_langinfo_l(MON_6, __cloc);
++	  _M_data->_M_month07 = __nl_langinfo_l(MON_7, __cloc);
++	  _M_data->_M_month08 = __nl_langinfo_l(MON_8, __cloc);
++	  _M_data->_M_month09 = __nl_langinfo_l(MON_9, __cloc);
++	  _M_data->_M_month10 = __nl_langinfo_l(MON_10, __cloc);
++	  _M_data->_M_month11 = __nl_langinfo_l(MON_11, __cloc);
++	  _M_data->_M_month12 = __nl_langinfo_l(MON_12, __cloc);
++
++	  // Abbreviated month names, starting with "C"'s Jan.
++	  _M_data->_M_amonth01 = __nl_langinfo_l(ABMON_1, __cloc);
++	  _M_data->_M_amonth02 = __nl_langinfo_l(ABMON_2, __cloc);
++	  _M_data->_M_amonth03 = __nl_langinfo_l(ABMON_3, __cloc);
++	  _M_data->_M_amonth04 = __nl_langinfo_l(ABMON_4, __cloc);
++	  _M_data->_M_amonth05 = __nl_langinfo_l(ABMON_5, __cloc);
++	  _M_data->_M_amonth06 = __nl_langinfo_l(ABMON_6, __cloc);
++	  _M_data->_M_amonth07 = __nl_langinfo_l(ABMON_7, __cloc);
++	  _M_data->_M_amonth08 = __nl_langinfo_l(ABMON_8, __cloc);
++	  _M_data->_M_amonth09 = __nl_langinfo_l(ABMON_9, __cloc);
++	  _M_data->_M_amonth10 = __nl_langinfo_l(ABMON_10, __cloc);
++	  _M_data->_M_amonth11 = __nl_langinfo_l(ABMON_11, __cloc);
++	  _M_data->_M_amonth12 = __nl_langinfo_l(ABMON_12, __cloc);
++	}
++    }
++
++#ifdef _GLIBCXX_USE_WCHAR_T
++  template<>
++    void
++    __timepunct<wchar_t>::
++    _M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format,
++	   const tm* __tm) const
++    {
++#ifdef __UCLIBC_HAS_XLOCALE__
++      __wcsftime_l(__s, __maxlen, __format, __tm, _M_c_locale_timepunct);
++      const size_t __len = __wcsftime_l(__s, __maxlen, __format, __tm,
++					_M_c_locale_timepunct);
++#else
++      char* __old = strdup(setlocale(LC_ALL, NULL));
++      setlocale(LC_ALL, _M_name_timepunct);
++      const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
++      setlocale(LC_ALL, __old);
++      free(__old);
++#endif
++      // Make sure __s is null terminated.
++      if (__len == 0)
++	__s[0] = L'\0';
++    }
++
++  template<>
++    void
++    __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc)
++    {
++      if (!_M_data)
++	_M_data = new __timepunct_cache<wchar_t>;
++
++#warning wide time stuff
++//       if (!__cloc)
++	{
++	  // "C" locale
++	  _M_c_locale_timepunct = _S_get_c_locale();
++
++	  _M_data->_M_date_format = L"%m/%d/%y";
++	  _M_data->_M_date_era_format = L"%m/%d/%y";
++	  _M_data->_M_time_format = L"%H:%M:%S";
++	  _M_data->_M_time_era_format = L"%H:%M:%S";
++	  _M_data->_M_date_time_format = L"";
++	  _M_data->_M_date_time_era_format = L"";
++	  _M_data->_M_am = L"AM";
++	  _M_data->_M_pm = L"PM";
++	  _M_data->_M_am_pm_format = L"";
++
++	  // Day names, starting with "C"'s Sunday.
++	  _M_data->_M_day1 = L"Sunday";
++	  _M_data->_M_day2 = L"Monday";
++	  _M_data->_M_day3 = L"Tuesday";
++	  _M_data->_M_day4 = L"Wednesday";
++	  _M_data->_M_day5 = L"Thursday";
++	  _M_data->_M_day6 = L"Friday";
++	  _M_data->_M_day7 = L"Saturday";
++
++	  // Abbreviated day names, starting with "C"'s Sun.
++	  _M_data->_M_aday1 = L"Sun";
++	  _M_data->_M_aday2 = L"Mon";
++	  _M_data->_M_aday3 = L"Tue";
++	  _M_data->_M_aday4 = L"Wed";
++	  _M_data->_M_aday5 = L"Thu";
++	  _M_data->_M_aday6 = L"Fri";
++	  _M_data->_M_aday7 = L"Sat";
++
++	  // Month names, starting with "C"'s January.
++	  _M_data->_M_month01 = L"January";
++	  _M_data->_M_month02 = L"February";
++	  _M_data->_M_month03 = L"March";
++	  _M_data->_M_month04 = L"April";
++	  _M_data->_M_month05 = L"May";
++	  _M_data->_M_month06 = L"June";
++	  _M_data->_M_month07 = L"July";
++	  _M_data->_M_month08 = L"August";
++	  _M_data->_M_month09 = L"September";
++	  _M_data->_M_month10 = L"October";
++	  _M_data->_M_month11 = L"November";
++	  _M_data->_M_month12 = L"December";
++
++	  // Abbreviated month names, starting with "C"'s Jan.
++	  _M_data->_M_amonth01 = L"Jan";
++	  _M_data->_M_amonth02 = L"Feb";
++	  _M_data->_M_amonth03 = L"Mar";
++	  _M_data->_M_amonth04 = L"Apr";
++	  _M_data->_M_amonth05 = L"May";
++	  _M_data->_M_amonth06 = L"Jun";
++	  _M_data->_M_amonth07 = L"Jul";
++	  _M_data->_M_amonth08 = L"Aug";
++	  _M_data->_M_amonth09 = L"Sep";
++	  _M_data->_M_amonth10 = L"Oct";
++	  _M_data->_M_amonth11 = L"Nov";
++	  _M_data->_M_amonth12 = L"Dec";
++	}
++#if 0
++      else
++	{
++	  _M_c_locale_timepunct = _S_clone_c_locale(__cloc);
++
++	  union { char *__s; wchar_t *__w; } __u;
++
++	  __u.__s = __nl_langinfo_l(_NL_WD_FMT, __cloc);
++	  _M_data->_M_date_format = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WERA_D_FMT, __cloc);
++	  _M_data->_M_date_era_format = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WT_FMT, __cloc);
++	  _M_data->_M_time_format = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WERA_T_FMT, __cloc);
++	  _M_data->_M_time_era_format = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WD_T_FMT, __cloc);
++	  _M_data->_M_date_time_format = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WERA_D_T_FMT, __cloc);
++	  _M_data->_M_date_time_era_format = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WAM_STR, __cloc);
++	  _M_data->_M_am = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WPM_STR, __cloc);
++	  _M_data->_M_pm = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WT_FMT_AMPM, __cloc);
++	  _M_data->_M_am_pm_format = __u.__w;
++
++	  // Day names, starting with "C"'s Sunday.
++	  __u.__s = __nl_langinfo_l(_NL_WDAY_1, __cloc);
++	  _M_data->_M_day1 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WDAY_2, __cloc);
++	  _M_data->_M_day2 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WDAY_3, __cloc);
++	  _M_data->_M_day3 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WDAY_4, __cloc);
++	  _M_data->_M_day4 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WDAY_5, __cloc);
++	  _M_data->_M_day5 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WDAY_6, __cloc);
++	  _M_data->_M_day6 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WDAY_7, __cloc);
++	  _M_data->_M_day7 = __u.__w;
++
++	  // Abbreviated day names, starting with "C"'s Sun.
++	  __u.__s = __nl_langinfo_l(_NL_WABDAY_1, __cloc);
++	  _M_data->_M_aday1 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABDAY_2, __cloc);
++	  _M_data->_M_aday2 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABDAY_3, __cloc);
++	  _M_data->_M_aday3 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABDAY_4, __cloc);
++	  _M_data->_M_aday4 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABDAY_5, __cloc);
++	  _M_data->_M_aday5 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABDAY_6, __cloc);
++	  _M_data->_M_aday6 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABDAY_7, __cloc);
++	  _M_data->_M_aday7 = __u.__w;
++
++	  // Month names, starting with "C"'s January.
++	  __u.__s = __nl_langinfo_l(_NL_WMON_1, __cloc);
++	  _M_data->_M_month01 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_2, __cloc);
++	  _M_data->_M_month02 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_3, __cloc);
++	  _M_data->_M_month03 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_4, __cloc);
++	  _M_data->_M_month04 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_5, __cloc);
++	  _M_data->_M_month05 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_6, __cloc);
++	  _M_data->_M_month06 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_7, __cloc);
++	  _M_data->_M_month07 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_8, __cloc);
++	  _M_data->_M_month08 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_9, __cloc);
++	  _M_data->_M_month09 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_10, __cloc);
++	  _M_data->_M_month10 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_11, __cloc);
++	  _M_data->_M_month11 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WMON_12, __cloc);
++	  _M_data->_M_month12 = __u.__w;
++
++	  // Abbreviated month names, starting with "C"'s Jan.
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_1, __cloc);
++	  _M_data->_M_amonth01 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_2, __cloc);
++	  _M_data->_M_amonth02 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_3, __cloc);
++	  _M_data->_M_amonth03 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_4, __cloc);
++	  _M_data->_M_amonth04 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_5, __cloc);
++	  _M_data->_M_amonth05 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_6, __cloc);
++	  _M_data->_M_amonth06 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_7, __cloc);
++	  _M_data->_M_amonth07 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_8, __cloc);
++	  _M_data->_M_amonth08 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_9, __cloc);
++	  _M_data->_M_amonth09 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_10, __cloc);
++	  _M_data->_M_amonth10 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_11, __cloc);
++	  _M_data->_M_amonth11 = __u.__w;
++	  __u.__s = __nl_langinfo_l(_NL_WABMON_12, __cloc);
++	  _M_data->_M_amonth12 = __u.__w;
++	}
++#endif // 0
++    }
++#endif
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/time_members.h b/libstdc++-v3/config/locale/uclibc/time_members.h
+new file mode 100644
+index 0000000..ba8e858
+--- /dev/null
++++ b/libstdc++-v3/config/locale/uclibc/time_members.h
+@@ -0,0 +1,68 @@
++// std::time_get, std::time_put implementation, GNU version -*- C++ -*-
++
++// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
++//
++// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
++// any later version.
++
++// This 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 General Public License for more details.
++
++// You should have received a copy of the GNU General Public License along
++// with this library; see the file COPYING.  If not, write to the Free
++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++// USA.
++
++// As a special exception, you may use this file as part of a free software
++// library without restriction.  Specifically, if other files instantiate
++// templates or use macros or inline functions from this file, or you compile
++// this file and link it with other files to produce an executable, this
++// file does not by itself cause the resulting executable to be covered by
++// the GNU General Public License.  This exception does not however
++// invalidate any other reasons why the executable file might be covered by
++// the GNU General Public License.
++
++//
++// ISO C++ 14882: 22.2.5.1.2 - time_get functions
++// ISO C++ 14882: 22.2.5.3.2 - time_put functions
++//
++
++// Written by Benjamin Kosnik <bkoz@redhat.com>
++
++  template<typename _CharT>
++    __timepunct<_CharT>::__timepunct(size_t __refs)
++    : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
++    _M_name_timepunct(_S_get_c_name())
++    { _M_initialize_timepunct(); }
++
++  template<typename _CharT>
++    __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs)
++    : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(NULL),
++    _M_name_timepunct(_S_get_c_name())
++    { _M_initialize_timepunct(); }
++
++  template<typename _CharT>
++    __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
++				     size_t __refs)
++    : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
++    _M_name_timepunct(__s)
++    {
++      char* __tmp = new char[std::strlen(__s) + 1];
++      std::strcpy(__tmp, __s);
++      _M_name_timepunct = __tmp;
++      _M_initialize_timepunct(__cloc);
++    }
++
++  template<typename _CharT>
++    __timepunct<_CharT>::~__timepunct()
++    {
++      if (_M_name_timepunct != _S_get_c_name())
++	delete [] _M_name_timepunct;
++      delete _M_data;
++      _S_destroy_c_locale(_M_c_locale_timepunct);
++    }
+diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
+index f40ddcf..c57a751 100755
+--- a/libstdc++-v3/configure
++++ b/libstdc++-v3/configure
+@@ -15822,6 +15822,9 @@ fi
+   # Default to "generic".
+   if test $enable_clocale_flag = auto; then
+     case ${target_os} in
++      *-uclibc*)
++        enable_clocale_flag=uclibc
++        ;;
+       linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu)
+ 	enable_clocale_flag=gnu
+ 	;;
+@@ -16079,6 +16082,78 @@ $as_echo "newlib" >&6; }
+       CTIME_CC=config/locale/generic/time_members.cc
+       CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h
+       ;;
++    uclibc)
++      { $as_echo "$as_me:${as_lineno-$LINENO}: result: uclibc" >&5
++$as_echo "uclibc" >&6; }
++
++      # Declare intention to use gettext, and add support for specific
++      # languages.
++      # For some reason, ALL_LINGUAS has to be before AM-GNU-GETTEXT
++      ALL_LINGUAS="de fr"
++
++      # Don't call AM-GNU-GETTEXT here. Instead, assume glibc.
++      # Extract the first word of "msgfmt", so it can be a program name with args.
++set dummy msgfmt; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if test "${ac_cv_prog_check_msgfmt+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$check_msgfmt"; then
++  ac_cv_prog_check_msgfmt="$check_msgfmt" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
++    ac_cv_prog_check_msgfmt="yes"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++  test -z "$ac_cv_prog_check_msgfmt" && ac_cv_prog_check_msgfmt="no"
++fi
++fi
++check_msgfmt=$ac_cv_prog_check_msgfmt
++if test -n "$check_msgfmt"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $check_msgfmt" >&5
++$as_echo "$check_msgfmt" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++      if test x"$check_msgfmt" = x"yes" && test x"$enable_nls" = x"yes"; then
++        USE_NLS=yes
++      fi
++      # Export the build objects.
++      for ling in $ALL_LINGUAS; do \
++        glibcxx_MOFILES="$glibcxx_MOFILES $ling.mo"; \
++        glibcxx_POFILES="$glibcxx_POFILES $ling.po"; \
++      done
++
++
++
++      CLOCALE_H=config/locale/uclibc/c_locale.h
++      CLOCALE_CC=config/locale/uclibc/c_locale.cc
++      CCODECVT_CC=config/locale/uclibc/codecvt_members.cc
++      CCOLLATE_CC=config/locale/uclibc/collate_members.cc
++      CCTYPE_CC=config/locale/uclibc/ctype_members.cc
++      CMESSAGES_H=config/locale/uclibc/messages_members.h
++      CMESSAGES_CC=config/locale/uclibc/messages_members.cc
++      CMONEY_CC=config/locale/uclibc/monetary_members.cc
++      CNUMERIC_CC=config/locale/uclibc/numeric_members.cc
++      CTIME_H=config/locale/uclibc/time_members.h
++      CTIME_CC=config/locale/uclibc/time_members.cc
++      CLOCALE_INTERNAL_H=config/locale/uclibc/c++locale_internal.h
++      ;;
+   esac
+ 
+   # This is where the testsuite looks for locale catalogs, using the
+diff --git a/libstdc++-v3/include/c_compatibility/wchar.h b/libstdc++-v3/include/c_compatibility/wchar.h
+index 580d725..3fe61b8 100644
+--- a/libstdc++-v3/include/c_compatibility/wchar.h
++++ b/libstdc++-v3/include/c_compatibility/wchar.h
+@@ -101,7 +101,9 @@ using std::wmemcmp;
+ using std::wmemcpy;
+ using std::wmemmove;
+ using std::wmemset;
++#if _GLIBCXX_HAVE_WCSFTIME
+ using std::wcsftime;
++#endif
+ 
+ #if _GLIBCXX_USE_C99
+ using std::wcstold;
+diff --git a/libstdc++-v3/include/c_std/cwchar b/libstdc++-v3/include/c_std/cwchar
+index 0e6b1fc..405aee2 100644
+--- a/libstdc++-v3/include/c_std/cwchar
++++ b/libstdc++-v3/include/c_std/cwchar
+@@ -175,7 +175,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+   using ::wcscoll;
+   using ::wcscpy;
+   using ::wcscspn;
++#if _GLIBCXX_HAVE_WCSFTIME
+   using ::wcsftime;
++#endif
+   using ::wcslen;
+   using ::wcsncat;
+   using ::wcsncmp;
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0004.gcc.extelim-v4-49x.patch b/recipes-devtools/gcc/gcc-4.9/0004.gcc.extelim-v4-49x.patch
new file mode 100644
index 0000000..14d7a17
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0004.gcc.extelim-v4-49x.patch
@@ -0,0 +1,4526 @@
+# Problem Statement:
+  Eliminate sign and zero extensions in PPC generated code
+
+# Owned by:
+  Edmar Wienskoski and John Russo
+
+# Action:
+  a) Eliminate sign and zero extensions in PPC generated code
+     A new module is introduced 'extelim.c' and a new RTL pass is introduced.
+     The '-f[no-]extelim' flag controls this pass and is enabled at -O2 and above.
+     The algorithm is based on the paper "Effective Sign Extension Elimination", Kawahito, et. al.
+     More details on implementation in the extelim.c module.
+
+  b) Combine clrldi and rldicr into a single rldic instruction. The particular difficulty in the
+     presented test case is that the clrldi reaches the rldicr instruction via a branch from the
+     bottom of a loop. This make the combination inappropriate for the combine phase
+     (reaches across basic blocks). The solution is to duplicate the clrldi at a reaching point at
+     rldicr and let the extension elimination eliminate the now redundant original clrldi.  The
+     instruction selector now sees the adjacent clrldi,rldicr (int rtl form) and selects the rldic
+     instruction.
+
+     This is only effective for 64-bit targets that have rldic instructions.
+     The test case rldic-1.c and tests that rldic is generated for the test case.
+
+  c) This patch also contains extension elimination fix for ENGR00225973 (segmentation fault at -O3).
+
+  d) Append patch to fix spec2k perlbmk issue when using -flto -funroll-loops
+
+  e) Append patch to select active 'prev_insn', else we end up with consecutive extensions 
+    (one inserted, one previously there) for return instructions. 
+
+  f) Updated changes to match with GCC v4.9.x source base.
+
+  g) Update vect-reduc-pattern-2b-big-array.c test case to prevent signed overflow.
+
+  h) The main entry point of extension elimination algorithm was returning void.
+     With v4.9.x source base, this file is compiled by C++ compiler which optimizes this code.
+     Update changes to work with v4.9.x source base.
+     Remove unused variables from 'init_flags_vector'.
+
+  i) spec2k.gap relies on signed arithmetic overflow being well-defined.
+     Disable extension elimination for '-fwrapv, -ftrapv, -fno-strict-overflow'.
+
+  j) Fix 20040709-2.c [-Os] and 20111227-1.c [-O2,-O3,-Os].
+     "operation_extends_to_upper_bits_size" had one of the conditional check reversed
+     which eliminated a required sign extension instruction.
+
+  k) Update gcc.dg/sms-1.c and gcc.dg/sms-6.c test cases so that Swing Modulo Scheduling happens
+
+  l) Added target macro header file to fix ICE in windows build with GCC v4.9.x
+
+  m) Add test case from coriant team which got fixed by (j).
+
+diff -Naur gcc-4.7.1/gcc/common.opt gcc-4.7.1-extelim-v4/gcc/common.opt
+--- gcc-4.7.1/gcc/common.opt	2012-05-04 06:34:25.000000000 -0500
++++ gcc-4.7.1-extelim-v4/gcc/common.opt	2012-10-31 03:12:42.109238187 -0500
+@@ -1054,6 +1054,10 @@
+ Common Report Var(flag_eliminate_dwarf2_dups)
+ Perform DWARF2 duplicate elimination
+ 
++fextelim
++Common Report Var(flag_extelim)
++Perform zero/sign extension removal
++
+ fipa-sra
+ Common Report Var(flag_ipa_sra) Init(0) Optimization
+ Perform interprocedural reduction of aggregates
+diff -Naur gcc-4.7.1/gcc/config/rs6000/extelim.c gcc-4.7.1-extelim-v4/gcc/config/rs6000/extelim.c
+--- gcc-4.7.1/gcc/config/rs6000/extelim.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.1-extelim-v4/gcc/config/rs6000/extelim.c	2012-11-05 00:43:33.642238016 -0600
+@@ -0,0 +1,3431 @@
++/* Redundant extension elimination 
++   Copyright (C) 2010 Free Software Foundation, Inc.
++   Contributed by John Russo (john.russo@freescale.com)
++
++This file is part of GCC.
++
++GCC 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, or (at your option) any later
++version.
++
++GCC 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 GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/*
++PURPOSE: Implement a method for eliminating redundant and superflous sign
++extension instructions from 64-bit PPC e5500 generated code.
++
++MOTIVATING EXAMPLE:
++The Nullstone loop_6.c kernel looks like:
++  int i;
++  int a[100];
++  
++  ref_int_p (&a[0]);
++  
++  for (i=2; i<100; i++)
++    a[i] = a[i-1] + a[i-2];
++  
++The final, generated code for the loop body is:
++
++32-bit                  64-bit
++add     r25,r11,r0	add     r5,r5,r8
++add     r26,r0,r25	addi    r4,r4,12
++stw     r25,0(r9)	add     r27,r5,r8
++add     r27,r25,r26	stw     r5,0(r9)
++stw     r26,4(r9)	extsw   r12,r27       <===
++add     r28,r26,r27	stw     r27,4(r9)
++stw     r27,8(r9)	add     r6,r5,r12
++add     r29,r27,r28	add     r28,r6,r12
++stw     r28,12(r9)	stw     r6,8(r9)
++add     r30,r28,r29	extsw   r0,r28        <===
++stw     r29,16(r9)	stw     r28,12(r9)
++add     r12,r29,r30	add     r7,r6,r0
++stw     r30,20(r9)	add     r29,r7,r0
++add     r3,r30,r12	stw     r7,16(r9)
++stw     r12,24(r9)	extsw   r3,r29        <===
++add     r4,r12,r3	stw     r29,20(r9)
++stw     r3,28(r9)	add     r10,r7,r3
++add     r5,r3,r4	add     r30,r10,r3
++stw     r4,32(r9)	stw     r10,24(r9)
++add     r6,r4,r5	extsw   r8,r30        <===
++stw     r5,36(r9)	stw     r30,28(r9)
++add     r7,r5,r6	add     r11,r10,r8
++stw     r6,40(r9)	add     r12,r11,r8
++add     r8,r6,r7	stw     r11,32(r9)
++stw     r7,44(r9)	extsw   r26,r12       <===
++add     r10,r7,r8	stw     r12,36(r9)
++stw     r8,48(r9)	add     r0,r11,r26
++add     r11,r8,r10	add     r3,r0,r26
++stw     r10,52(r9)	stw     r0,40(r9)
++add     r0,r10,r11	subfic  r26,r4,100
++stw     r11,56(r9)	stw     r3,44(r9)
++stw     r0,60(r9)	extsw   r5,r0         <===
++addi    r9,r9,64	extsw   r8,r3         <===
++bdnz+   10000640        extsw   r4,r4         <===
++                        clrldi  r26,r26,32
++                        addi    r9,r9,48
++                        bdnz+   10000890 
++
++GENERAL APPROACH:
++Consider a machine whose native register size is 64-bits
++
++0          3132         63
++|-----------||-----------|
++
++where bit 63 is the LSB and bit 0 is the MSB of a long int
++and bit 63 is the LSB and bit 32 is the MSB of an int.
++
++Sign and zero extension are inserted to RTL to preserve the
++operation's semantics when the operands used are not the 
++native register size since normally the machine only performs
++the operation using a native register size. In practice, many
++of the inserted extensions are not necessary.
++
++First, the extension may simply be redundant. That is, the 
++same operation is performed on the same operands. The redundant
++extensions can be eliminated.
++
++Secondly, if the extended portion of the register (the "upper" bits)
++are not essential to the calculations performed on the output of the
++extension, then the extension is not necessary. For example, given
++int (32-bit) inputs and outputs:
++
++c = a + b
++d = sxt(c)
++e = d + 1; 
++
++The "upper" bits of d (bit 0-31) do not affect the calculation
++of e. It doesn't matter what the "upper" bits of d are, the int result
++e is the same regardless of the sxt instruction.
++
++Thirdly, the extensions may not be necessary if the operands are
++already extended and the operation preserves the extended bits.
++
++a = mem[&b] ; sign extending load
++c = a + 1
++d = sxt(c)
++
++Here, a is generated by a sign extending load, the operation
++does nothing to invalidate the extension to c, thus the extension
++on c to d is not necessary.
++
++In each case, the redundant extension must be replaced by a copy,
++with the copy to be optimized out in later phases.
++
++The three cases described above form the general idea behind the
++algorithms implemented here to eliminate redundant and unneccessary
++extensions. 
++
++Sign extensions do not have to be preserved for overflow conditions
++since signed overflow behavior is not defined in C. For example,
++take a 16-bit variable in a 32-bit register. It is ok
++for 0x0000_7fff to overflow to 0x0000_8000 and not 0xffff_8000.
++This implies that it is not necessary to preserve the sign
++extension.
++
++Unsigned overflow extension need to be preserved because 
++unsigned overflow is modulo. For example, a 16-bit unsigned 
++overflow of 0x0000_FFFF must be 0x0000_0000 in a 32-bit register, 
++not 0x0001_0000. In order to remove the unsigned zero extension,
++we would need to range check the variable to be sure it doesn't
++overflow.  
++
++RTL ANALYSIS:
++I looked at the RTL representation after RTL generation (.expand) and
++after the first forward propagation (.fwprop1). Since RTL is not compact
++when printing out, I reduced the .fwprop1 RTL to this pseudocode:
++
++(note: sxt,zxt mean double word length, 64-bit, extension).
++
++(1)     r198 = m[r113+ #112]     ; load a[0]
++(2)     r174 = sxt(r198)
++(3)     r199 = m[r113+ #116]     ; load a[1] 
++(4)     r186 = sxt(r199)
++(5)     r181 = r113 + #120       ; load &a[2]
++(6)     r180 = 2                 ; i = 2
++(7)     L1:
++(8)     r200 = r174 + r186       ; t1 = a[i-1] + a[i-2]
++(9)     r174 = sxt(r200)
++(10)    m[r181] = r200           ; a[i] = t1
++(11)    r201 = r200 + r186       ; t2 = t1 + a[i-1]
++(12)    r186 = sxt(r201)
++(13)    m[r181+4] = r201         ; a[i+1] = t2
++(14)    r202 = r180 + 2          ; i += 2
++(14.1)  r180 = sxt(r202)     
++(15)    r203 = 100 - r202        ; used to calc loop remainder
++(16)    r185 = zxt(r203)         ; used to calc loop remainder
++(17)    r181 = r181 + 8          ; address induction var
++(18)    ccr204 = cmp(r202,#98)   ; set CC
++(19)    BNE ccr204,L1            ; branch 
++
++In the pseudo-code, you see several sign extension candidates: (2),(4),
++(9), (12), (14.1), (16).  
++
++ALGORITHM:
++To eliminate the extra sign ext you have to look at (1) the definitions
++of the source of the sign extensions and/or (2) look at the uses of the target
++of the sign extensions. In either case, if doing a global elimination
++pass, you'll need def-use chain information. 
++
++The algorithms are recursive. Using the use/def and def/use chains
++we attempt to find ultimately whether the extension is relevant
++or not. 
++
++
++Example 1.
++Extensions (2) and (4) are not put in the candidate list because
++they are combined into a load/ext pair that is ultimately generated
++as sign extending loads.
++
++Take the sign extension at (9), r174 = sxt(r200).
++Def analysis shows that r200 is defined by 2 registers, thus no
++further def analysis recursion can occur.
++Use analysis. Find all the uses of r174. There is 1 use at (8) r200 = r174 + r186. 
++The extension does not affect the add operation results. Continuing, we look at
++the uses of r200 to see if the results of operations on r200 need the sign extended bits.
++We see 2 uses of r200 at (10) and (11). (10) is a 32-bit store of r200,
++so the sign extended bits are irrelevant. (11), however, is an unknown,
++so we must look that the uses of this result, r201. A similar sequence
++occurs for r201 when it defines r186. Looking at the uses of r186 at 
++(8) and (11), we have already visited those statements so they have
++been covered already. So it appears that the sxt to r174 at (9) ultimately
++dead-ends to a store instruction that doesn't case about the sign extended
++bits. The sxt at (9) can be removed.
++
++The remaining extensions are processed similarly.
++
++PROGRAM STRUCTURE:
++
++extension elimination                            -- main entry point
++ find extensions                                 -- identify extension candidates
++ extension duplication                           -- insert extension at strategic points to
++                                                    enable removal of extensions at more frequently
++                                                    executed points.
++ find extensions                                 -- recreate extension candidate list
++ sort extensions                                 -- sort extension candidate list by loop depth
++ for each ext in list                            -- process each extension candidate
++  eliminate one extension
++ replace marked candidates with copy             -- optimize the extension
++
++PSEUDOCODE:
++
++Create working list of sign extensions, sxt_list
++
++For each insn, insn_sxt,  in sxt_list 
++   ext_needed = true 
++   For all insns, insn_def, that DEFINE and REACH the SOURCE_REG(insn_sxt)
++     ext_needed = analyze_def(insn_def, insn_sxt)
++     if (ext_needed)
++       break;
++   end_loop
++   if (ext_needed)
++     For all insns, insn_use, that USE and are REACHED by the DEST_REG(insn_sxt)
++       ext_needed = analyze_use(insn_use, insn_sxt)
++       if (ext_needed)
++         break;
++     end_loop
++    
++   if (!ext_needed)
++     mark_for_replace_with_copy(I)
++end_loop
++
++For each insn, insn_sxt, in sxt_list
++   if (insn_sxt is marked for replacement)
++     replace_insn_with_copy(insn_sxt)
++end_loop
++
++--------------------------
++function: analyze_def(def)
++---------------------------
++return true if extension is needed, false otherwise.
++
++destination_operand = defined operand of source 
++source_operand = source operand of def 
++
++if (have_seen_this_insn_already (def))
++ return true;
++
++set_seen_this_insn_flag (def)
++
++analysis_result = analyze_result_def (def)
++switch (analysis_result)
++ case source_operand_is_extended:
++  return false
++ case stop_recursion:
++  return true
++ case continue_recursion: 
++  break;
++
++ext_needed = true;
++
++For all insns, insn_def, that USE and REACHED by the register of destination_operand 
++ ext_needed = analyze_def(insn_def))
++ if (ext_needed)
++  break;
++end_loop
++
++return ext_needed 
++
++--------------------------
++function: analyze_use(use)
++---------------------------
++return true if extension is needed, false otherwise.
++
++destination_operand = destination operand of use
++source_operand = source operand of use
++
++if (have_seen_this_insn_already (use))
++ return false;
++
++set_seen_this_insn_flag (use)
++
++analysis_result = analyze_result_use (use)
++switch (analysis_result)
++ case low_bits_not_affected_by_use:
++  return false
++ case low_bits_affected_by_use:
++  return true
++ case look_at_uses_of_destination_operand
++  break;
++
++ext_needed = true;
++For all insns, insn_use, that USE the register of destination_operand 
++    ext_needed = analyze_use(insn_use))
++    if (ext_needed)
++     break;
++end_loop
++
++return ext_needed 
++
++REFERENCES:
++
++"Effective Sign Extension Elimination", Kawahito, Komatsu, Nakatani. 
++IBM Tokyo Researc Laboratory.
++
++"New sign/zero extension elimination pass", deVries.
++http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01529.html
++*/
++
++/*
++Iteration 4: pre-ZERO_EXTEND version, duplicates sign_extend at uses
++Iteration 5: begin supporting ZERO_EXTEND, crashes on Coremark.
++Iteration 6: revert to 4, support SI:HI sign_extensions.
++Iteration 7: Add support for zero extend. This version deletes
++ "inserted" duplicate extensions when redundant and propagates
++ the copied value. This propagate fails in other_tests/test2.sh.
++ I am reverting back to replacing the "inserted" extension to a copy.
++ Copy propagation should always be able to eliminate this copy.
++ Coremark was stable, however.
++Iteration 8: Revert to change extensions to copy, regardless of whether
++ the extension was duplicated or not. 
++ Refactor setting of dest,src in analyze_ext_use, analyze_ext_def, now
++ handled with a single function.
++Iteration 9: 
++ Inserted redundant extensions at function return points.
++ Sorted the order that extensions are processed by loop depth.
++ Additional cases in upper_bits_do_not_affect_dest
++Iteration 10:
++ Fixes for test failures. A major problem was uncovered where
++ the "visited" flag was not properly cleared. This meant that
++ each time a new extension was processed, it appeared that some
++ extensions were visited already and there were not. The result
++ was false removals. This fix significantly affects the benchmark.
++ Another change was to comment out the duplicate_exts_at_uses. This
++ seemed to have little effect now that the visited flag issue is
++ fixed. 
++Iteration 11:
++ Cleanup warnings during build.
++Iteration 12:
++ QImode support started.
++Iteration 13:
++ Redesign and refactor analyze_ext_use, analyze_ext_def
++Iteration 14:
++ Continue redesign and refactor of analyze_ext_use, analyze_ext_def
++ Debugging paper_example.c
++Iteration 15:
++ cond_c fix
++Iteration 16: (not tested)
++ Refactor check_compare code 
++ Refactor action decision in PARALLEL 
++ Allow pass-thru on insns that are marked for replace copy 
++ instead of stopping recursion if we see a marked insn.
++ Examining lshiftrt.c program (signed and unsigned).
++Iteration 17: 
++ Refactor mostly complete. Passed all local testing including
++ nas and perfect. Best coremark results so far.
++Iteration 18:
++ Oops. analyze_ext_def was disabled. Enabling it improves
++ Coremark. Passed coremark, perfect.
++Iteration 19:
++ Local tests are passing. Tested with glibc.
++ Added statistics.
++ Fixed elimination from CALL output in operand_is_extended.
++  This impacted Coremark went from 6300 to 6170. But is necessary.
++ More safety for used regs in analyze_ext_def.
++ More safety for the types of extensions.
++Iteration 20:
++ Fixes for various tests.
++Iteration 21:
++ pr43017 -funroll_loops fix.
++Iteration 22:
++ Fixes for AND immediate in operand_is_extended.
++ Cosmetic cleanup.
++Iteration 23:
++ Fixes for consumer-2,spec2k,spec2k6. Handle 
++ SUBREG_PROMOTED_VAR_P flags on operands whose
++ dependent extension has been eliminated.
++Iteration 24:
++ Fixed problem in native build during bootstrapping.
++ Extelim was considering debug_insns and should have
++ ignored them. This resulted in a compare fail between
++ stage2 and stage3.
++Iteration 25:
++ - Post-release 4.6.1 development
++ - Full duplication of extensions at uses turned on.
++ - Recursion into original extension no longer kills optimization (analyze_ext_def only)
++ - Allow some duplication into the same block if it enables insn selection
++ - Allow CCmode and CCUNSmode into mode_supported_p
++Iteration 26:
++ - Solve ICEs due to null df-ref.
++Iteration 27:
++ - Fixed issue with duplication of extension at a self-assign.
++ - Some fixes for copying flags during duplication
++ - Some fixes for counting register uses.
++Iteration 28:
++ - Fixed issue with duplication of extension when use has multiple
++   reaching definitions.
++Iteration 29:
++ - Release candidate for Q42011 release iteration.
++Iteration 30:
++ - Turn off extension duplication - minimally effective
++Iteration 31:
++ - Turn on extension duplication for specific case to allow
++   'rldic' insn generation.
++Iteration 32:
++ - Fix issue with spec2k6 soplex where zero-extends duplicated
++   even if shift is already zero-extended.
++*/
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "tree.h"
++#include "tm_p.h"
++#include "flags.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "basic-block.h"
++#include "insn-config.h"
++#include "function.h"
++#include "expr.h"
++#include "insn-attr.h"
++#include "recog.h"
++#include "toplev.h"
++#include "target.h"
++#include "timevar.h"
++#include "optabs.h"
++#include "insn-codes.h"
++#include "rtlhooks-def.h"
++#include "output.h"
++#include "params.h"
++#include "timevar.h"
++#include "tree-pass.h"
++#include "cgraph.h"
++#include "df.h"
++#include "vec.h"
++
++/* Feature flags */
++/* Duplicate extensions at each immediate use */
++#define EXTELIM_DUPLICATE_EXTS_AT_USES 1
++/* Dump DF information also in dump */
++#define EXTELIM_DF_DUMP 0
++
++
++/* Typedefs */
++typedef unsigned int insn_flag_t;       /* Insn flags type */
++typedef int extelim_uid_t;      /* UID type */
++DEF_VEC_I (insn_flag_t);        /* Define vector type and allocation type */
++DEF_VEC_ALLOC_I (insn_flag_t, heap);
++
++typedef struct GTY (()) ext_record
++{
++  rtx ext;                      /* The extension insn */
++  VEC (rtx, heap) * ext_uses;   /* List of use records for this extension. For some
++                                   some extensions, we will duplicate the extension
++                                   at these use points. */
++  VEC (rtx, heap) * ext_updates;/* List of rtx that need to be updated if the extension
++                                   is to be eliminated. For example, SUBREG_PROMOTED flags
++                                   on SUBREG uses defined by this extension should
++                                   be reset since the extension is eliminated. The PROMOTED
++                                   flag is no longer valid. */
++} *ext_record_t;
++
++typedef struct regspec_cb_data
++{
++  unsigned int regno;
++  rtx exp;
++} regspec_cb_data_t;
++
++/* Static variables */
++DEF_VEC_P (ext_record_t);
++DEF_VEC_ALLOC_P (ext_record_t, heap);
++VEC (ext_record_t, heap) * extensions;  /* Vector holding all extension records */
++VEC (insn_flag_t, heap) * insn_flags;   /* Vector holding flags for all insns */
++VEC (rtx, heap) * returns;      /* Vector holding return insns for this function */
++
++     static extelim_uid_t max_uid;      /* Max UID insn value for insn_flags allocation */
++     static ext_record_t current_ext_record; /* Current extension record being processed */
++
++/* Statistics */
++     static int num_cand;       /* Number of extensions detected */
++     static int num_cand_ignored;       /* Number of extensions ignored */
++     static int num_cand_transformed;   /* Number of extensions transformed to copy */
++
++/* Basic information about the extension being processed */
++     enum machine_mode ext_to_mode;     /* Mode extended to */
++     enum machine_mode ext_from_mode;   /* Mode extended from */
++     enum rtx_code ext_code;    /* Sign or zero extend */
++
++/* Insn use analysis possible results */
++     enum insn_use_results
++     {
++       EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED,
++       EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED,
++       EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION
++     };
++
++/* Insn def analysis possible results */
++     enum insn_def_results
++     {
++       EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED,
++       EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION,
++       EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION
++     };
++
++/* Insn flags for this pass */
++#define       EXTELIM_NONE           0
++#define       EXTELIM_SEEN           (1<<0)     /* Mark insn as visited during DF traversal */
++#define       EXTELIM_REPLACE_COPY   (1<<1)     /* Mark ext insn as replace with copy */
++#define       EXTELIM_INSERTED       (1<<2)     /* Mark ext insn as algorithmically inserted */
++#define       EXTELIM_INSERTED_FOR   (1<<3)     /* Mark use insn for which ext has been inserted */
++
++
++/* Query the insn flag */
++
++     static bool insn_flag_p (insn_flag_t set_p, extelim_uid_t uid)
++{
++  insn_flag_t flags;
++
++  if (((flags = VEC_index (insn_flag_t, insn_flags, uid)) & set_p) == set_p)
++    return true;
++
++  return false;
++}
++
++/* Set the insn flags */
++
++static void
++insn_flag_set (insn_flag_t flags, extelim_uid_t uid)
++{
++  insn_flag_t set;
++  set = VEC_index (insn_flag_t, insn_flags, uid);
++  set |= flags;
++  VEC_replace (insn_flag_t, insn_flags, uid, set);
++}
++
++/* Clear insn flags */
++
++static void
++insn_flag_clear (insn_flag_t flags, extelim_uid_t uid)
++{
++  insn_flag_t clear;
++  clear = VEC_index (insn_flag_t, insn_flags, uid);
++  clear &= ~flags;
++  VEC_replace (insn_flag_t, insn_flags, uid, clear);
++}
++
++/* Set static variable max_uid to the largest
++   insn uid found in the module plus 1. This will be the
++   size of the vector for insn flags. */
++
++static void
++set_max_uid (void)
++{
++  basic_block bb;
++  rtx insn;
++  extelim_uid_t lmax_uid = 0;
++
++  FOR_EACH_BB (bb) FOR_BB_INSNS (bb, insn)
++  {
++    if (INSN_P (insn))
++      {
++        if (INSN_UID (insn) > lmax_uid)
++          lmax_uid = INSN_UID (insn);
++      }
++  }
++  max_uid = lmax_uid + 1;
++}
++
++/* Re-initializes the requested insn flags to their reset state */
++
++static void
++reinit_insn_flags (insn_flag_t flags_to_be_reset)
++{
++  extelim_uid_t i;
++
++  /* Account for new insns */
++  set_max_uid ();
++
++  for (i = 0; i < max_uid; i++)
++    {
++      insn_flag_clear (flags_to_be_reset, i);
++    }
++}
++
++/* Init the vector for insn flags. One
++   vector element per insn is created.
++   The flags are init'd to EXTELIM_NONE. */
++
++static void
++init_flags_vector (void)
++{
++  extelim_uid_t i;
++  /* Get the maximum uid value. We'll use this
++     information to set up a vector of max_uid
++     length. Each element of the vector will hold
++     the pass-specific flags for each insn. */
++  max_uid = 0;
++  set_max_uid ();
++
++  /* Allocate the vector of insn flags */
++  insn_flags = VEC_alloc (insn_flag_t, heap, max_uid);
++
++  /* Initialize the insn flags vector */
++  for (i = 0; i < max_uid; i++)
++    {
++      VEC_quick_insert (insn_flag_t, insn_flags, i, EXTELIM_NONE);
++    }
++}
++
++/* Initialize this pass */
++
++static void
++init_pass (void)
++{
++  /* Init insn flags vector */
++  init_flags_vector ();
++
++  /* This pass requires def-use chain information */
++  df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN);
++  df_analyze ();
++}
++
++static void
++free_extensions (void)
++{
++  ext_record_t ext_record;
++  unsigned i;
++
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, ext_record)
++  {
++    if (!VEC_empty (rtx, ext_record->ext_uses))
++      VEC_free (rtx, heap, ext_record->ext_uses);
++
++    if (!VEC_empty (rtx, ext_record->ext_updates))
++      VEC_free (rtx, heap, ext_record->ext_updates);
++  }
++  VEC_free (ext_record_t, heap, extensions);
++}
++
++/* Clean up this pass */
++
++static void
++finish_pass (void)
++{
++  free_extensions ();
++  VEC_free (insn_flag_t, heap, insn_flags);
++  VEC_free (rtx, heap, returns);
++}
++
++static void
++update_uid_vectors (extelim_uid_t uid)
++{
++  VEC_safe_grow_cleared (insn_flag_t, heap, insn_flags, uid + 1);
++}
++
++/* Emit a insn before a given insn, update vector lengths
++   of those vectors that are indexed by uid. Return uid
++   of the inserted insn. */
++
++static extelim_uid_t
++extelim_emit_before (rtx new_insn, rtx before_insn)
++{
++  rtx seq;
++  extelim_uid_t new_uid;
++
++  start_sequence ();
++  emit_insn (new_insn);
++  seq = get_insns ();
++  end_sequence ();
++  new_insn = emit_insn_before (seq, before_insn);
++
++  /* Expand the flags vector to hold the new insn and set the
++     inserted flag on the insn. */
++  new_uid = INSN_UID (new_insn);
++  update_uid_vectors (new_uid);
++  return new_uid;
++}
++
++/* Utility function to find the REG exp 
++   given an rtx */
++
++static rtx
++register_exp (rtx exp)
++{
++  if (REG_P (exp))
++    {
++      return exp;
++    }
++  else if (GET_CODE (exp) == SUBREG)
++    {
++      return SUBREG_REG (exp);
++    }
++  else
++    return NULL;
++}
++
++/* Check whether this is a sign extension.  */
++
++static bool
++extension_p (rtx insn, rtx * dest, rtx * inner, int *preserved_size)
++{
++  rtx src, op0;
++
++  /* Detect set of reg.  */
++  if (GET_CODE (PATTERN (insn)) != SET)
++    return false;
++
++  src = SET_SRC (PATTERN (insn));
++  *dest = SET_DEST (PATTERN (insn));
++
++  if (!REG_P (*dest))
++    return false;
++
++  if (GET_CODE (src) == SIGN_EXTEND || GET_CODE (src) == ZERO_EXTEND)
++    {
++      op0 = XEXP (src, 0);
++
++      /* Determine amount of least significant bits preserved by operation.  */
++      if (GET_CODE (src) == AND)
++        *preserved_size = ctz_hwi (~UINTVAL (XEXP (src, 1)));
++      else
++        *preserved_size = GET_MODE_BITSIZE (GET_MODE (op0));
++
++      if (GET_CODE (op0) == SUBREG)
++        {
++          if (subreg_lsb (op0) != 0)
++            return false;
++
++          *inner = SUBREG_REG (op0);
++          return true;
++        }
++      else if (REG_P (op0))
++        {
++          *inner = op0;
++          return true;
++        }
++    }
++
++  return false;
++}
++
++/* Return true if this is the last use of a
++   register, false otherwise.  */
++
++static bool
++reg_is_dead_p (rtx insn, rtx reg_expr)
++{
++  rtx link;
++  gcc_assert (REG_P (reg_expr));
++
++  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
++    {
++      if (REG_NOTE_KIND (link) == REG_DEAD && REG_P (XEXP (link, 0)))
++        {
++          if (REGNO (XEXP (link, 0)) == REGNO (reg_expr))
++            return true;
++        }
++    }
++  return false;
++}
++
++/* Return true if we don't want to place this
++   extension in the candidate extensions list because of the
++   previous insn. Return false otherwise. */
++
++static bool
++ignore_extension_prev_p (rtx ext_insn, rtx prev_insn)
++{
++  rtx prev_dest, prev_src, prev = PATTERN (prev_insn);
++  rtx ext_src, ext = PATTERN (ext_insn);
++
++  /* It's OK to allow extension with no accompanying prev real insn */
++  if (!NONDEBUG_INSN_P (prev_insn) || NOTE_P (prev_insn))
++    return false;
++
++  if (GET_CODE (prev) != SET)
++    return false;
++
++  if (GET_CODE (ext) != SET)
++    return false;
++
++  prev_dest = SET_DEST (prev);
++  prev_src = SET_SRC (prev);
++
++  /* Source register of sign extension */
++  ext_src = XEXP (SET_SRC (ext), 0);
++
++  /* Check previous insns */
++
++  /* Previous insn is a load whose dest is the
++     extension's source  and the dest reg is
++     dead */
++  if (MEM_P (prev_src) && (prev_dest = register_exp (prev_dest)))
++    {
++      if ((ext_src = register_exp (ext_src)))
++        {
++          if ((REGNO (prev_dest) == REGNO (ext_src))
++              && reg_is_dead_p (ext_insn, ext_src))
++            return true;
++        }
++    }
++  return false;
++}
++
++/* Return true if we don't want to place this
++   extension in the candidate extensions list because of the
++   next insn. Return false otherwise. */
++
++static bool
++ignore_extension_next_p (rtx ext_insn, rtx next_insn)
++{
++  rtx next = PATTERN (next_insn);
++  rtx ext = PATTERN (ext_insn);
++
++  if (GET_CODE (ext) != SET)
++    return false;
++
++  /* Check next insns */
++  if (!NONDEBUG_INSN_P (next_insn) || NOTE_P (next_insn))
++    return false;
++
++  if (GET_CODE (next) != SET)
++    return false;
++
++  /* zero-extend followed by left shift by 1 -- this sequence will be
++     detected by the insn selection. */
++  if (GET_CODE (SET_SRC (ext)) == ZERO_EXTEND)
++    {
++      if (GET_CODE (SET_SRC (next)) == ASHIFT
++          && CONST_INT_P (XEXP (SET_SRC (next), 1))
++          && UINTVAL (XEXP (SET_SRC (next), 1)) == 0x1)
++        return true;
++    }
++
++  return false;
++}
++
++/* Find extensions and store them in the extensions vector.  */
++
++static bool
++find_extensions (void)
++{
++  basic_block bb;
++  rtx insn, dest, inner;
++  int preserved_size;
++  ext_record_t extrec;
++
++  /* For all insns, call note_use for each use in insn.  */
++  FOR_EACH_BB (bb)
++  {
++    FOR_BB_INSNS (bb, insn)
++    {
++      if (!NONDEBUG_INSN_P (insn))
++        continue;
++
++      if (!extension_p (insn, &dest, &inner, &preserved_size))
++        {
++          continue;
++        }
++
++      /* We do not consider extensions that follow a load for
++         this target, as the code selector optimizes the sequence
++         to a load with sign extend or load with zero extend. */
++      if (PREV_INSN (insn)
++          && ignore_extension_prev_p (insn, PREV_INSN (insn)))
++        {
++          if (dump_file)
++            fprintf (dump_file, "extension at uid=%d ignored\n",
++                     INSN_UID (insn));
++          num_cand_ignored++;
++          continue;
++        }
++      /* We don't consider certain sequences that are picked up by
++         insn selection. */
++      if (NEXT_INSN (insn)
++          && ignore_extension_next_p (insn, NEXT_INSN (insn)))
++        {
++          if (dump_file)
++            fprintf (dump_file, "extension at uid=%d ignored\n",
++                     INSN_UID (insn));
++          num_cand_ignored++;
++          continue;
++        }
++
++      /* Only looking at sign extensions to DImode, SImode, or HImode  */
++      if (GET_MODE_BITSIZE (SImode) != preserved_size
++          && GET_MODE_BITSIZE (HImode) != preserved_size
++          && GET_MODE_BITSIZE (QImode) != preserved_size)
++        continue;
++
++      extrec = (ext_record_t) xmalloc (sizeof (struct ext_record));
++      extrec->ext = insn;
++      extrec->ext_uses = NULL;
++      extrec->ext_updates = NULL;
++      VEC_safe_push (ext_record_t, heap, extensions, extrec);
++      num_cand++;
++    }
++  }
++
++  if (dump_file)
++    {
++      if (!VEC_empty (ext_record_t, extensions))
++        fprintf (dump_file, "\n");
++      else
++        fprintf (dump_file, "no extensions found.\n");
++    }
++
++  return !VEC_empty (ext_record_t, extensions);
++}
++
++/* Return true if the rtx mode is a supported mode for
++   this optimization, false otherwise. */
++
++static bool
++mode_supported_p (rtx exp)
++{
++  if (GET_MODE (exp) != QImode
++      && GET_MODE (exp) != HImode
++      && GET_MODE (exp) != SImode 
++      && GET_MODE (exp) != DImode
++      && GET_MODE (exp) != CCmode
++      && GET_MODE (exp) != CCUNSmode)
++    return false;
++
++  return true;
++}
++
++/* Return true if the rtx is a function return expr, false otherwise */
++
++static bool
++return_val_p (rtx dest)
++{
++  if ((REG_P (dest) || GET_CODE (dest) == PARALLEL) &&
++      REG_FUNCTION_VALUE_P (dest))
++    {
++      return true;
++    }
++  return false;
++}
++
++
++/* A 'for_each_rtx' callback returning 1 if the rtx is a
++   REG or SUBREG rtx. The first matching rtx found stops the 
++   rtx traversal. */
++
++static int
++reg_or_subreg_rtx (rtx * x, void *data)
++{
++  regspec_cb_data_t *ldata = (regspec_cb_data_t *) data;
++
++  if (REG_P (*x))
++    {
++      ldata->exp = *x;
++      return 1;
++    }
++
++  if (GET_CODE (*x) == SUBREG)
++    {
++      ldata->exp = SUBREG_REG (*x);
++      return 1;
++    }
++
++  return 0;
++}
++
++/* A 'for_each_rtx' callback returning 1 if the rtx is a
++   REG or SUBREG rtx whose register number is that passed
++   in the data parameter. Data parameter's rtx value is
++   set to the matching rtx if found. */
++
++static int
++reg_or_subreg_rtx_regno (rtx * x, void *data)
++{
++  regspec_cb_data_t *ldata = (regspec_cb_data_t *) data;
++
++  if (REG_P (*x) && (REGNO (*x) == ldata->regno))
++    {
++      ldata->exp = *x;
++      return 1;
++    }
++  if (GET_CODE (*x) == SUBREG && (REGNO (SUBREG_REG (*x)) == ldata->regno))
++    {
++      ldata->exp = SUBREG_REG (*x);
++      return 1;
++    }
++  return 0;
++}
++
++/* Callback that counts the number of register operands
++   in an expression. Return 0 to allow all rtxs to be
++   traversed. */
++
++static int
++count_reg_operands (rtx * x, void *data)
++{
++  regspec_cb_data_t *ldata = (regspec_cb_data_t *) data;
++
++  if (register_exp (*x) != NULL)
++    {
++      ldata->regno++;
++    }
++  return 0;
++}
++
++/* Count the number of register operands in an expression.
++   We use the regspec_cb_data_t regno field as the number
++   of register operands we found in an expression. */
++
++static int
++num_reg_operands (rtx x)
++{
++  int rv;
++  regspec_cb_data_t data;
++  data.regno = 0;
++  data.exp = NULL_RTX;
++
++  if ((rv = for_each_rtx (&x, count_reg_operands, (void *) &data)) == 0)
++    return (data.regno);        /* contains the count */
++  else
++    return 0;
++}
++
++/* Find the SUBREG or REG rtx corresponding to regno in the given rtx.
++   Return NULL_RTX if the regno rtx is not found. */
++
++static rtx
++find_regspec_regno (unsigned int regno, rtx x)
++{
++  int rv;
++  regspec_cb_data_t data;
++  data.regno = regno;
++  data.exp = NULL_RTX;
++
++  if ((rv = for_each_rtx (&x, reg_or_subreg_rtx_regno, (void *) &data)) != 0)
++    return (data.exp);
++  else
++    return NULL_RTX;
++}
++
++/* Find a REG or SUBREG rtx, starting at expr x.
++   Return NULL_RTX if no REG or SUBREG rtx is found.
++   If found, the rtx returned is a REG (not SUBREG) */
++
++static rtx
++find_regspec (rtx x)
++{
++  int rv;
++  regspec_cb_data_t data;
++  data.regno = -1;              /* not used */
++  data.exp = NULL_RTX;
++
++  if ((rv = for_each_rtx (&x, reg_or_subreg_rtx, (void *) &data)) != 0)
++    return (data.exp);
++  else
++    return NULL_RTX;
++}
++
++/* Return true if the expression defines single register, regno. */
++
++static bool
++expr_defines_regno_p (rtx insn, unsigned int regno)
++{
++  rtx reg;
++  if (GET_CODE (insn) == SET)
++    {
++      reg = SET_DEST (insn);
++      if (find_regspec_regno (regno, reg) != NULL_RTX)
++        return true;
++    }
++  return false;
++}
++
++/* Return true if the insn defines a single register, regno.
++   Return false otherwise */
++
++static bool
++defines_regno_p (rtx insn_insn, unsigned int regno, int indent)
++{
++  extelim_uid_t uid = INSN_UID (insn_insn);
++  df_ref *p_def;
++
++  /* Get the operands defined */
++  p_def = DF_INSN_UID_DEFS (uid);
++
++  if (!p_def)
++    return false;
++
++  if (*(p_def + 1) != NULL)
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*suid=%d defines multiple registers\n",
++                 indent, " ", uid);
++      return false;
++    }
++
++  if (DF_REF_REGNO (*p_def) != regno)
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*suid=%d defines does not define %d\n",
++                 indent, " ", uid, regno);
++      return false;
++    }
++
++  return true;
++}
++
++/* The operand is already extended and the extension is compatible with
++   the originating extension with respect to type and size.
++   E.g. zero_extend:HI meets and AND r,#0xffff. Another example
++   is LSHIFT:SI left or right and zero_extend:SI, because the 
++   instruction selected is rlwinm and clears the upper 32 bits.
++   Other examples in the code. Return true if a compatible extension
++   is found, false otherwise. */
++
++static bool
++operand_is_extended (rtx dest, rtx srcexp, int indent)
++{
++  /* Output of a CALL is already extended. 
++     To ensure that the return value is not modified by the extend,
++     the extend from mode size must be at least the size of the CALL output. 
++     Example - this is redundant since output of CALL is extended.
++     X:SI = CALL ...
++     Y:DI = sign_extend:DI (X:SI) */
++  if (GET_CODE (srcexp) == CALL
++      && (GET_MODE_BITSIZE (ext_from_mode)) >=
++      GET_MODE_BITSIZE (GET_MODE (dest)))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...is extended already (CALL insn output)\n", indent,
++                 " ");
++      return true;
++    }
++
++  /* Output is load immediate or load constant */
++  if (CONST_INT_P (srcexp))
++    {
++      bool is_extended;
++      if (ext_from_mode == QImode && (UINTVAL (srcexp) <= 0xff))
++        is_extended = true;
++      else if (ext_from_mode == HImode && (UINTVAL (srcexp) <= 0xffff))
++        is_extended = true;
++      else if (ext_from_mode == SImode && (UINTVAL (srcexp) <= 0xffffffff))
++        is_extended = true;
++      else
++        is_extended = false;
++
++      if (is_extended)
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*s... is extended already (CONST_INT load)\n", indent,
++                     " ");
++          return true;
++        }
++    }
++
++  /* Sign extension of the same type as the originating extension.
++     Here the candidate defines the register used in the originating extension.
++     The originating extension will be replaced by a copy if it is found to be
++     redundant with respect to the candidate extension. 
++     The candidate (this extension dest,src) must write the at least the same bits as the 
++     originating extension in order to be redundant. So, we follow these rules:
++
++     cand_to_mode == machine mode of the destination for this candidate extension
++     cand_from_mode == machine mode of the source for this candidate extension
++     ext_to_mode == machine mode of the originating extension output
++     ext_from_mode == machine mode of the originating extension input
++
++     SIZE(cand_to_mode) >= SIZE(extend_to_mode) && SIZE(cand_from_mode) <= SIZE(extend_from_mode)
++
++     Example 1:
++     Candidate (HI->SI extension)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Originating (SI->DI)
++     DI       SI   HI QI 0
++     |<-------|    |  |  |
++
++     Not redundant, candidate does not cover the original bits:
++     SIZE(cand_to_mode)[SI] !>= SIZE(extend_to_mode)[DI]
++
++     Example 2:
++     Candidate (QI->DI extension)
++     DI       SI   HI QI 0
++     |<-------|----|--|  |
++
++     Originating (HI->SI)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Redundant, candidate covers the original bits:
++     SIZE(cand_to_mode) [DI] >= SIZE(extend_to_mode) [SI]
++     AND
++     SIZE(cand_from_mode) [QI] <= SIZE(extend_from_mode) [HI]
++   */
++  if (GET_CODE (srcexp) == ext_code)
++    {
++      enum machine_mode cand_from_mode = GET_MODE (XEXP (srcexp, 0));
++      enum machine_mode cand_to_mode = GET_MODE (dest);
++      if ((GET_MODE_BITSIZE (cand_to_mode) >= GET_MODE_BITSIZE (ext_to_mode))
++          && (GET_MODE_BITSIZE (cand_from_mode) <=
++              GET_MODE_BITSIZE (ext_from_mode)))
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*s...is already extended (redundant extension)\n",
++                     indent, " ");
++          return true;
++        }
++    }
++
++  /* Encountered an insn with the same effect as extension, e.g.
++     AND (regspec) (const_int). E.g. AND (reg:SI) (0x7fff) is equivalent
++     to ZERO_EXTEND:DI (reg:HI) or SIGN_EXTEND:DI (reg:HI). The code selection
++     for AND zero extends the entire register, so we don't have to
++     check that srcexp extends to at least ext_to_mode size. */
++  if ((GET_CODE (srcexp) == AND) && CONST_INT_P (XEXP (srcexp, 1)))
++    {
++      if (ext_from_mode == QImode && (UINTVAL (XEXP (srcexp, 1)) <= 0x7f))
++        return true;
++      else if (ext_from_mode == HImode
++               && (UINTVAL (XEXP (srcexp, 1)) <= 0x7fff))
++        return true;
++      else if (ext_from_mode == SImode
++               && (UINTVAL (XEXP (srcexp, 1)) <= 0x7fffffff))
++        return true;
++    }
++
++  return false;
++}
++
++/* Determine if the operation allows us to continue the propagation. 
++   We kill the propagation for all operations except copy. This
++   ensures that the extended operand that we may find eventually
++   is not modified by insns in the def-use chain. It's harsh,
++   but it's safest eliminate all but the most benign (copy) operations
++   in the propagation chain. */
++
++static bool
++continue_def_propagation (rtx srcexp)
++{
++  /* Only continue if its a copy -- that is, the srcexp is a register expression */
++  if ( register_exp (srcexp) )
++    return true;
++
++  return false;
++}
++
++/* Helper for insn_def_analysis_result.
++   The register operand, src is set here. Recall we
++   can only handle one register operand in the src expression.
++   We one of 3 states:
++   1) Determine the operand is extended, ...DEF_EXTENDED returned.
++   2) Determine the propagation can continue, ...DEF_CONTINUE_RECURSION returned. 
++   3) Otherwise, ...DEF_STOP_RECURSION is returned. */
++static enum insn_def_results
++insn_def_analysis_result_1 (rtx insn, bool treat_as_copy,
++                            unsigned int regno_def ATTRIBUTE_UNUSED,
++                            rtx * src, int indent)
++{
++  rtx dest, srcexp;
++  int num_operands;
++
++  /* Insn has to be an expression we can analyze */
++  if (GET_CODE (insn) != SET)
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*s...is not a SET expression\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++  dest = SET_DEST (insn);
++  srcexp = SET_SRC (insn);
++
++  /* Dest must be a reg, not expression */
++  if (!REG_P (dest))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...dest is not a simple register\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* First check whether the operand is extended already. If so,
++     we can leave immediately successfully. */
++  if (operand_is_extended (dest, srcexp, indent) && !treat_as_copy)
++    return (EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED);
++
++
++  /* Failing to determine that the operand is already extended, 
++     we have to validate that we have register operands to propagate. */
++  num_operands = num_reg_operands (srcexp);
++
++  /* At least one register operand required for propagation. */
++  if (num_operands == 0)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...no register operands in RHS\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* Only one register operand is allowed in the RHS since we can't
++     can't propagate more than one register. */
++  if (num_operands > 1)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...found multiple register operands in RHS\n", indent,
++                 " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* Find the used operand in the src expression */
++  *src = find_regspec (srcexp);
++  if (*src == NULL_RTX || !mode_supported_p (*src))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...src operand reg=%d cannot be found or is unsupported mode\n",
++                 indent, " ", regno_def);
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* This is an extension, but it is previously marked to be transformed to a copy.
++     We just treat it as a copy even though it hasn't been transformed yet. So 
++     continue the propagation. */
++  if (treat_as_copy)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s is treated as a copy (marked for replace)\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (srcexp)));
++      return (EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION);
++    }
++
++  /* Validate that it's ok to continue propagation with this operand. */
++  if (continue_def_propagation (srcexp))
++    return (EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION);
++
++  /* Else we default to halting the search for a redundant extension */
++  return (EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION);
++}
++
++/* Determine if the insn extends it's destination register in
++   a manner such that the original extension is redundant. */
++
++static enum insn_def_results
++insn_def_analysis_result (rtx insn_insn, unsigned int regno_def, rtx * src,
++                          int indent)
++{
++  bool treat_as_copy = false;
++
++  /* Insn must only define one output */
++  if (!defines_regno_p (insn_insn, regno_def, indent))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...defines more than 1 output\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* We want to treat this extension as a copy and continue propagation.
++     Otherwise, it would be detected again as redundant. */
++  if (insn_flag_p (EXTELIM_REPLACE_COPY, INSN_UID (insn_insn)))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d is marked to transform to copy\n", indent,
++                 " ", INSN_UID (insn_insn));
++      treat_as_copy = true;
++    }
++
++  /* Do the analysis */
++  return (insn_def_analysis_result_1
++          (PATTERN (insn_insn), treat_as_copy, regno_def, src, indent));
++}
++
++/* Analyze each of the expressions in a PARALLEL expression. As each of
++   the expressions may yield a different state, select the most conservative
++   state to return. */
++
++static enum insn_def_results
++insn_def_analysis_2 (rtx insn_def, unsigned int regno_def, rtx * src,
++                     int indent)
++{
++  int i;
++  rtx insn = PATTERN (insn_def);
++  enum insn_def_results action;
++  enum insn_def_results return_action =
++    EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++
++  gcc_assert (GET_CODE (insn) == PARALLEL);
++
++  for (i = XVECLEN (insn, 0) - 1; i >= 0; i--)
++    {
++      rtx body = XVECEXP (insn, 0, i);
++      /* Only act on the expressions that define regno_def */
++      if (!expr_defines_regno_p (body, regno_def))
++        continue;
++      /* Determine the next action */
++      action = insn_def_analysis_result_1 (body, false /* treat_as_copy */ ,
++                                           regno_def, src, indent);
++      /* The result of this expression stops the recursion, i.e. no
++         longer reasonable to continue looking at further recursion. */
++      if (action == EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION)
++        return action;
++      /* Only return EXTENDED if there are no other different actions
++         in the series. Otherwise, CONTINUE_RECURSION is returned. */
++      if (action == EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION)
++        return_action = action;
++      else if (return_action ==
++               EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION)
++        return_action = EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION;
++      else
++        return_action = action;
++    }
++  return (return_action);
++}
++
++/* Helper 1 for insn_def_analysis */
++
++static enum insn_def_results
++insn_def_analysis_1 (rtx insn_def, unsigned int regno_def, rtx * src,
++                     int indent)
++{
++  rtx def = PATTERN (insn_def);
++  enum insn_def_results action;
++
++  switch (GET_CODE (def))
++    {
++    case PARALLEL:
++      action = insn_def_analysis_2 (insn_def, regno_def, src, indent);
++      break;
++    default:
++      action = insn_def_analysis_result (insn_def, regno_def, src, indent);
++      break;
++    }
++  return action;
++}
++
++/* We look at the definition of a register that is either the
++   sign or zero extend source register or a definition that that
++   has been propagated to here via analyze_ext_def. The objective
++   is to determine, by looking at the operation and operands, whether
++   the register is sign/zero extended by virtue of the operation and/or
++   operands. If so, the original extension is redundant.
++   The function returns one of 3 possible states after analyzing the
++   insn:
++   1. EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED - we determined that the
++   insn does indeed extend the original source extension register.
++   analyze_ext_def returns FALSE, therefore, ending the recursion
++   and propagation.
++   2. EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION - we determined that 
++   the insn does not meet the criteria to continue the recursive search.
++   Some conditions causing this may be multiple operands defining this
++   register (we only propagate on a single input operand) or the insn
++   defines more than one output or the operation does not allow
++   a previous extension to propagate, e.g. an arithmetic shift on
++   a SI value clears the upper bits using rlwinm. MUL, DIV, MOD
++   stop recursion because the result is longer than the input size,
++   thus impacting the possible previous extension.
++   3. EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION - we found an
++   operation with one register operand and the operation will not
++   affect a previous extension if one exists. ADD, SUB are examples.
++   We continue looking up the chain at the definition of the operand
++   for an extended result. 
++   If we run into a previous extension marked for replacement during
++   recursion, we treat it as a copy (CONTINUE_RECURSION since the
++   extension is preserved by the copy). */
++
++static enum insn_def_results
++insn_def_analysis (rtx insn_def, unsigned int regno_def, rtx * src,
++                   int indent)
++{
++  return (insn_def_analysis_1 (insn_def, regno_def, src, indent));
++}
++
++/* Analyze the insn defining the source of the sign extension.
++   If it can be determined that the definition is already
++   sign extended, return false. Otherwise, return true if 
++   extension is needed. */
++
++static bool
++analyze_ext_def (rtx insn_def, unsigned int regno_def, int indent)
++{
++  extelim_uid_t uid;
++  rtx def = PATTERN (insn_def);
++  rtx src;
++  df_ref df_def, *p_use;
++  bool ext_needed, indent_once;
++  struct df_link *link;
++  enum insn_def_results analysis_result;
++
++  gcc_assert (def != NULL);
++
++  uid = INSN_UID (insn_def);
++
++  /* If we seen the originating extension again, return false (ext not needed) */
++  if (current_ext_record->ext == insn_def)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdef at uid=%d is original extension\n", indent, " ", uid);
++      return false;
++    }
++
++  /* The recursion has to definitively end with an operand being
++     extended (and compatible with the originating extension). If
++     we see the insn again, this could return a faulty positive (false),
++     so we return true here instead of false. See pr43017 (-funroll-loops)
++     as an example. */
++  if (insn_flag_p (EXTELIM_SEEN, uid))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdef at uid=%d is visited already\n", indent, " ", uid);
++      return true;
++    }
++
++  /* Mark this insn as seen */
++  insn_flag_set (EXTELIM_SEEN, uid);
++
++  analysis_result = insn_def_analysis (insn_def, regno_def, &src, indent);
++  switch (analysis_result)
++    {
++      /* We know conclusively that the register defined in this expression
++         is already extended. */
++    case EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED:
++      if (dump_file)
++        fprintf (dump_file, "%*sdef at uid=%d is extended\n", indent, " ",
++                 uid);
++      return false;
++      break;
++      /* We know conclusively that we cannot continue the recursion. Perhaps 
++         the expression defines multiple registers, etc. */
++    case EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION:
++      if (dump_file)
++        fprintf (dump_file, "%*sdef at uid=%d cannot be propagated\n", indent,
++                 " ", uid);
++      return true;
++      break;
++      /* Continue to look at the operands of this expression. They may be extended
++         already. */
++    case EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION:
++      break;
++    default:
++      gcc_unreachable ();
++    }
++
++  /* This is the operand for which we want to find definitions. There should
++     only be one operand as we have previously checked for operations with only
++     one register operand as the src previously. */
++  p_use = DF_INSN_UID_USES (uid);
++  gcc_assert (p_use != NULL);
++
++  /* Make sure that this use is the one returned in src. Otherwise we simply
++     stop the propagation. Note the DF_INSN_UID_USES works at the insn
++     level, so a PARALLEL pattern may return many uses, hence the need
++     to validate the correct use here. */
++  if ((*p_use == NULL) || (DF_REF_REGNO (*p_use) != REGNO (src)))
++    return true;
++
++  ext_needed = true;
++  indent_once = true;
++  for (link = DF_REF_CHAIN (*p_use); link; link = link->next)
++    {
++      rtx insn_def;
++      df_def = link->ref;
++      if (!df_def)
++        continue;
++      /* Link must be to a definition of the use */
++      if (!DF_REF_REG_DEF_P (df_def))
++        continue;
++      /* Ignore ARTIFICIAL defs */
++      if (DF_REF_IS_ARTIFICIAL (df_def))
++        continue;
++      insn_def = DF_REF_INSN (df_def);
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_def))
++        continue;
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdef of reg=%d at uid=%d\n", indent, " ",
++                 DF_REF_REGNO (df_def), INSN_UID (insn_def));
++      /* Set indent for dump formatting */
++      if (indent_once)
++        {
++          ++indent;
++          indent_once = false;
++        }
++      ext_needed = analyze_ext_def (insn_def, DF_REF_REGNO (df_def), indent);
++      if (ext_needed)
++        break;
++    }
++
++  if (dump_file)
++    fprintf (dump_file,
++             "%*sext %s needed\n", indent, " ", ext_needed ? "" : "not");
++
++  return ext_needed;
++}
++
++/* Determine whether the expression needs to be saved for this extension.
++   The expression will be updated in some way if the extension is ultimately
++   eliminated. */
++
++static bool
++exp_needs_update_p (rtx exp)
++{
++  if (GET_CODE (exp) == SUBREG
++      && (SUBREG_PROMOTED_VAR_P (exp)))
++    {
++      return true;
++    }
++  return false;
++}
++
++/* Some expressions may need to be updated if the originating extension
++   is eliminated. For example, SUBREG_PROMOTED flags on uses are no longer
++   valid if the extension is eliminated. Save the expression here. */
++
++static void
++save_ext_update (ext_record_t extrec, rtx exp)
++{
++  /* Save this expression to be updated if the extension is eliminated. */
++  VEC_safe_push (rtx, heap, extrec->ext_updates, exp);
++}
++
++/* Check a compare operation to determine whether the operands
++   of the compare use the upper bits of the extension. Return
++   true if the upper bits are not relevant in the compare, false
++   otherwise. */
++
++static bool
++check_compare (rtx dest, rtx src)
++{
++  /* Detect 
++     (set (reg:CC r0) (compare:CC (REGSPEC) (REGSPEC)))
++     or
++     (set (reg:CC r0) (compare:CC (REGSPEC) (CONST)))
++     where REGSPEC is (reg:mm r) or (subreg:mm (reg:MM r) n) 
++     CONST is a constant integer.
++     The mode size of compare ops must be less than the
++     mode of the original extension for the upper bits to
++     be irrelevant. 
++     An exception is made for mode sizes less than a word size.
++     For our targets, there is no 'cmph' insn, so we bail out 
++     if we see a comparison of sizes less than a word (SI). */
++  if (REG_P (dest)
++      && (GET_MODE (dest) == CCmode || GET_MODE (dest) == CCUNSmode)
++      && GET_CODE (src) == COMPARE
++      && (GET_MODE (src) == CCmode || GET_MODE (src) == CCUNSmode))
++    {
++      rtx compare_op0 = XEXP (src, 0);
++      rtx compare_op1 = XEXP (src, 1);
++
++      /* Check the first operand, op0, size. */
++      if ((REG_P (compare_op0) || GET_CODE (compare_op0) == SUBREG)
++          && (GET_MODE_BITSIZE (GET_MODE (compare_op0)) <=
++              GET_MODE_BITSIZE (ext_from_mode)))
++        {
++          /* Half word compares and smaller are performed as word compares, so upper bits are used. */
++          if (GET_MODE_BITSIZE (GET_MODE (compare_op0)) < SImode)
++            return false;
++
++          /* Now check the other operand, op1. */
++          if ((REG_P (compare_op1) || GET_CODE (compare_op1) == SUBREG)
++              && (GET_MODE_BITSIZE (GET_MODE (compare_op1)) <=
++                  GET_MODE_BITSIZE (ext_from_mode)))
++            return true;
++
++          /* Compare to constant, we know op0 already meets size constraints. */
++          if (CONST_INT_P (compare_op1))
++            return true;
++        }
++    }
++  return false;
++}
++
++/* Determine condition a, whether the upper bits are relevant to the operation.
++   Return false if we prove the upper bits are not relevant in the operation,
++   true otherwise. */
++
++static bool
++operation_uses_upper_bits (rtx dest, rtx src, unsigned int regno_use,
++                           int indent ATTRIBUTE_UNUSED)
++{
++  rtx regspec_src = find_regspec_regno (regno_use, src);
++
++  if (check_compare (dest, src))
++    return false;
++
++  /* Store of regno to mem, size stored is the same or smaller than the extended from size */
++  if (MEM_P (dest)
++      && (GET_MODE_BITSIZE (GET_MODE (dest)) <=
++          GET_MODE_BITSIZE (ext_from_mode))
++      /* Ensure the used register is being stored and not used in another capacity, say, as a pointer. */
++      && (regspec_src))
++    return false;
++
++  /* Operation operand size is the same or smaller than the extended from size */
++  if (regspec_src)
++    {
++      if (GET_MODE_BITSIZE (GET_MODE (regspec_src)) <=
++          GET_MODE_BITSIZE (ext_from_mode))
++        return false;
++    }
++
++  /* Default to the safest result */
++  return true;
++}
++
++/* Determine if this insn also extends to the size or greater of the original extension.
++   Sign extend can propagate to zero extend and vice-versa because the upper bits
++   haven't affected the low bits up to now throughout the propagation. */
++
++static bool
++operation_extends_to_upper_bits_size (rtx src, int indent ATTRIBUTE_UNUSED)
++{
++  /* Sign extension of the same type as the originating extension.
++     Here the candidate uses the register defined by the originating extension.
++     If the candidate is found to be redundant, the originating extension is
++     replaced with a copy.
++
++     We follow these rules:
++
++     dest_mode == machine mode of the destination for this candidate extension
++     (it's the same mode as the src, e,g, reg:DI = sign_extend:DI ...)
++     src_mode == machine mode of the source for this candidate extension
++     (the mode of the used register, SI in this case, e.g. reg:DI = sign_extend:DI (subreg:SI (reg:DI))
++     ext_to_mode == machine mode of the originating extension output
++     ext_from_mode == machine mode of the originating extension input
++
++     SIZE(cand_from_mode) >= SIZE(extend_from_mode) && SIZE(cand_to_mode) <= SIZE(extend_to_mode)  
++
++     Example 1:
++     Originating (SI->DI)
++     DI       SI   HI QI 0
++     |<-------|    |  |  |
++
++     Candidate (HI->SI extension)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Not redundant, candidate does not cover the original bits:
++     SIZE(dest_mode)[SI] !<= SIZE(extend_to_mode)[DI]
++
++     Example 2:
++     Originating (HI->SI)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Candidate (QI->DI extension)
++     DI       SI   HI QI 0
++     |<-------|----|--|  |
++
++     Redundant, candidate covers the original bits:
++     SIZE(cand_to_mode) [DI] >= SIZE(extend_to_mode) [SI]
++     AND
++     SIZE(cand_from_mode) [QI] <= SIZE(extend_from_mode) [HI] */
++  if (GET_CODE (src) == ext_code)
++    {
++      /* Extend is redundant if we don't overwrite the source of the
++         previous extension and extends to at least the extent of the original. */
++      enum machine_mode cand_from_mode = GET_MODE (XEXP (src, 0));
++      enum machine_mode cand_to_mode = GET_MODE (src);
++      if (GET_MODE_BITSIZE (cand_from_mode) >=
++          GET_MODE_BITSIZE (ext_from_mode)
++          && (GET_MODE_BITSIZE (cand_to_mode) <=
++              GET_MODE_BITSIZE (ext_to_mode)))
++        return true;
++    }
++
++  /* Encountered an insn with the same effect as extension, e.g.
++     AND (regspec) (const_int). E.g. AND (reg:SI) (0xffff) is equivalent
++     to ZERO_EXTEND:DI (reg:HI) */
++  if ((GET_CODE (src) == AND) && CONST_INT_P (XEXP (src, 1)))
++    {
++      /* Extends to at least the original extension size */
++      if (GET_MODE_BITSIZE (GET_MODE (src)) >= GET_MODE_BITSIZE (ext_to_mode))
++        {
++          if (ext_from_mode == QImode && (UINTVAL (XEXP (src, 1)) <= 0xff))
++            return true;
++          else if (ext_from_mode == HImode
++                   && (UINTVAL (XEXP (src, 1)) <= 0xffff))
++            return true;
++          else if (ext_from_mode == SImode
++                   && (UINTVAL (XEXP (src, 1)) <= 0xffffffff))
++            return true;
++          else
++            return false;
++        }
++    }
++  return false;
++}
++
++/* Determine whether the operation's upper bits subtly or overtly affects the low bits. */
++
++static bool
++operation_implicitly_affects_lowbits (rtx dest, rtx src,
++                                      unsigned int regno_use, int indent)
++{
++  rtx regspec = find_regspec_regno (regno_use, src);
++
++  /* First, a return expression must be assumed to affect the lowbits as the return value
++     must be extended properly. */
++  if (return_val_p (dest))
++    {
++      if (dump_file)
++        {
++          fprintf (dump_file, "%*sDestination is a return value\n", indent,
++                   " ");
++        }
++      return true;
++    }
++
++  /* These operations implicitly affect the lowbits, except where noted. */
++  switch (GET_CODE (src))
++    {
++    case MULT:
++    case DIV:
++    case UDIV:
++    case UMOD:
++    case MOD:
++      /* Normally, yes, these operations return true (affects low bits). But when the 
++         the operand size is less than or equal to the "low bits" size AND the operation size
++         is the same as the operand size, the operation is performed only on the "low bits"
++         and the "upper bits" do not contribute to the output. */
++      if (regspec
++          && (GET_MODE_BITSIZE (GET_MODE (regspec)) <=
++              GET_MODE_BITSIZE (ext_from_mode))
++          && GET_MODE_BITSIZE (GET_MODE (src)) ==
++          GET_MODE_BITSIZE (GET_MODE (regspec)))
++        return false;
++      return true;
++
++      break;
++      /* Shift rights normally affect the low bits. There can be special cases where this
++         is not true, such a the operand size is smaller than the extended from size, e.g.
++         set (reg:SI Y) (zero_extend:SI (subreg:HI (reg:SI X)))
++         set (reg:QI Z) (lshiftrt (subreg:QI (reg:SI Y))
++         The shift of the QI data is not affected by the extension of HI data unless the
++         shift is large enough to encroach into the QI bits. This seems rare and I do not
++         check for it. */
++    case LSHIFTRT:
++    case ASHIFTRT:
++      return true;
++      break;
++      /* Other operations are known not to impact the low bits */
++    default:
++      return false;
++    }
++
++}
++
++/* The operation directly defines a propagatable output. Several
++   operations do not define such output. E.g. MEM (loads) do not
++   define an output based on the operation. USE is another example,
++   as it isn't a real operation. */
++
++static bool
++operation_directly_defines_an_output (rtx dest, rtx src,
++                                      int indent ATTRIBUTE_UNUSED)
++{
++  switch (GET_CODE (src))
++    {
++    case REG:
++    case SUBREG:
++    case PLUS:
++    case MINUS:
++    case NEG:
++    case MULT:
++    case DIV:
++    case MOD:
++    case UDIV:
++    case UMOD:
++    case AND:
++    case IOR:
++    case XOR:
++    case NOT:
++    case ASHIFT:
++    case ROTATE:
++    case ASHIFTRT:
++    case LSHIFTRT:
++    case ROTATERT:
++    case SIGN_EXTEND:
++    case ZERO_EXTEND:
++    case TRUNCATE:
++      return true;
++      break;
++      /* OK to propagate if the output of IF_THEN_ELSE is a register */
++    case IF_THEN_ELSE:
++      if (REG_P (dest))
++        return true;
++      break;
++      /* All others are assumed not to generate a normal output */
++    default:
++      break;
++    }
++  return false;
++}
++
++/* Helper for insn_use_analysis_result */
++
++static enum insn_use_results
++insn_use_analysis_result_1 (rtx insn, bool treat_as_copy,
++                            unsigned int regno_use, rtx * dest, int indent)
++{
++  rtx src;
++  bool cond_a, cond_b, cond_c, cond_d;
++
++  if (GET_CODE (insn) != SET)
++    return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++
++  *dest = SET_DEST (insn);
++  src = SET_SRC (insn);
++
++  /* Bail out on inline assembly also */
++  if (GET_CODE (src) == ASM_INPUT || GET_CODE (src) == ASM_OPERANDS)
++    return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++
++  /* Bail out on non supported types */
++  if (!mode_supported_p (*dest))
++    return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++
++  /* First, we determine cond_c (is a redundant extension) because it gates the
++     other conditions. */
++  if ((cond_c = operation_extends_to_upper_bits_size (src, indent)))
++    {
++      if (treat_as_copy)
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*s...%s is treated as a copy (marked for replace)\n",
++                     indent, " ", GET_RTX_NAME (GET_CODE (src)));
++          return EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION;
++        }
++
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s is a redundant extension\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED;
++    }
++
++  cond_a = operation_uses_upper_bits (*dest, src, regno_use, indent);
++
++  cond_b =
++    operation_implicitly_affects_lowbits (*dest, src, regno_use, indent);
++
++  cond_d = operation_directly_defines_an_output (*dest, src, indent);
++
++  /* Operation implicitly affects low bits */
++  if (cond_b)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s implicitly affects low bits\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++    }
++
++  /* Neither cond_a nor cond_b affects the low bits */
++  if (!cond_a)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s does not use upper bits\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED;
++    }
++
++  /* To continue recursion, the operation must define a 
++     meaningful output. */
++  if (!cond_d)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s does not define a propagatable output\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++    }
++
++  /* This leaves cond_a, meaning we need to continue down the chain
++     to see if the low bits are ultimately affected by the upper bits. */
++  return EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION;
++}
++
++/* Determine the action based on the insn conditions. The truth table is
++   simplified using if statements. Insns previously marked for replace by copy
++   are identified, these will be essentially be treated as copies now and not
++   be detected as redundant for this use. */
++static enum insn_use_results
++insn_use_analysis_result (rtx insn_insn, unsigned int regno_use, rtx * dest,
++                          int indent)
++{
++  bool treat_as_copy = false;
++  if (insn_flag_p (EXTELIM_REPLACE_COPY, INSN_UID (insn_insn)))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d is marked to transform to copy\n", indent,
++                 " ", INSN_UID (insn_insn));
++      treat_as_copy = true;
++    }
++  return (insn_use_analysis_result_1
++          (PATTERN (insn_insn), treat_as_copy, regno_use, dest, indent));
++}
++
++/* We have to analyze each expression action in a PARALLEL series.
++   Return the appropriate action for a series of expressions in a PARALLEL insn. 
++   LOWBITS_AFFECTED stops the loop. This leaves only CONTINUE_RECURSION
++   or LOWBITS_NOT_AFFECTED. LOWBITS_NOT_AFFECTED is only returned
++   if there are no other different actions in the series (no CONTINUE_RECURSION
++   states). For each CONTINUE_RECURSION action we encounter, the destination
++   registers must be identical since we can only propagate one use (one definition
++   of dest) should CONTINUE_RECURSION be returned. */
++
++static enum insn_use_results
++analyze_action (enum insn_use_results cur_action,
++                enum insn_use_results prev_action,
++                rtx * dest, rtx * prev_dest)
++{
++  enum insn_use_results return_action;
++
++  if (cur_action == EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED)
++    return cur_action;
++
++  if (cur_action == EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION)
++    return_action = cur_action;
++  else if (prev_action == EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION)
++    return_action = EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION;
++  else
++    return_action = cur_action;
++
++  if (return_action == EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION)
++    {
++      if (*prev_dest)
++        {
++          /* All bets off if the series defines multiple outputs */
++          if (*prev_dest != *dest)
++            return_action = EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++        }
++    }
++  /* Set prev_dest */
++  *prev_dest = *dest;
++
++  return return_action;
++}
++
++/* Helper 2 for insn_use_analysis. Return the appropriate action
++   for a series of expressions in a PARALLEL insn. */
++
++static enum insn_use_results
++insn_use_analysis_2 (rtx insn_use, unsigned int regno_use, rtx * dest,
++                     int indent)
++{
++  int i;
++  rtx insn = PATTERN (insn_use);
++  rtx prev_dest = NULL_RTX;
++  enum insn_use_results action;
++  enum insn_use_results return_action =
++    EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED;
++
++  gcc_assert (GET_CODE (insn) == PARALLEL);
++
++  /* We make a quick decision about call_insns here. Since the use reached
++     a call, we assume it's an outgoing parameter and thus must be extended
++     as per the ABI. */
++  if (CALL_P (insn_use))
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*s...is a call parameter\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++    }
++
++  for (i = XVECLEN (insn, 0) - 1; i >= 0; i--)
++    {
++      rtx body = XVECEXP (insn, 0, i);
++      /* Only act on the expressions containing a use of regno_use. */
++      if (regno_use_in (regno_use, body) == NULL_RTX)
++        continue;
++
++      /* Determine the next action */
++      action = insn_use_analysis_result_1 (body, false /* treat as copy */ ,
++                                           regno_use, dest, indent);
++
++      /* Here we make a decision on the return action based on the previous actions.
++         This is done to accomodate different actions from different elements in the
++         PARALLEL series of expressions. */
++      return_action =
++        analyze_action (action, return_action, dest, &prev_dest);
++
++      /* The result of this expression stops the recursion, i.e.  "low bits"
++         are affected by the operation. */
++      if (return_action == EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED)
++        break;
++    }
++  return (return_action);
++}
++
++/* Helper 1 for insn_use_analysis */
++
++static enum insn_use_results
++insn_use_analysis_1 (rtx insn_use, unsigned int regno_use, rtx * dest,
++                     int indent)
++{
++  rtx use = PATTERN (insn_use);
++  enum insn_use_results action;
++
++  switch (GET_CODE (use))
++    {
++    case PARALLEL:
++      action = insn_use_analysis_2 (insn_use, regno_use, dest, indent);
++      break;
++    default:
++      action = insn_use_analysis_result (insn_use, regno_use, dest, indent);
++      break;
++    }
++
++  return action;
++}
++
++/* Analyze the insn and determine the next course of action in the
++   use analysis loop.
++   There are several conditions to consider:
++
++   1. The "extended from" mode. This is an enum machine_mode value
++   that determines what is the size extended. It is derived from the
++   source of the original extension. It is the "low bits" value.
++   It is these range of bits that cannot be affected by the operation's
++   "upper bits" in order to determine whether the extend is useful or not.
++   Examples: 
++   (1) set (reg:DI Y (zero_extend:DI (subreg:QI (reg:DI X))) ==> low bits = QI
++   (2) set (reg:SI Y (sign_extend:SI (reg:HI X) ==> low bits = HI
++
++   2. The "extend to" mode. This is the size extended to in the original
++   extension. It is the "upper bits" value. The entire extended to size may 
++   be used subsequently or it may be subreg'd to a smaller or larger sizes 
++   later in the propagation.
++   For example (1) above, "upper bits" is DI, and (2) "upper bits" is SI.
++
++   3. The code, ext_code, of the original extension, either ZERO_EXTEND or SIGN_EXTEND.
++
++   4. Operation code. For an insn, the actual operation code corresponding to
++   a machine instruction. For certain codes, we know that the "low bits" of the
++   result are modified by the insn because of the values in the "upper bits" of the
++   input operand. We say the operation implicitly uses the "upper bits" to modify the
++   "low bits". For other codes, the "upper bits" do not affect the output result
++   in the "low bits". 
++
++   If the operation does implicitly use the "upper bits" to modify
++   the "low bits", it is instantly a deal killer. The original extension must be 
++   preserved. 
++
++   If the operation does not implicitly use "upper bits" to modify the "low bits",
++   then the action to take depends on the operation operand size relative to 
++   "low bits" size.
++
++   We only want to deal with codes that map to real instructions,
++   like ADD, SUB, MULT, LSHIFTRT, etc. Codes such as PARALLEL, etc. do not map to
++   instruction and must be dissected to extract the real instructions.
++
++   Furthermode, for recursion to continue, the operation and operand must define
++   an output related to the input operand (the use register). This doesn't happen
++   for operations such as "mem" where the output is indirectly related to the
++   input operand. 
++
++   5. Operation mode. The operation mode of the operation code. This sometimes impacts
++   the effect of the operation. For example MULT:SI and MULT:DI map to two different
++   machine instructions and both may have operands of SI mode. However, the MULT:SI 
++   results will be oblivious to the upper bits of the DI register whereas, SI part of
++   MULT:DI result will be affected by the upper bits of the DI register.
++
++   Several conditions determine the action to take based on the various inputs.
++
++   The truth table inputs are A, B, and C. The truth table output is the action to take. 
++
++   A. True if the used operand mode size is greater than the extended_from ("low bits") mode size.
++   B. True if the operation implicitly uses upper bits to define the low bits  
++   C. True if the operation also extends the output to upper bits size
++   D. True if the operation and input operand directly define an output operand.
++
++   Condition A. means the upper bits are in use in the operation. The extend _may_ be needed, 
++   all things being equal, so the action would be to continue recursion to the use of the
++   defined operand, i.e. return CONTINUE_RECURSION.
++
++   Condition B. means the "low bits" are modified by the extended portion of the register
++   by virtue of the operation. For example, logical shift right, where the extended
++   portion is shifted into the "low bits". Another example, multiply, where the machine
++   uses the extended portion implicitly to calculate the results, some of which are 
++   reflected in the "low bits" of the result. The extension is definitely needed in these 
++   cases for this use, so return LOWBITS_AFFECTED. Recursion is stopped and analysis of 
++   this extension is halted.
++
++   Condition C. means the operation and it's operands perform the same extension as
++   the originating extension. The operation must extend to the same size _or higher_ of
++   the original extension. In this case, the original extension is truly redundant and
++   we return LOWBITS_NOT_AFFECTED for this use.
++
++   Condtion D. means the operation and operand directly define an output operand. For most
++   arithmetic and unary operations this is true. For mem and other internal operations,
++   e.g. USE, this is false.
++
++      Condition                      Action                 Comments
++    ==================================================================
++    A.     B.     C.     D.
++    ------------------------------------------------------------------
++    X      X      true   true     LOW_BITS_NOT_AFFECTED  extend is redundant
++    ------------------------------------------------------------------
++    false  false  false  X        LOW_BITS_NOT_AFFECTED  used operand is smaller than "low bits"
++    ------------------------------------------------------------------
++    false  true   false  true     LOW_BITS_AFFECTED      "low bits" modified implicitly by operation
++    ------------------------------------------------------------------
++    true   false  false  true     CONTINUE_RECURSION     "low bits" _may_ be impacted by next uses
++    ------------------------------------------------------------------
++    true   true   false  true     LOW_BITS_AFFECTED      "low bits" modified implicitly by operation */
++
++static enum insn_use_results
++insn_use_analysis (rtx insn_use, unsigned int regno_use, rtx * dest,
++                   int indent)
++{
++  return (insn_use_analysis_1 (insn_use, regno_use, dest, indent));
++}
++
++/* Analyze the operation and operands of this use of a sign extension
++   target register. If the target register's upper bits do not
++   affect the result of the operation, then the sign extension is
++   useless. Returns true if the extension is needed, false 
++   otherwise. */
++
++static bool
++analyze_ext_use (rtx insn_use, unsigned int regno_use, int indent)
++{
++  bool ext_needed, indent_once;
++  unsigned int dest_target_regno;
++  extelim_uid_t uid;
++  rtx use = PATTERN (insn_use), dest;
++  df_ref df_use, *p_def;
++  struct df_link *link;
++  enum insn_use_results analysis_result;
++
++  gcc_assert (use != NULL);
++
++  uid = INSN_UID (insn_use);
++
++  if (insn_flag_p (EXTELIM_SEEN, uid))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d is visited already\n", indent, " ", uid);
++      return false;
++    }
++
++  /* Mark this insn as seen */
++  insn_flag_set (EXTELIM_SEEN, uid);
++
++  analysis_result = insn_use_analysis (insn_use, regno_use, &dest, indent);
++  switch (analysis_result)
++    {
++      /* We know conclusively that the "upper bits" of the extended
++         entity do not impact the "low bits" of the output of the operation. */
++    case EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED:
++      if (dump_file)
++        fprintf (dump_file, "%*suse at uid=%d is not affected\n", indent, " ",
++                 uid);
++      return false;
++      break;
++      /* We know conclusively that the "upper bits" of the extended
++         entity _do_ impact the "low bits" of the output of the operation. */
++    case EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED:
++      if (dump_file)
++        fprintf (dump_file, "%*suse at uid=%d is affected\n", indent, " ",
++                 uid);
++      return true;
++      break;
++      /* Continue to look at the uses of the result to determine the impact
++         of the "upper bits" */
++    case EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION:
++      break;
++    default:
++      gcc_unreachable ();
++    }
++
++  /* We reach here because the action taken is CONTINUE_RECURSION.
++     Continue to look at the uses of the destination register recursively. 
++     If the propagation ultimately ends where the upper bits are not significant 
++     to the final output, then the extension can be removed. */
++  if (!REG_P (dest))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdest of uid=%d (SET) is not a register\n", indent, " ",
++                 uid);
++      return true;
++    }
++
++  dest_target_regno = REGNO (dest);
++
++  /* What this insn defines */
++  p_def = DF_INSN_UID_DEFS (uid);
++
++  /* Ref must be valid and there must be only one definition and it must be the
++     destination */
++  if ((*p_def == NULL) || (*(p_def + 1) != NULL))
++    return true;
++
++  gcc_assert (DF_REF_REGNO (*p_def) == dest_target_regno);
++
++  ext_needed = true;
++  indent_once = true;
++  for (link = DF_REF_CHAIN (*p_def); link; link = link->next)
++    {
++      rtx insn_use, use_exp;
++      df_use = link->ref;
++      if (!df_use)
++        continue;
++      /* Link must be a USE of the DEF */
++      if (!DF_REF_REG_USE_P (df_use))
++        continue;
++      /* Ignore ARTIFICIAL USES */
++      if (DF_REF_IS_ARTIFICIAL (df_use))
++        continue;
++      insn_use = DF_REF_INSN (df_use);
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_use))
++        continue;
++      use_exp = DF_REF_REG (df_use);
++
++      if (exp_needs_update_p (use_exp))
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*ssaved reg=%d expression for update\n", indent, " ", DF_REF_REGNO (df_use));
++          save_ext_update (current_ext_record, use_exp);
++        }
++
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d of reg=%d\n", indent, " ",
++                 INSN_UID (insn_use), DF_REF_REGNO (df_use));
++      /* Set indent for dump formatting */
++      if (indent_once)
++        {
++          ++indent;
++          indent_once = false;
++        }
++      ext_needed = analyze_ext_use (insn_use, DF_REF_REGNO (df_use), indent);
++      if (ext_needed)
++        break;
++    }
++
++  if (dump_file)
++    fprintf (dump_file,
++             "%*sext %s needed\n", indent, " ", ext_needed ? "" : "not");
++
++  return ext_needed;
++}
++
++/* Set a flag on an insn indicating that it is
++   marked for replacement by a copy insn or for
++   deletion. */
++
++static void
++mark_replace_with_copy (rtx ext)
++{
++  extelim_uid_t uid = INSN_UID (ext);
++  insn_flag_set (EXTELIM_REPLACE_COPY, uid);
++}
++
++/* Get the mode that we are sign/zero extending from */
++
++static enum machine_mode
++get_ext_from_mode (rtx src)
++{
++  rtx regexp;
++  gcc_assert (GET_CODE (src) == ZERO_EXTEND || GET_CODE (src) == SIGN_EXTEND);
++
++  /* The SUBREG or REG mode of the extend operand */
++  regexp = XEXP (src, 0);
++  return (GET_MODE (regexp));
++}
++
++/* Perform the action on the expression. Return true
++   if any action performed, false otherwise. */
++
++static bool 
++process_ext_update (rtx exp)
++{
++  /* Reset SUBREG_PROMOTED state to false */
++  if (GET_CODE (exp) == SUBREG
++      && SUBREG_PROMOTED_VAR_P (exp))
++    {
++      SUBREG_PROMOTED_VAR_P (exp) = 0;
++      return true;
++    }
++
++  return false;
++}
++
++/* Process the current extension record, looking at all the
++   the expressions that need to be updated because this
++   extension will be replaced by a copy. */
++
++static void
++process_ext_updates (ext_record_t extrec)
++{
++  unsigned i;
++  rtx exp;
++  bool updated=false;
++
++
++  FOR_EACH_VEC_ELT (rtx, extrec->ext_updates, i, exp)
++    {
++      updated |= process_ext_update (exp);
++    }
++
++  if (dump_file && updated)
++    fprintf (dump_file, " updates processed for extension at uid=%d\n",
++             INSN_UID (extrec->ext));
++}
++
++/* Try to eliminate the sign extension by examining the
++   definitions of the extension source and the uses
++   of the extension destination. */
++
++static void
++eliminate_one_extend (rtx ext)
++{
++  rtx src, dest, regexp;
++  df_ref df_use, df_def, *ext_use, *ext_def;
++  unsigned int ext_dest_regno, ext_src_regno, def_use_count = 1;
++  bool ext_needed = true;
++  extelim_uid_t uid = INSN_UID (ext);
++  struct df_link *link;
++  const char *inserted =
++    insn_flag_p (EXTELIM_INSERTED, uid) ? "inserted" : "";
++
++  /* Reset desired per insn flags for each extension analyzed */
++  reinit_insn_flags (EXTELIM_SEEN);
++
++  gcc_assert (GET_CODE (PATTERN (ext)) == SET);
++  src = SET_SRC (PATTERN (ext));
++  dest = SET_DEST (PATTERN (ext));
++
++  /* Save the basic information about the extension in a file global */
++  ext_to_mode = GET_MODE (dest);
++  ext_from_mode = get_ext_from_mode (src);
++  ext_code = GET_CODE (src);
++
++  /* Also mark this original extension as "SEEN" so we don't recurse into it. */
++  insn_flag_set (EXTELIM_SEEN, INSN_UID (ext));
++
++  /* Find the target of the extension */
++  if (!REG_P (dest))
++    return;
++  ext_dest_regno = REGNO (dest);
++
++  /* Find the source of the extension: set (REG:MODE (sign_extend (REG|SUBREG:MODE ... */
++  if ((regexp = register_exp (XEXP (src, 0))) == NULL)
++    return;
++  ext_src_regno = REGNO (regexp);
++
++  /* Iterate through the reaching definitions of the source of the extension 
++     recursively. If the source if already sign extended, mark the 
++     extension for replacement with a copy or deletion (deletion if it was
++     inserted in the duplication pass). */
++  ext_use = DF_INSN_UID_USES (uid);
++  /* There is only one use in a sign/zero extension insn and it must be the
++     source register */
++  gcc_assert (*(ext_use + 1) == NULL);
++  gcc_assert (DF_REF_REGNO (*ext_use) == ext_src_regno);
++
++  /* Now look at all the reaching definitions of this use */
++  for (link = DF_REF_CHAIN (*ext_use); link; link = link->next)
++    {
++      rtx insn_def;
++      df_def = link->ref;
++      if (!df_def)
++        continue;
++      /* Link must be to a definition of the use */
++      if (!DF_REF_REG_DEF_P (df_def))
++        continue;
++      /* Ignore ARTIFICIAL defs */
++      if (DF_REF_IS_ARTIFICIAL (df_def))
++        continue;
++      insn_def = DF_REF_INSN (df_def);
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_def))
++        continue;
++      if (dump_file)
++        fprintf (dump_file,
++                 " analyze def #%d of reg=%d at uid=%u\n",
++                 def_use_count, DF_REF_REGNO (*ext_use), INSN_UID (insn_def));
++      ext_needed = analyze_ext_def (insn_def, DF_REF_REGNO (*ext_use), 2);
++      if (ext_needed)
++        break;
++      def_use_count++;
++    }
++
++  /* Try the def-use chains if the extension wasn't marked by the
++     previous pass. */
++  if (ext_needed)
++    {
++      /* Defs of the sign extension */
++      ext_def = DF_INSN_UID_DEFS (uid);
++      /* There is only one def in a sign extension insn and it must be the
++         destination */
++      gcc_assert (*(ext_def + 1) == NULL);
++      gcc_assert (DF_REF_REGNO (*ext_def) == ext_dest_regno);
++
++      /* Counter for debug dump */
++      def_use_count = 1;
++      /* Reset desired per insn flags for each extension analyzed */
++      reinit_insn_flags (EXTELIM_SEEN);
++      /* Also mark this original extension as "SEEN" so we don't recurse into it. */
++      insn_flag_set (EXTELIM_SEEN, INSN_UID (ext));
++
++      /* Iterate over the reached uses of extension destination register recursively.
++         If the destination register's upper bits are ultimately not
++         relevant, the extension can be marked for replacement with a
++         copy. */
++      for (link = DF_REF_CHAIN (*ext_def); link; link = link->next)
++        {
++          rtx insn_use, use_exp;
++          df_use = link->ref;
++          if (!df_use)
++            continue;
++          /* Link must be a USE of the DEF */
++          if (!DF_REF_REG_USE_P (df_use))
++            continue;
++          /* Ignore ARTIFICIAL USES */
++          if (DF_REF_IS_ARTIFICIAL (df_use))
++            continue;
++          insn_use = DF_REF_INSN (df_use);
++          /* Don't consider debug_insns */
++          if (!NONDEBUG_INSN_P (insn_use))
++            continue;
++          use_exp = DF_REF_REG (df_use);
++
++          if (exp_needs_update_p (use_exp))
++            {
++              if (dump_file)
++                fprintf (dump_file,
++                         " saved reg=%d expression for update\n", DF_REF_REGNO (df_use));
++              save_ext_update (current_ext_record, use_exp);
++            }
++            
++          if (dump_file)
++            fprintf (dump_file,
++                     " analyze use #%d at uid=%u of reg=%d\n",
++                     def_use_count, INSN_UID (insn_use),
++                     DF_REF_REGNO (*ext_def));
++          ext_needed = analyze_ext_use (insn_use, DF_REF_REGNO (*ext_def), 2);
++          if (ext_needed)
++            break;
++          def_use_count++;
++        }
++    }
++
++  /* The extension is not needed. The rtl for the extension is marked
++     for replace by copy. */
++  if (!ext_needed)
++    {
++      process_ext_updates (current_ext_record);
++
++      if (dump_file)
++        fprintf (dump_file,
++                 ":) mark %s extension insn uid=%d for copy replacement\n",
++                 inserted, INSN_UID (ext));
++      mark_replace_with_copy (ext);
++      num_cand_transformed++;
++    }
++  else
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 ":( %s extension insn uid=%d is needed\n", inserted,
++                 INSN_UID (ext));
++    }
++}
++
++/* Replace the sign extension with a copy instruction
++
++   example 1:
++   from:
++        dest              src
++   (set (reg:DI destreg) (sign_extend:DI (reg:SI srcreg)))
++   to:
++   (clobber (reg:DI destreg))
++   (set (subreg:SI (reg:DI destreg) 4) (reg:SI srcreg)) 
++
++   or
++
++   example 2:
++   from:
++        dest             src
++   (set (reg:DI destreg) (sign_extend:DI (subreg:SI (reg:DI srcreg) 4)))
++   to:
++   (clobber (reg:DI destreg))
++   (set (subreg:SI (reg:DI destreg) 4) (subreg:SI (reg:DI srcreg) 4)) 
++
++   or
++
++   example 3:
++   from:
++        dest             src
++   (set (reg:SI destreg) (sign_extend:SI (subreg:HI (reg:SI srcreg) 2)))
++   to:
++   (clobber (reg:SI destreg))
++   (set (subreg:HI (reg:SI destreg) 2) (subreg:HI (reg:SI srcreg) 2)) */
++
++static void
++replace_with_copy (rtx ext)
++{
++  rtx extension = PATTERN (ext);
++  rtx ext_op, src, dest, insns, cp_dest, cp_src;
++  enum machine_mode inner_mode;
++  gcc_assert (GET_CODE (extension) == SET);
++
++  dest = SET_DEST (extension);
++  src = SET_SRC (extension);
++
++  /* The sign extension operand */
++  ext_op = XEXP (src, 0);
++  /* Get the inner mode */
++  inner_mode = GET_MODE (ext_op);
++  gcc_assert (inner_mode == SImode || inner_mode == HImode
++              || inner_mode == QImode);
++
++  /* Make dest a SUBREG:mm */
++  cp_dest = gen_lowpart_SUBREG (inner_mode, dest);
++
++  /* Copy src is the sign extension target register */
++  cp_src = ext_op;
++
++  /* ??? clobber is needed for rtl consistency, don't know why */
++  start_sequence ();
++  emit_clobber (dest);
++  emit_move_insn (cp_dest, cp_src);
++  insns = get_insns ();
++  end_sequence ();
++  emit_insn_before (insns, ext);
++
++  delete_insn (ext);
++}
++
++/* Iterate through extensions, replace those extensions
++   that are marked as so with a copy insn. */
++
++static void
++replace_ext_with_copy (void)
++{
++  ext_record_t extrec;
++  unsigned i;
++
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  {
++    const char *inserted = insn_flag_p (EXTELIM_INSERTED,
++                                        INSN_UID (extrec->
++                                                  ext)) ? "inserted" : "";
++    if (insn_flag_p (EXTELIM_REPLACE_COPY, INSN_UID (extrec->ext)))
++      {
++        if (dump_file)
++          fprintf (dump_file,
++                   " replace %s extension uid=%d with a copy\n", inserted,
++                   INSN_UID (extrec->ext));
++        replace_with_copy (extrec->ext);
++      }
++  }
++}
++
++
++/* Copy the RTX flags from old to new */
++
++static void
++copy_flags (rtx oldrtx, rtx newrtx)
++{
++  if (RTX_FLAG (oldrtx, in_struct))
++    RTX_FLAG (newrtx, in_struct) = true;
++
++  if (RTX_FLAG (oldrtx, volatil))
++    RTX_FLAG (newrtx, volatil) = true;
++
++  if (RTX_FLAG (oldrtx, unchanging))
++    RTX_FLAG (newrtx, unchanging) = true;
++
++  if (RTX_FLAG (oldrtx, frame_related))
++    RTX_FLAG (newrtx, frame_related) = true;
++
++  if (RTX_FLAG (oldrtx, jump))
++    RTX_FLAG (newrtx, jump) = true;
++
++  if (RTX_FLAG (oldrtx, call))
++    RTX_FLAG (newrtx, call) = true;
++
++  if (RTX_FLAG (oldrtx, return_val))
++    RTX_FLAG (newrtx, return_val) = true;
++}
++
++/* Iterate through the insn notes looking for 'kind'. If 
++   found replace the register rtx with the new rtx. */
++
++static void
++update_notes (enum reg_note kind, rtx insn, rtx reg, rtx new_reg)
++{
++  rtx link;
++  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
++    if (REG_NOTE_KIND (link) == kind)
++      {
++        rtx op0 = XEXP (link, 0);
++        if (kind == REG_DEAD)
++          if (REG_P (op0) && op0 == reg)
++            XEXP (link, 0) = new_reg;
++      }
++}
++
++
++
++#if EXTELIM_DUPLICATE_EXTS_AT_USES
++/* Insert a duplicate sign extension at the use point.
++   Add a flag indicating this extension is algorithmically
++   added. Since the "inserted" extensions have the form
++   regX = sign_extend (subreg:mm (reg:MM regX), offset), 
++   they can simply be deleted if they are redundant since we 
++   are at a reaching use of the original definition. We also 
++   mark the use insn where the insert occurs so we don't insert 
++   the same extension from another def at this use. */
++
++static void
++insert_duplicate_ext_at_use (rtx ext_insn, rtx use_insn)
++{
++  int i;
++  rtx ext = PATTERN (ext_insn), ext_src, ext_dest;
++  rtx new_ext_src_inner, new_ext_src_outer, new_ext_part;
++  rtx new_ext_dest, new_ext_insn;
++  extelim_uid_t new_uid;
++  df_ref *p_df_uses;
++  unsigned int ext_dest_regno;
++  enum machine_mode inner_mode;
++  bool sign_extend_p =
++    GET_CODE (SET_SRC (PATTERN (ext_insn))) == SIGN_EXTEND ? true : false;
++
++  /* This new extension must be of the form:
++     set (reg:MM X (sign_extend:MM (subreg:mm (reg:MM X)))) 
++     where mm is smaller than MM. */
++  ext_dest = SET_DEST (ext);
++  ext_src = SET_SRC (ext);
++
++  gcc_assert (REG_P (register_exp (ext_dest)));
++
++  /* A copy of the extend destination register to a new virtual register */
++  new_ext_dest = gen_reg_rtx (GET_MODE (ext_dest));
++  /* A copy of the extend source (same reg as dest), REG_P */
++  new_ext_src_inner = copy_rtx (ext_dest);
++  /* Get inner mode, either mm for SUBREG:mm (REG:MM) or MM for (REG:MM) */
++  if (GET_CODE (XEXP (ext_src, 0)) == SUBREG)
++    inner_mode = GET_MODE (XEXP (ext_src, 0));
++  else if (REG_P (XEXP (ext_src, 0)))
++    inner_mode = GET_MODE (XEXP (ext_src, 0));
++  else
++    /* Can't determine sign_extend operand */
++    gcc_unreachable ();
++
++  /* Make a subreg rtx */
++  new_ext_src_outer = gen_lowpart_SUBREG (inner_mode, new_ext_src_inner);
++  /* Make a sign/zero extend insn */
++  new_ext_part = sign_extend_p
++    ? gen_rtx_SIGN_EXTEND (GET_MODE (ext_dest), new_ext_src_outer)
++    : gen_rtx_ZERO_EXTEND (GET_MODE (ext_dest), new_ext_src_outer);
++  /* (set (new:MM (sign_extend:MM (subreg:mm (reg:MM ext_dest))))) */
++  new_ext_insn = gen_rtx_SET (VOIDmode, new_ext_dest, new_ext_part);
++
++  /* Now update the use */
++  /* Operands used by this the use_insn */
++  ext_dest_regno = REGNO (register_exp (ext_dest));
++  for (p_df_uses = DF_INSN_UID_USES (INSN_UID (use_insn)), i = 0; *p_df_uses;
++       p_df_uses++, i++)
++    {
++      if (DF_REF_REGNO (*p_df_uses) == ext_dest_regno)
++        {
++          rtx use_reg = DF_REF_REG (*p_df_uses);
++
++          /*  Replace the register use in use_insn with the new register. If the use
++             is a subreg pattern, replace the innermost reg. */
++          replace_rtx (PATTERN (use_insn), register_exp (use_reg),
++                       new_ext_dest);
++          /* Update flags on new dest reg */
++          copy_flags (register_exp (use_reg), new_ext_dest);
++          /* Update any notes associated with use reg and use_insn */
++          update_notes (REG_DEAD, use_insn, register_exp (use_reg), new_ext_dest);
++          /* DF info must be updated since existing insn is changed */
++          if (df_insn_rescan (use_insn))
++            {
++              p_df_uses = DF_INSN_UID_USES (INSN_UID (use_insn));
++	      p_df_uses += i;
++            }
++        }
++    }
++
++  new_uid = extelim_emit_before (new_ext_insn, use_insn);
++  insn_flag_set (EXTELIM_INSERTED, new_uid);
++}
++
++/* Allow the duplication of the extension even if the extension
++   and the duplication use are in the same block. */
++
++static bool
++allow_duplication_p (rtx ext_insn, rtx use_insn)
++{
++  rtx ext = PATTERN (ext_insn);
++  rtx use = PATTERN (use_insn);
++  rtx insn;
++  basic_block bb;
++  bool found_zxt=false;
++
++  /* Do not allow duplication if use is already preceded by a ZERO_EXTEND in this 
++     basic block. Start at beginning of block and search down until the use insn. */
++
++  bb = BLOCK_FOR_INSN (use_insn);
++  FOR_BB_INSNS (bb, insn)
++    {
++      if (!NONDEBUG_INSN_P (insn))
++        continue;
++      if (insn == use_insn)
++        break;
++      if ((GET_CODE (PATTERN (insn)) == SET)
++          && (GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTEND))
++        found_zxt=true;
++    }
++
++  /* We must have found the use insn (and therefore insn is not null) */
++  gcc_assert(insn != NULL_RTX);
++
++  if (found_zxt)
++    return false;
++
++  if (GET_CODE (SET_SRC (use)) == ASHIFT && GET_CODE (SET_SRC (ext)) == ZERO_EXTEND)
++    return true;
++
++  return false;
++}
++
++/* Determine if the extension should be duplicated at this use point.
++   Return true if yes, false otherwise. */
++
++static bool
++save_ext_use_p (ext_record_t extrec, rtx use_insn)
++{
++  rtx ext_insn, ext, ext_dest, use = PATTERN (use_insn);
++  df_ref df_use, df_def;
++  struct df_link *link;
++
++  ext_insn = extrec->ext;
++  ext = PATTERN (ext_insn);
++  ext_dest = SET_DEST (ext);
++
++  if (GET_CODE (use) != SET)
++    return false;
++
++  /* 1. Duplicate the extension at certain CODEs that are known to generate 
++     a target insn when paired with the extension duplication. E.g. 
++     128 = ZERO_EXTEND (159)
++     153 = ASHIFT (128)
++     will match a single rldic insn. This limits extension duplication to points where it is
++     possibly beneficial if the original extension is deleted. It doesn't guarantee that
++     the original extension will be deleted, however, because the elimination pass has to
++     make that decision. */
++  if (INSN_P (ext_insn) && INSN_P (use_insn))
++    {
++      if ( ! allow_duplication_p (ext_insn, use_insn))
++          return false;
++    }
++
++  /* 2. Check if all other definitions reaching this use are already extended,
++     and therefore duplicating the extension does not change the value
++     of that reaching definition. (testcase: nof/muldf3.c) */
++  df_use = df_find_use (use_insn, ext_dest);
++
++  /* Iterate through definitions reaching this use */
++  for (link = DF_REF_CHAIN (df_use); link; link = link->next)
++    {
++      rtx insn_def, def;
++      df_def = link->ref;
++      if (!df_def)
++        continue;
++      /* Link must be to a definition of the use */
++      if (!DF_REF_REG_DEF_P (df_def))
++        continue;
++      /* Ignore ARTIFICIAL defs */
++      if (DF_REF_IS_ARTIFICIAL (df_def))
++        continue;
++      insn_def = DF_REF_INSN (df_def);
++      def = PATTERN (insn_def);
++
++      /* If def is a PARALLEL, find the SET */
++      if (GET_CODE (def) == PARALLEL)
++	{
++	  int i;
++	  for (i = 0; i < XVECLEN (def, 0); i++)
++	    {
++	      rtx body = XVECEXP (def, 0, i);
++	      if (GET_CODE (body) == SET)
++		{
++		  def = body;
++		  break;
++		}
++	      return false;
++	    }
++	}
++
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_def))
++        continue;
++
++      /* The original extension, obviously ignore this one. */
++      if (insn_def == ext_insn)
++        continue;
++
++      /* We must know what mode we are extending from in 'operand_is_extended' */
++      ext_from_mode = get_ext_from_mode ( SET_SRC (ext) );
++
++      /* Here we check whether the defined operand is already extended (insn_def) with
++         respect to the potentially duplicated extension (ext). Bail out if any reaching
++         defs are not extended. */ 
++      if ( ! operand_is_extended (ext, SET_SRC (def), 2 /* indent */) ) 
++          return false;
++    }
++  return true;
++}
++
++/* Save the use insn in the extension records list of
++   uses. At the next phase, we will duplicate the extension
++   at these use points. */
++
++static void
++save_ext_use (ext_record_t extrec, rtx use_insn)
++{
++  /* Mark the use insn, it will have a duplicate inserted */
++  insn_flag_set (EXTELIM_INSERTED_FOR, INSN_UID (use_insn));
++  /* Save use to the list of uses to be duplicated for this extension. */
++  VEC_safe_push (rtx, heap, extrec->ext_uses, use_insn);
++}
++
++
++/* Save the qualified use of an extension to a list */
++
++static void
++gather_ext_uses_info (ext_record_t extrec)
++{
++  rtx ext;
++  df_ref *ext_def, df_use;
++  unsigned int def_use_count = 1;
++  extelim_uid_t uid;
++  struct df_link *link;
++
++  gcc_assert (extrec != NULL);
++  ext = extrec->ext;
++  uid = INSN_UID (ext);
++
++  /* Insn level defs of the sign extension */
++  ext_def = DF_INSN_UID_DEFS (uid);
++  /* There is only one def in a sign extension insn */
++  gcc_assert (*(ext_def + 1) == NULL);
++
++  /* Iterate over the reached uses of extension destination register.
++     Duplicate the extension at the use point. */
++  for (link = DF_REF_CHAIN (*ext_def); link; link = link->next)
++    {
++      rtx insn_use;
++      df_use = link->ref;
++      if (!df_use)
++        continue;
++      /* Link must be a USE of the DEF */
++      if (!DF_REF_REG_USE_P (df_use))
++        continue;
++      /* Ignore ARTIFICIAL USES */
++      if (DF_REF_IS_ARTIFICIAL (df_use))
++        continue;
++      insn_use = DF_REF_INSN (df_use);
++
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_use))
++        continue;
++
++      if (dump_file)
++        fprintf (dump_file,
++                 " use #%d: insert duplicate extension of reg=%d at uid=%u? ",
++                 def_use_count, DF_REF_REGNO (*ext_def), INSN_UID (insn_use));
++
++      /* Determine whether its worthwhile duplicating the extension at this use */
++      if (save_ext_use_p (extrec, insn_use))
++        {
++          if (dump_file)
++            fprintf (dump_file, "  yes\n");
++          save_ext_use (extrec, insn_use);
++        }
++      else
++        {
++          if (dump_file)
++            fprintf (dump_file, "  no\n");
++        }
++      def_use_count++;
++    }
++}
++
++/* At each use point of the sign extension, unless the 
++   use is obviously already sign extended, insert a 
++   sign extension insn before the use if criteria for inserting
++   a duplicate extension is met.
++   Do this in 2 passes to avoid confusing the dataflow information. */
++
++static void
++duplicate_exts_at_uses (void)
++{
++  unsigned i, j;
++  ext_record_t extrec;
++  rtx use_insn;
++
++  if (dump_file)
++    fprintf (dump_file, "Duplicate Extension at Uses pass.\n");
++
++  /* Get the uses where the extensions will be duplicated */
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  {
++    if (dump_file)
++      fprintf (dump_file, "gathering extension uid=%u use information\n",
++               INSN_UID (extrec->ext));
++    gather_ext_uses_info (extrec);
++  }
++
++  /* Now duplicate the extensions at the appropriate use points */
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  {
++    FOR_EACH_VEC_ELT (rtx, extrec->ext_uses, j, use_insn)
++    {
++      insert_duplicate_ext_at_use (extrec->ext, use_insn);
++    }
++  }
++}
++#endif /* EXTELIM_DUPLICATE_EXTS_AT_USES */
++
++/* Determine if an instruction is a return insn */
++
++static rtx
++return_p (rtx rtn_insn)
++{
++  rtx rtn = PATTERN (rtn_insn), dest;
++  int i;
++
++  if (GET_CODE (rtn) != SET)
++    return false;
++
++  dest = SET_DEST (rtn);
++
++  /* Is a return value? */
++  if ((REG_P (dest) || GET_CODE (dest) == PARALLEL) &&
++      REG_FUNCTION_VALUE_P (dest))
++    {
++      /* Simple SET, return the insn */
++      if (REG_P (dest))
++        return rtn_insn;
++      /* PARALLEL, find the embedded rtx */
++      if (GET_CODE (dest) == PARALLEL)
++        for (i = XVECLEN (rtn_insn, 0) - 1; i >= 0; i--)
++          {
++            rtx body = XVECEXP (rtn_insn, 0, i);
++            if (GET_CODE (body) == SET)
++              {
++                dest = SET_DEST (body);
++                if (REG_FUNCTION_VALUE_P (dest))
++                  return body;
++              }
++          }
++    }
++  /* Not a return */
++  return NULL;
++}
++
++/* Find all return RTLs in the function and save them in
++   a list. */
++
++static bool
++find_returns (void)
++{
++  basic_block bb;
++  rtx insn, rtn_insn;
++  bool found = false;
++
++  /* For all insns  */
++  FOR_EACH_BB (bb)
++  {
++    FOR_BB_INSNS (bb, insn)
++    {
++      if (!NONDEBUG_INSN_P (insn))
++        continue;
++
++      if ((rtn_insn = return_p (insn)) == NULL)
++        {
++          continue;
++        }
++      if (dump_file)
++        fprintf (dump_file, " found return at uid=%u\n", INSN_UID (rtn_insn));
++
++      VEC_safe_push (rtx, heap, returns, rtn_insn);
++      found = true;
++    }
++  }
++
++  return (found);
++}
++
++/* Get the signedness and machine mode of the function */
++
++static bool
++get_return_info (bool * signed_p, enum machine_mode *return_mode)
++{
++  tree rtninfo;
++
++  if ((rtninfo = DECL_RESULT (current_function_decl)) != NULL)
++    {
++      *signed_p = !TYPE_UNSIGNED (TREE_TYPE (rtninfo));
++      *return_mode = DECL_MODE (rtninfo);
++      return true;
++    }
++  return false;
++}
++
++/* If the dest mode of the return is larger than
++   the function return mode, we can subreg the return
++   insn to the return mode and extend to the destination.
++   E.g. unsigned, return mode: HImode
++   set (reg/i:DI Y) (reg:DI X) 
++   becomes
++   set (reg:DI new) (zero_extend:DI (subreg:HI (reg:DI X)))
++   set (reg/i:DI Y) (reg:DI new) */
++
++static void
++make_ext_at_rtn (rtx rtn_insn, bool fun_signed_p, enum machine_mode fun_mode)
++{
++  rtx rtn = PATTERN (rtn_insn);
++  rtx dest, src, new_ext_dest, new_ext_src, new_ext_outer, new_ext_part,
++    new_ext_insn;
++  extelim_uid_t new_uid;
++  gcc_assert (GET_CODE (rtn) == SET);
++
++  dest = SET_DEST (rtn);
++  src = SET_SRC (rtn);
++
++  /* Deal with scalar rtn values only */
++  if (fun_mode != DImode
++      && fun_mode != SImode && fun_mode != HImode && fun_mode != QImode)
++    {
++      if (dump_file)
++        fprintf (dump_file, "failed-- not scalar return mode\n");
++      return;
++    }
++
++  /* Dest and src have to have the same mode. This should always be
++     true for well formed rtl, but we check anyway. */
++  if (GET_MODE (dest) != GET_MODE (src))
++    {
++      if (dump_file)
++        fprintf (dump_file, "failed-- dest and src modes differ\n");
++      return;
++    }
++
++  /* Also check that we are dealing with simple regs here. */
++  if (!REG_P (dest) || !REG_P (src))
++    {
++      if (dump_file)
++        fprintf (dump_file, "failed-- dest or src is not REG_P\n");
++      return;
++    }
++
++  /* The return reg mode should never be smaller than fun return mode. If the
++     same size, however, we can't subreg either, so return */
++  if (GET_MODE_BITSIZE (GET_MODE (dest)) <= GET_MODE_BITSIZE (fun_mode))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "failed-- dest size mode is smaller or equal to function mode size\n");
++      return;
++    }
++
++  /* From here we should be able to build a subreg since the function return mode
++     size is smaller than the return register mode size */
++  new_ext_dest = gen_reg_rtx (GET_MODE (src));  /*  set (reg:MM new) */
++  new_ext_src = copy_rtx (src); /*  copy of X, copyX */
++  new_ext_outer = gen_lowpart_SUBREG (fun_mode, new_ext_src);   /*  subreg:mm (reg:MM copyX) */
++  new_ext_part = fun_signed_p   /*  extend:MM (subreg:mm (reg:MM copyX)) */
++    ? gen_rtx_SIGN_EXTEND (GET_MODE (src), new_ext_outer)
++    : gen_rtx_ZERO_EXTEND (GET_MODE (src), new_ext_outer);
++  /* Put it together */
++  new_ext_insn = gen_rtx_SET (VOIDmode, new_ext_dest, new_ext_part);
++
++  /* Modify src of return insn to use new pseudo */
++  replace_rtx (PATTERN (rtn_insn), src, new_ext_dest);
++  /* Update flags on new dest reg */
++  copy_flags (src, new_ext_dest);
++  /* Update any notes associated with replaced register */
++  update_notes (REG_DEAD, rtn_insn, src, new_ext_dest);
++  /* Rescan the modified insn */
++  df_insn_rescan (rtn_insn);
++  /* Insert the new insn */
++  new_uid = extelim_emit_before (new_ext_insn, rtn_insn);
++
++  if (dump_file)
++    fprintf (dump_file, "success\n");
++}
++
++/* Insert extensions at return points. Scan the RTL
++   for the return statements. Determine if the RTL 
++   can be modified to insert an extension. Modify the
++   return to insert the extension. */
++
++static void
++insert_ext_at_returns (void)
++{
++  bool signed_p;
++  enum machine_mode return_mode;
++  rtx rtn_insn;
++  int i;
++
++  /* Generate list of return rtls for the function */
++  if (dump_file)
++    {
++      fprintf (dump_file, "Insert Extensions at Returns pass.\n");
++      fprintf (dump_file, "gathering return insns...\n");
++    }
++
++  if (!find_returns ())
++    return;
++
++  if (!get_return_info (&signed_p, &return_mode))
++    return;
++
++  /* For each return instruction, generate a sign/zero extend
++     if the current return size is larger than the function
++     return mode. */
++  FOR_EACH_VEC_ELT (rtx, returns, i, rtn_insn)
++  {
++    if (dump_file)
++      fprintf (dump_file, " making extension at return uid=%u...",
++               INSN_UID (rtn_insn));
++    make_ext_at_rtn (rtn_insn, signed_p, return_mode);
++  }
++}
++
++/* Compare two extension records by loop depth.
++   Used by VEC_qsort to sort the order in which extensions
++   are processed. */
++
++static int
++ext_record_compare (const void *p_er1, const void *p_er2)
++{
++  const ext_record_t er1 = *(const ext_record_t *) p_er1;
++  const ext_record_t er2 = *(const ext_record_t *) p_er2;
++  basic_block bb1, bb2;
++  rtx ext1, ext2;
++
++  if (er1 == er2)
++    return 0;
++
++  ext1 = er1->ext;
++  ext2 = er2->ext;
++
++  bb1 = BLOCK_FOR_INSN (ext1);
++  bb2 = BLOCK_FOR_INSN (ext2);
++
++  /* Sort high to low */
++  return (bb2->loop_depth - bb1->loop_depth);
++}
++
++/* The main interface to this optimization. */
++
++static void
++extension_elimination (void)
++{
++  ext_record_t ext;
++  unsigned i;
++
++  init_pass ();
++
++  /* Find initial sign extension candidates */
++  if (!find_extensions ())
++    {
++      finish_pass ();
++      return;
++    }
++
++  /* Insert sign extension at return points in
++     the function. */
++  insert_ext_at_returns ();
++
++  /* Duplicate the sign extensions at their use
++     points unless the use is already obviously sign
++     extended or extension is already added. */
++#if EXTELIM_DUPLICATE_EXTS_AT_USES
++  duplicate_exts_at_uses ();
++#endif
++
++  /* Update DF information since now have new insns. */
++  df_finish_pass (true);
++  df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN);
++  df_analyze ();
++
++#if EXTELIM_DF_DUMP
++  if (dump_file)
++    df_dump (dump_file);
++#endif
++
++  /* Init statistics */
++  num_cand = 0;
++  num_cand_ignored = 0;
++  num_cand_transformed = 0;
++
++  /* Free old extensions list, generate new one that includes
++     the new extensions. */
++  free_extensions ();
++
++ if (!find_extensions ())
++    {
++      finish_pass ();
++      return;
++    }
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "\nRTL After Extension Duplication\n");
++      print_rtl (dump_file, get_insns ());
++    }
++
++  if (dump_file)
++    fprintf (dump_file, "Begin extension elimination analysis\n");
++
++  /* Sort the extensions by loop depth. We want to try to eliminate
++     those in innermost loops (highest loop depth) first. */
++  VEC_qsort (ext_record_t, extensions, ext_record_compare);
++
++  /* Iterate through extension worklist */
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, ext)
++  {
++    rtx ext_insn = ext->ext;
++    rtx ext_src = SET_SRC (PATTERN (ext_insn));
++    const char *ext_name =
++      GET_CODE (ext_src) == SIGN_EXTEND ? "sign" : "zero";
++    const char *inserted =
++      insn_flag_p (EXTELIM_INSERTED, INSN_UID (ext_insn)) ? "inserted" : "";
++    extelim_uid_t uid = INSN_UID (ext_insn);
++
++    if (dump_file)
++      fprintf (dump_file,
++               "<analyzing %s %s extension uid=%u> (loop_depth=%d)\n",
++               inserted, ext_name, uid,
++               BLOCK_FOR_INSN (ext_insn)->loop_depth);
++
++    current_ext_record = ext;
++    eliminate_one_extend (ext->ext);
++  }
++
++  if (dump_file)
++    fprintf (dump_file, "Begin extension elimination transformations\n");
++
++  replace_ext_with_copy ();
++
++  if (dump_file)
++    fprintf (dump_file, "\nRTL After Extension Elimination\n");
++
++  finish_pass ();
++
++  /* Print statistics */
++  if (dump_file)
++    {
++      fprintf (dump_file,
++               "Number of extensions ignored: %d (of %d candidiates)\nDETECTION EFFECTIVENESS: %f%%\n",
++               num_cand_ignored, num_cand,
++               ((float) (num_cand - num_cand_ignored) / (float) num_cand) *
++               100);
++      fprintf (dump_file,
++               "Number of extensions converted to copy: %d (of %d candidiates)\nCONVERSION EFFECTIVENESS: %f%%\n",
++               num_cand_transformed, num_cand,
++               ((float) num_cand_transformed / (float) num_cand) * 100);
++    }
++}
++
++/* Remove redundant extensions.  */
++
++static unsigned int
++rest_of_handle_extelim (void)
++{
++  extension_elimination ();
++  return 0;
++}
++
++/* Run extelim pass when flag_extelim is set at optimization level > 0.  */
++
++static bool
++gate_handle_extelim (void)
++{
++  return (optimize > 0 && flag_extelim);
++}
++
++struct rtl_opt_pass pass_rtl_extelim = {
++  {
++   RTL_PASS,
++   "extelim",                   /* name */
++   gate_handle_extelim,         /* gate */
++   rest_of_handle_extelim,      /* execute */
++   NULL,                        /* sub */
++   NULL,                        /* next */
++   0,                           /* static_pass_number */
++   TV_EXTELIM,                  /* tv_id */
++   0,                           /* properties_required */
++   0,                           /* properties_provided */
++   0,                           /* properties_destroyed */
++   0,                           /* todo_flags_start */
++   TODO_ggc_collect | TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing,        /* todo_flags_finish */
++   }
++};
+diff -Naur gcc-4.7.1/gcc/config.gcc gcc-4.7.1-extelim-v4/gcc/config.gcc
+--- gcc-4.7.1/gcc/config.gcc	2012-10-31 07:52:07.285238149 -0500
++++ gcc-4.7.1-extelim-v4/gcc/config.gcc	2012-11-02 03:59:15.803237359 -0500
+@@ -417,6 +417,8 @@
+ 		cpu_is_64bit=yes
+ 		;;
+ 	esac
++	tm_defines="${tm_defines} ENABLE_EXTELIM"
++	extra_objs="extelim.o"
+ 	extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
+ 	;;
+ rs6000*-*-*)
+diff -Naur gcc-4.7.1/gcc/opts.c gcc-4.7.1-extelim-v4/gcc/opts.c
+--- gcc-4.7.1/gcc/opts.c	2012-01-10 10:27:55.000000000 -0600
++++ gcc-4.7.1-extelim-v4/gcc/opts.c	2012-10-31 06:14:17.344237543 -0500
+@@ -485,6 +485,9 @@
+     { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
+     { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
+     { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
++#ifdef ENABLE_EXTELIM 
++    { OPT_LEVELS_2_PLUS, OPT_fextelim, NULL, 1 },
++#endif
+     { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
+     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
+ 
+diff -Naur gcc-4.7.1/gcc/testsuite/gcc.target/powerpc/rldic-1.c gcc-4.7.1-extelim-v4/gcc/testsuite/gcc.target/powerpc/rldic-1.c
+--- gcc-4.7.1/gcc/testsuite/gcc.target/powerpc/rldic-1.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.1-extelim-v4/gcc/testsuite/gcc.target/powerpc/rldic-1.c	2012-11-05 00:43:33.619237992 -0600
+@@ -0,0 +1,33 @@
++/* { dg-do run { target { powerpc*-*-* } } } */
++/* skip test unless -m64 is present */
++/* { dg-skip-if "" { powerpc*-*-* } { "*" } { "-m64" } } */
++/* { dg-options "-O3 -save-temps" } */
++
++int sum;
++
++void sum1 ( unsigned  int N, short *C) __attribute__((__noinline__)); 
++void sum1 ( unsigned  int N, short *C) 
++{
++        unsigned int i;
++
++        for (i=0; i<N; i++)
++        {
++                sum += C[i*N];
++        }
++} __attribute__((__noinline__))
++int main()
++{
++        short C [5*5] = { 1 , 0, 0, 0, 0, 
++        2 , 0, 0, 0, 0, 
++        3 , 0, 0, 0, 0, 
++        4 , 0, 0, 0, 0, 
++        5 , 0, 0, 0, 0,         
++        };
++        sum1 (5, C);
++        return (sum==15 ? 0 : 1);
++}
++
++
++
++/* { dg-final { scan-assembler-times "rldic " 1  { target powerpc*-*-*  } } } */
++/* { dg-final { cleanup-saved-temps } } */
+diff -Naur gcc-4.7.1/gcc/timevar.def gcc-4.7.1-extelim-v4/gcc/timevar.def
+--- gcc-4.7.1/gcc/timevar.def	2011-12-21 05:52:27.000000000 -0600
++++ gcc-4.7.1-extelim-v4/gcc/timevar.def	2012-10-31 03:12:42.109238187 -0500
+@@ -197,6 +197,7 @@
+ DEFTIMEVAR (TV_VARCONST              , "varconst")
+ DEFTIMEVAR (TV_LOWER_SUBREG	     , "lower subreg")
+ DEFTIMEVAR (TV_JUMP                  , "jump")
++DEFTIMEVAR (TV_EXTELIM               , "extension elimination")
+ DEFTIMEVAR (TV_FWPROP                , "forward prop")
+ DEFTIMEVAR (TV_CSE                   , "CSE")
+ DEFTIMEVAR (TV_DCE                   , "dead code elimination")
+diff -Naur gcc-4.6.3-orig/gcc/config/rs6000/extelim.c gcc-4.6.3/gcc/config/rs6000/extelim.c
+--- gcc-4.6.3-orig/gcc/config/rs6000/extelim.c	2012-11-30 16:01:48.701986000 -0600
++++ gcc-4.6.3/gcc/config/rs6000/extelim.c	2012-11-30 15:54:09.636986000 -0600
+@@ -411,6 +411,10 @@
+ Iteration 32:
+  - Fix issue with spec2k6 soplex where zero-extends duplicated
+    even if shift is already zero-extended.
++Iteration 33:
++ - Fix issue with spec2k perlbmk using '-O3 -flto -funroll-loops'
++   where the duplication of an extension was wrong because
++   the register rtx's are shared. See save_ext_use_p() for details.
+ */
+ 
+ #include "config.h"
+@@ -2869,7 +2873,26 @@
+   if (GET_CODE (use) != SET)
+     return false;
+ 
+-  /* 1. Duplicate the extension at certain CODEs that are known to generate 
++  /* 1. If the use defines itself, e.g.
++     128 = ZERO_EXTEND (159) ; the def
++     ...
++     128 = ASHIFT (128) ; the use
++     ...
++     use 128 ; use reached by the self-assign above
++     then disallow the duplication. RTX's are shared within an insn 
++     so you end up with
++     128 = ZERO_EXTEND (159)
++     ...
++     NewVR = ZERO_EXTEND (128) ; the duplicate extension
++     NewVR = ASHIFT(NewVR) ; wrong! should define 128 for next use 
++     ...
++     use 128
++  */
++  if (REGNO(SET_DEST(use)) == REGNO(SET_DEST(ext)))
++    return false;
++  
++
++  /* 2. Duplicate the extension at certain CODEs that are known to generate 
+      a target insn when paired with the extension duplication. E.g. 
+      128 = ZERO_EXTEND (159)
+      153 = ASHIFT (128)
+@@ -2883,7 +2906,7 @@
+           return false;
+     }
+ 
+-  /* 2. Check if all other definitions reaching this use are already extended,
++  /* 3. Check if all other definitions reaching this use are already extended,
+      and therefore duplicating the extension does not change the value
+      of that reaching definition. (testcase: nof/muldf3.c) */
+   df_use = df_find_use (use_insn, ext_dest);
+--- gcc-4.7.2-orig/gcc/config/rs6000/extelim.c	2013-01-15 11:26:54.761989180 -0600
++++ gcc-4.7.2/gcc/config/rs6000/extelim.c	2013-01-15 11:27:57.933986000 -0600
+@@ -415,6 +415,16 @@
+  - Fix issue with spec2k perlbmk using '-O3 -flto -funroll-loops'
+    where the duplication of an extension was wrong because
+    the register rtx's are shared. See save_ext_use_p() for details.
++Iteration 34:
++-  Bug Fix: Clearquest issue ENGR00239811. 
++   We end up with consecutive extensions (one inserted, one previously there) due
++   to extension insertions are return insns.
++   This is not great, but shouldn't be catastrophic as one will be transformed to a copy.
++   The order in which the extensions are processed in windows and linux is different,
++   however. The 'combine' pass fails to treat the windows/linux cases equally and 
++   misses an important extension in the windows program. Combine is complex and 
++   there's no obvious reason why it is failing, so we disallow an extension insertion
++   at the return insn if the previous insn is an extension.
+ */
+ 
+ #include "config.h"
+@@ -3181,6 +3191,29 @@
+   dest = SET_DEST (rtn);
+   src = SET_SRC (rtn);
+ 
++  /* Do not insert extension if the preceeding insn is already an extension. 
++     - Bug: ENGR00239811. 
++     We end up with consecutive extensions (one inserted, one previously there).
++     This is not great, but shouldn't be catastrophic as one will be transformed to a copy.
++     The order in which the extensions are processed in windows and linux is different,
++     however. Combine fails to treat either case equally and misses an important extension
++     in the windows program. Combine is complex and there's no obvious reason why it is
++     failing, so this will have to do. */
++ if (PREV_INSN (rtn_insn) && NONDEBUG_INSN_P (PREV_INSN (rtn_insn))) 
++    {
++      rtx prev_insn = PATTERN (PREV_INSN (rtn_insn));
++      if (GET_CODE (prev_insn) == SET) 
++        {
++          enum rtx_code prev_code = GET_CODE (SET_SRC (prev_insn));
++          if (prev_code == ZERO_EXTEND || prev_code == SIGN_EXTEND) 
++            {
++              if (dump_file)
++                fprintf (dump_file, "failed-- prev insn is an extension\n");
++              return;
++            }
++        }
++    }
++
+   /* Deal with scalar rtn values only */
+   if (fun_mode != DImode
+       && fun_mode != SImode && fun_mode != HImode && fun_mode != QImode)
+--- gcc-4.7.2/gcc/config/rs6000/extelim.c	2013-04-02 13:17:08.644779000 -0500
++++ gcc-4.8.0/gcc/config/rs6000/extelim.c	2013-04-11 13:48:23.864779000 -0500
+@@ -425,6 +425,9 @@
+    misses an important extension in the windows program. Combine is complex and 
+    there's no obvious reason why it is failing, so we disallow an extension insertion
+    at the return insn if the previous insn is an extension.
++Iteration 35:
++- Port to gcc 4.8 ( vec.h and bb_loop_depth )
++
+ */
+ 
+ #include "config.h"
+@@ -456,6 +459,7 @@
+ #include "cgraph.h"
+ #include "df.h"
+ #include "vec.h"
++#include "cfgloop.h"
+ 
+ /* Feature flags */
+ /* Duplicate extensions at each immediate use */
+@@ -465,18 +469,18 @@
+ 
+ 
+ /* Typedefs */
+-typedef unsigned int insn_flag_t;       /* Insn flags type */
+-typedef int extelim_uid_t;      /* UID type */
+-DEF_VEC_I (insn_flag_t);        /* Define vector type and allocation type */
+-DEF_VEC_ALLOC_I (insn_flag_t, heap);
++typedef unsigned int insn_flag_t;/* Insn flags type */
++typedef int extelim_uid_t;       /* UID type */
+ 
+ typedef struct GTY (()) ext_record
+ {
+   rtx ext;                      /* The extension insn */
+-  VEC (rtx, heap) * ext_uses;   /* List of use records for this extension. For some
++  vec<rtx, va_gc> *ext_uses;
++                                /* List of use records for this extension. For some
+                                    some extensions, we will duplicate the extension
+                                    at these use points. */
+-  VEC (rtx, heap) * ext_updates;/* List of rtx that need to be updated if the extension
++  vec<rtx, va_gc> *ext_updates; 
++                               /* List of rtx that need to be updated if the extension
+                                    is to be eliminated. For example, SUBREG_PROMOTED flags
+                                    on SUBREG uses defined by this extension should
+                                    be reset since the extension is eliminated. The PROMOTED
+@@ -490,24 +494,22 @@
+ } regspec_cb_data_t;
+ 
+ /* Static variables */
+-DEF_VEC_P (ext_record_t);
+-DEF_VEC_ALLOC_P (ext_record_t, heap);
+-VEC (ext_record_t, heap) * extensions;  /* Vector holding all extension records */
+-VEC (insn_flag_t, heap) * insn_flags;   /* Vector holding flags for all insns */
+-VEC (rtx, heap) * returns;      /* Vector holding return insns for this function */
++vec<insn_flag_t, va_gc>  *insn_flags; 
++vec<ext_record_t, va_gc> *extensions;
++vec<rtx, va_gc> *returns;
+ 
+      static extelim_uid_t max_uid;      /* Max UID insn value for insn_flags allocation */
+      static ext_record_t current_ext_record; /* Current extension record being processed */
+ 
+ /* Statistics */
+-     static int num_cand;       /* Number of extensions detected */
++     static int num_cand;               /* Number of extensions detected */
+      static int num_cand_ignored;       /* Number of extensions ignored */
+      static int num_cand_transformed;   /* Number of extensions transformed to copy */
+ 
+ /* Basic information about the extension being processed */
+      enum machine_mode ext_to_mode;     /* Mode extended to */
+      enum machine_mode ext_from_mode;   /* Mode extended from */
+-     enum rtx_code ext_code;    /* Sign or zero extend */
++     enum rtx_code ext_code;            /* Sign or zero extend */
+ 
+ /* Insn use analysis possible results */
+      enum insn_use_results
+@@ -535,12 +537,15 @@
+ 
+ /* Query the insn flag */
+ 
+-     static bool insn_flag_p (insn_flag_t set_p, extelim_uid_t uid)
++static bool insn_flag_p (insn_flag_t set_p, extelim_uid_t uid)
+ {
+-  insn_flag_t flags;
+-
+-  if (((flags = VEC_index (insn_flag_t, insn_flags, uid)) & set_p) == set_p)
+-    return true;
++  insn_flag_t * flags;
++  
++  if (vec_safe_iterate (insn_flags, uid, &flags))
++    {
++      if ((*flags & set_p) == set_p)
++        return true;
++    }
+ 
+   return false;
+ }
+@@ -550,10 +555,9 @@
+ static void
+ insn_flag_set (insn_flag_t flags, extelim_uid_t uid)
+ {
+-  insn_flag_t set;
+-  set = VEC_index (insn_flag_t, insn_flags, uid);
+-  set |= flags;
+-  VEC_replace (insn_flag_t, insn_flags, uid, set);
++  insn_flag_t *set;
++  gcc_assert (vec_safe_iterate (insn_flags, uid, &set));
++  *set |= flags;
+ }
+ 
+ /* Clear insn flags */
+@@ -561,10 +565,9 @@
+ static void
+ insn_flag_clear (insn_flag_t flags, extelim_uid_t uid)
+ {
+-  insn_flag_t clear;
+-  clear = VEC_index (insn_flag_t, insn_flags, uid);
+-  clear &= ~flags;
+-  VEC_replace (insn_flag_t, insn_flags, uid, clear);
++  insn_flag_t * clear;
++  gcc_assert (vec_safe_iterate (insn_flags, uid, &clear));
++  *clear &= ~flags;
+ }
+ 
+ /* Set static variable max_uid to the largest
+@@ -613,6 +616,7 @@
+ init_flags_vector (void)
+ {
+   extelim_uid_t i;
++  insn_flag_t * flags;
+   /* Get the maximum uid value. We'll use this
+      information to set up a vector of max_uid
+      length. Each element of the vector will hold
+@@ -620,14 +624,9 @@
+   max_uid = 0;
+   set_max_uid ();
+ 
+-  /* Allocate the vector of insn flags */
+-  insn_flags = VEC_alloc (insn_flag_t, heap, max_uid);
+-
+-  /* Initialize the insn flags vector */
+-  for (i = 0; i < max_uid; i++)
+-    {
+-      VEC_quick_insert (insn_flag_t, insn_flags, i, EXTELIM_NONE);
+-    }
++  /* Allocate and populate vector of insn flags */
++  /* Vector is init'd to 0 (EXTELIM_NONE) */
++  vec_safe_grow_cleared (insn_flags, max_uid);
+ }
+ 
+ /* Initialize this pass */
+@@ -638,6 +637,10 @@
+   /* Init insn flags vector */
+   init_flags_vector ();
+ 
++  /* Init statics */
++  vec_alloc(extensions, 0);
++  vec_alloc(returns, 0);
++
+   /* This pass requires def-use chain information */
+   df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN);
+   df_analyze ();
+@@ -649,15 +652,16 @@
+   ext_record_t ext_record;
+   unsigned i;
+ 
+-  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, ext_record)
+-  {
+-    if (!VEC_empty (rtx, ext_record->ext_uses))
+-      VEC_free (rtx, heap, ext_record->ext_uses);
+-
+-    if (!VEC_empty (rtx, ext_record->ext_updates))
+-      VEC_free (rtx, heap, ext_record->ext_updates);
+-  }
+-  VEC_free (ext_record_t, heap, extensions);
++  FOR_EACH_VEC_SAFE_ELT (extensions, i, ext_record)
++    {
++      if (!vec_safe_is_empty(ext_record->ext_uses))
++        vec_free(ext_record->ext_uses);
++      if (!vec_safe_is_empty(ext_record->ext_updates))
++        vec_free(ext_record->ext_updates);
++    }
++      
++  if (!vec_safe_is_empty(extensions))
++    vec_free(extensions);
+ }
+ 
+ /* Clean up this pass */
+@@ -666,14 +670,16 @@
+ finish_pass (void)
+ {
+   free_extensions ();
+-  VEC_free (insn_flag_t, heap, insn_flags);
+-  VEC_free (rtx, heap, returns);
++  if (!vec_safe_is_empty(insn_flags))
++    vec_free(insn_flags);
++  if (!vec_safe_is_empty(returns))
++    vec_free(returns);
+ }
+ 
+ static void
+ update_uid_vectors (extelim_uid_t uid)
+ {
+-  VEC_safe_grow_cleared (insn_flag_t, heap, insn_flags, uid + 1);
++  vec_safe_grow_cleared(insn_flags, uid + 1);
+ }
+ 
+ /* Emit a insn before a given insn, update vector lengths
+@@ -789,13 +795,21 @@
+ static bool
+ ignore_extension_prev_p (rtx ext_insn, rtx prev_insn)
+ {
+-  rtx prev_dest, prev_src, prev = PATTERN (prev_insn);
++  rtx prev_dest, prev_src, prev;
+   rtx ext_src, ext = PATTERN (ext_insn);
+ 
+-  /* It's OK to allow extension with no accompanying prev real insn */
+-  if (!NONDEBUG_INSN_P (prev_insn) || NOTE_P (prev_insn))
++  /* Find a real previous insn, ignoring debug and notes */
++  while (prev_insn && (!NONDEBUG_INSN_P (prev_insn) || NOTE_P (prev_insn)))
++    {
++      prev_insn = PREV_INSN (prev_insn);
++    }
++
++  /* Beginning of block reached */
++  if (prev_insn == NULL_RTX)
+     return false;
+ 
++  prev = PATTERN (prev_insn);
++
+   if (GET_CODE (prev) != SET)
+     return false;
+ 
+@@ -867,6 +881,7 @@
+   rtx insn, dest, inner;
+   int preserved_size;
+   ext_record_t extrec;
++  bool has_extensions;
+ 
+   /* For all insns, call note_use for each use in insn.  */
+   FOR_EACH_BB (bb)
+@@ -913,22 +928,23 @@
+ 
+       extrec = (ext_record_t) xmalloc (sizeof (struct ext_record));
+       extrec->ext = insn;
+-      extrec->ext_uses = NULL;
+-      extrec->ext_updates = NULL;
+-      VEC_safe_push (ext_record_t, heap, extensions, extrec);
++      vec_alloc(extrec->ext_uses, 0);
++      vec_alloc(extrec->ext_updates, 0);
++      vec_safe_push(extensions, extrec);
+       num_cand++;
+     }
+   }
+ 
+   if (dump_file)
+     {
+-      if (!VEC_empty (ext_record_t, extensions))
++      if (! vec_safe_is_empty(extensions)) 
+         fprintf (dump_file, "\n");
+       else
+         fprintf (dump_file, "no extensions found.\n");
+     }
+ 
+-  return !VEC_empty (ext_record_t, extensions);
++  has_extensions = !vec_safe_is_empty(extensions);
++  return (has_extensions);
+ }
+ 
+ /* Return true if the rtx mode is a supported mode for
+@@ -1648,7 +1664,7 @@
+ save_ext_update (ext_record_t extrec, rtx exp)
+ {
+   /* Save this expression to be updated if the extension is eliminated. */
+-  VEC_safe_push (rtx, heap, extrec->ext_updates, exp);
++  vec_safe_push(extrec->ext_updates, exp);
+ }
+ 
+ /* Check a compare operation to determine whether the operands
+@@ -2435,7 +2451,7 @@
+   bool updated=false;
+ 
+ 
+-  FOR_EACH_VEC_ELT (rtx, extrec->ext_updates, i, exp)
++  FOR_EACH_VEC_SAFE_ELT (extrec->ext_updates, i, exp)
+     {
+       updated |= process_ext_update (exp);
+     }
+@@ -2679,7 +2695,7 @@
+   ext_record_t extrec;
+   unsigned i;
+ 
+-  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  FOR_EACH_VEC_SAFE_ELT (extensions, i, extrec)
+   {
+     const char *inserted = insn_flag_p (EXTELIM_INSERTED,
+                                         INSN_UID (extrec->
+@@ -2983,7 +2999,7 @@
+   /* Mark the use insn, it will have a duplicate inserted */
+   insn_flag_set (EXTELIM_INSERTED_FOR, INSN_UID (use_insn));
+   /* Save use to the list of uses to be duplicated for this extension. */
+-  VEC_safe_push (rtx, heap, extrec->ext_uses, use_insn);
++  vec_safe_push(extrec->ext_uses, use_insn);
+ }
+ 
+ 
+@@ -3065,7 +3081,7 @@
+     fprintf (dump_file, "Duplicate Extension at Uses pass.\n");
+ 
+   /* Get the uses where the extensions will be duplicated */
+-  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  FOR_EACH_VEC_SAFE_ELT (extensions, i, extrec)
+   {
+     if (dump_file)
+       fprintf (dump_file, "gathering extension uid=%u use information\n",
+@@ -3074,9 +3090,9 @@
+   }
+ 
+   /* Now duplicate the extensions at the appropriate use points */
+-  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  FOR_EACH_VEC_SAFE_ELT (extensions, i, extrec)
+   {
+-    FOR_EACH_VEC_ELT (rtx, extrec->ext_uses, j, use_insn)
++    FOR_EACH_VEC_SAFE_ELT (extrec->ext_uses, j, use_insn)
+     {
+       insert_duplicate_ext_at_use (extrec->ext, use_insn);
+     }
+@@ -3146,7 +3162,7 @@
+       if (dump_file)
+         fprintf (dump_file, " found return at uid=%u\n", INSN_UID (rtn_insn));
+ 
+-      VEC_safe_push (rtx, heap, returns, rtn_insn);
++      vec_safe_push(returns, rtn_insn);
+       found = true;
+     }
+   }
+@@ -3305,7 +3321,7 @@
+   /* For each return instruction, generate a sign/zero extend
+      if the current return size is larger than the function
+      return mode. */
+-  FOR_EACH_VEC_ELT (rtx, returns, i, rtn_insn)
++  FOR_EACH_VEC_SAFE_ELT (returns, i, rtn_insn)
+   {
+     if (dump_file)
+       fprintf (dump_file, " making extension at return uid=%u...",
+@@ -3336,7 +3352,7 @@
+   bb2 = BLOCK_FOR_INSN (ext2);
+ 
+   /* Sort high to low */
+-  return (bb2->loop_depth - bb1->loop_depth);
++  return (bb_loop_depth(bb2) - bb_loop_depth(bb1));
+ }
+ 
+ /* The main interface to this optimization. */
+@@ -3403,10 +3419,11 @@
+ 
+   /* Sort the extensions by loop depth. We want to try to eliminate
+      those in innermost loops (highest loop depth) first. */
+-  VEC_qsort (ext_record_t, extensions, ext_record_compare);
++  if (!vec_safe_is_empty(extensions))
++    extensions->qsort(ext_record_compare);
+ 
+   /* Iterate through extension worklist */
+-  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, ext)
++  FOR_EACH_VEC_SAFE_ELT (extensions, i, ext)
+   {
+     rtx ext_insn = ext->ext;
+     rtx ext_src = SET_SRC (PATTERN (ext_insn));
+@@ -3420,7 +3437,7 @@
+       fprintf (dump_file,
+                "<analyzing %s %s extension uid=%u> (loop_depth=%d)\n",
+                inserted, ext_name, uid,
+-               BLOCK_FOR_INSN (ext_insn)->loop_depth);
++               bb_loop_depth(BLOCK_FOR_INSN (ext_insn)));
+ 
+     current_ext_record = ext;
+     eliminate_one_extend (ext->ext);
+@@ -3472,6 +3489,7 @@
+   {
+    RTL_PASS,
+    "extelim",                   /* name */
++   OPTGROUP_NONE,               /* optinfo_flags */
+    gate_handle_extelim,         /* gate */
+    rest_of_handle_extelim,      /* execute */
+    NULL,                        /* sub */
+@@ -3482,6 +3500,6 @@
+    0,                           /* properties_provided */
+    0,                           /* properties_destroyed */
+    0,                           /* todo_flags_start */
+-   TODO_ggc_collect | TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing,        /* todo_flags_finish */
++   TODO_ggc_collect | TODO_df_finish | TODO_verify_rtl_sharing,        /* todo_flags_finish */
+    }
+ };
+diff -Naur gcc-4.8.1/gcc/config/rs6000/extelim.c gcc-4.8.1-extelim/gcc/config/rs6000/extelim.c
+--- gcc-4.8.1/gcc/config/rs6000/extelim.c	2013-07-24 03:30:41.516002676 -0500
++++ gcc-4.8.1-extelim/gcc/config/rs6000/extelim.c	2013-07-24 03:36:47.337002744 -0500
+@@ -416,7 +416,7 @@
+    where the duplication of an extension was wrong because
+    the register rtx's are shared. See save_ext_use_p() for details.
+ Iteration 34:
+--  Bug Fix: Clearquest issue ENGR00239811. 
++ -  Bug Fix: Clearquest issue ENGR00239811. 
+    We end up with consecutive extensions (one inserted, one previously there) due
+    to extension insertions are return insns.
+    This is not great, but shouldn't be catastrophic as one will be transformed to a copy.
+@@ -426,8 +426,10 @@
+    there's no obvious reason why it is failing, so we disallow an extension insertion
+    at the return insn if the previous insn is an extension.
+ Iteration 35:
+-- Port to gcc 4.8 ( vec.h and bb_loop_depth )
+-
++ - Port to gcc 4.8 ( vec.h and bb_loop_depth )
++Iteration 36:
++ - We end up with consecutive extensions (one inserted, one previously there) for
++   return instructions. Updated to select active 'prev_insn'.
+ */
+ 
+ #include "config.h"
+@@ -798,12 +800,6 @@
+   rtx prev_dest, prev_src, prev;
+   rtx ext_src, ext = PATTERN (ext_insn);
+ 
+-  /* Find a real previous insn, ignoring debug and notes */
+-  while (prev_insn && (!NONDEBUG_INSN_P (prev_insn) || NOTE_P (prev_insn)))
+-    {
+-      prev_insn = PREV_INSN (prev_insn);
+-    }
+-
+   /* Beginning of block reached */
+   if (prev_insn == NULL_RTX)
+     return false;
+@@ -878,7 +874,7 @@
+ find_extensions (void)
+ {
+   basic_block bb;
+-  rtx insn, dest, inner;
++  rtx insn, dest, inner, real_insn;
+   int preserved_size;
+   ext_record_t extrec;
+   bool has_extensions;
+@@ -899,8 +895,8 @@
+       /* We do not consider extensions that follow a load for
+          this target, as the code selector optimizes the sequence
+          to a load with sign extend or load with zero extend. */
+-      if (PREV_INSN (insn)
+-          && ignore_extension_prev_p (insn, PREV_INSN (insn)))
++      real_insn = prev_active_insn (insn);
++      if (real_insn && ignore_extension_prev_p (insn, real_insn))
+         {
+           if (dump_file)
+             fprintf (dump_file, "extension at uid=%d ignored\n",
+@@ -910,8 +906,8 @@
+         }
+       /* We don't consider certain sequences that are picked up by
+          insn selection. */
+-      if (NEXT_INSN (insn)
+-          && ignore_extension_next_p (insn, NEXT_INSN (insn)))
++      real_insn = next_active_insn (insn);
++      if (real_insn && ignore_extension_next_p (insn, real_insn))
+         {
+           if (dump_file)
+             fprintf (dump_file, "extension at uid=%d ignored\n",
+@@ -3200,7 +3196,7 @@
+ {
+   rtx rtn = PATTERN (rtn_insn);
+   rtx dest, src, new_ext_dest, new_ext_src, new_ext_outer, new_ext_part,
+-    new_ext_insn;
++    new_ext_insn, prev_insn = prev_active_insn (rtn_insn);
+   extelim_uid_t new_uid;
+   gcc_assert (GET_CODE (rtn) == SET);
+ 
+@@ -3215,9 +3211,9 @@
+      however. Combine fails to treat either case equally and misses an important extension
+      in the windows program. Combine is complex and there's no obvious reason why it is
+      failing, so this will have to do. */
+- if (PREV_INSN (rtn_insn) && NONDEBUG_INSN_P (PREV_INSN (rtn_insn))) 
++ if (prev_insn)
+     {
+-      rtx prev_insn = PATTERN (PREV_INSN (rtn_insn));
++      prev_insn = PATTERN(prev_insn);
+       if (GET_CODE (prev_insn) == SET) 
+         {
+           enum rtx_code prev_code = GET_CODE (SET_SRC (prev_insn));
+diff -Naur gcc-4.9.0/gcc/passes.def gcc-4.9.0-extelim-v4-49/gcc/passes.def
+--- gcc-4.9.0/gcc/passes.def    2014-06-23 06:53:56.202371998 -0500
++++ gcc-4.9.0-extelim-v4-49/gcc/passes.def      2014-06-23 06:47:57.177372771 -0500
+@@ -350,6 +353,9 @@
+       NEXT_PASS (pass_web);
+       NEXT_PASS (pass_rtl_cprop);
+       NEXT_PASS (pass_cse2);
++#ifdef ENABLE_EXTELIM
++      NEXT_PASS (pass_rtl_extelim);
++#endif
+       NEXT_PASS (pass_rtl_dse1);
+       NEXT_PASS (pass_rtl_fwprop_addr);
+       NEXT_PASS (pass_inc_dec);
+diff -Naur gcc-4.9.0/gcc/tree-pass.h gcc-4.9.0-extelim-v4-49/gcc/tree-pass.h
+--- gcc-4.9.0/gcc/tree-pass.h   2014-06-23 06:53:55.464372003 -0500
++++ gcc-4.9.0-extelim-v4-49/gcc/tree-pass.h     2014-06-23 06:55:48.850372107 -0500
+@@ -487,6 +490,9 @@
+
+ extern rtl_opt_pass *make_pass_expand (gcc::context *ctxt);
+ extern rtl_opt_pass *make_pass_instantiate_virtual_regs (gcc::context *ctxt);
++#ifdef ENABLE_EXTELIM
++extern rtl_opt_pass *make_pass_rtl_extelim (gcc::context *ctxt);
++#endif
+ extern rtl_opt_pass *make_pass_rtl_fwprop (gcc::context *ctxt);
+ extern rtl_opt_pass *make_pass_rtl_fwprop_addr (gcc::context *ctxt);
+ extern rtl_opt_pass *make_pass_jump (gcc::context *ctxt);
+
+diff -Naur gcc-4.9.0/gcc/config/rs6000/extelim.c gcc-4.9.0-extelim-v5-49/gcc/config/rs6000/extelim.c
+--- gcc-4.9.0/gcc/config/rs6000/extelim.c	2014-06-23 07:28:52.129371041 -0500
++++ gcc-4.9.0-extelim-v5-49/gcc/config/rs6000/extelim.c	2014-06-23 08:01:42.535372591 -0500
+@@ -583,7 +583,7 @@
+   rtx insn;
+   extelim_uid_t lmax_uid = 0;
+ 
+-  FOR_EACH_BB (bb) FOR_BB_INSNS (bb, insn)
++  FOR_EACH_BB_FN (bb, cfun) FOR_BB_INSNS (bb, insn)
+   {
+     if (INSN_P (insn))
+       {
+@@ -880,7 +880,7 @@
+   bool has_extensions;
+ 
+   /* For all insns, call note_use for each use in insn.  */
+-  FOR_EACH_BB (bb)
++  FOR_EACH_BB_FN (bb, cfun)
+   {
+     FOR_BB_INSNS (bb, insn)
+     {
+@@ -3144,7 +3144,7 @@
+   bool found = false;
+ 
+   /* For all insns  */
+-  FOR_EACH_BB (bb)
++  FOR_EACH_BB_FN (bb, cfun)
+   {
+     FOR_BB_INSNS (bb, insn)
+     {
+@@ -3464,38 +3464,54 @@
+     }
+ }
+ 
+-/* Remove redundant extensions.  */
++namespace {
++
++const pass_data pass_data_rtl_extelim =
++{
++  RTL_PASS,							/* type */
++  "extelim", 							/* name */
++  OPTGROUP_NONE,						/* optinfo_flags */
++  true,								/* has_gate */
++  true,								/* has_execute */
++  TV_EXTELIM,							/* tv_id */
++  0,								/* properties_required */
++  0,								/* properties_provided */
++  0,								/* properties_destroyed */
++  0,								/* todo_flags_start */
++  ( TODO_df_finish | TODO_verify_rtl_sharing ),		/* todo_flags_finish */
++};
+ 
+-static unsigned int
+-rest_of_handle_extelim (void)
++class pass_rtl_extelim : public rtl_opt_pass
++{
++public:
++  pass_rtl_extelim (gcc::context *ctxt)
++    : rtl_opt_pass (pass_data_rtl_extelim, ctxt)
++  {}
++
++  /* opt_pass methods: */
++  virtual bool gate (function *)
++    {
++      /* Run extelim pass when flag_extelim is set at optimization level > 0.  */
++      return (optimize > 0 && flag_extelim);
++    }
++
++  virtual unsigned int execute (function *);
++
++}; // class pass_rtl_extelim
++
++/* Remove redundant extensions.  */
++unsigned int
++pass_rtl_extelim::execute (function *fun ATTRIBUTE_UNUSED)
+ {
+   extension_elimination ();
+   return 0;
+ }
+ 
+-/* Run extelim pass when flag_extelim is set at optimization level > 0.  */
++} // anon namespace
+ 
+-static bool
+-gate_handle_extelim (void)
++rtl_opt_pass *
++make_pass_rtl_extelim (gcc::context *ctxt)
+ {
+-  return (optimize > 0 && flag_extelim);
++  return new pass_rtl_extelim (ctxt);
+ }
+ 
+-struct rtl_opt_pass pass_rtl_extelim = {
+-  {
+-   RTL_PASS,
+-   "extelim",                   /* name */
+-   OPTGROUP_NONE,               /* optinfo_flags */
+-   gate_handle_extelim,         /* gate */
+-   rest_of_handle_extelim,      /* execute */
+-   NULL,                        /* sub */
+-   NULL,                        /* next */
+-   0,                           /* static_pass_number */
+-   TV_EXTELIM,                  /* tv_id */
+-   0,                           /* properties_required */
+-   0,                           /* properties_provided */
+-   0,                           /* properties_destroyed */
+-   0,                           /* todo_flags_start */
+-   TODO_ggc_collect | TODO_df_finish | TODO_verify_rtl_sharing,        /* todo_flags_finish */
+-   }
+-};
+diff -Naur gcc-4.9.0/gcc/config/rs6000/t-rs6000 gcc-4.9.0-extelim-v5-49/gcc/config/rs6000/t-rs6000
+--- gcc-4.9.0/gcc/config/rs6000/t-rs6000	2014-06-23 08:05:22.079372002 -0500
++++ gcc-4.9.0-extelim-v5-49/gcc/config/rs6000/t-rs6000	2014-06-23 08:01:31.479372221 -0500
+@@ -24,6 +24,14 @@
+ 	$(COMPILE) $<
+ 	$(POSTCOMPILE)
+ 
++extelim.o: $(srcdir)/config/rs6000/extelim.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
++   $(TREE_H) $(TM_P_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) \
++   insn-config.h $(FUNCTION_H) $(EXPR_H) $(INSN_ATTR_H) $(RECOG_H) \
++   toplev.h $(TARGET_H) $(TIMEVAR_H) $(OPTABS_H) insn-codes.h  \
++   output.h $(PARAMS_H) $(TREE_PASS_H) $(CGRAPH_H)
++	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
++                $(srcdir)/config/rs6000/extelim.c
++
+ $(srcdir)/config/rs6000/rs6000-tables.opt: $(srcdir)/config/rs6000/genopt.sh \
+   $(srcdir)/config/rs6000/rs6000-cpus.def
+ 	$(SHELL) $(srcdir)/config/rs6000/genopt.sh $(srcdir)/config/rs6000 > \
+diff -Naur gcc-4.8.3/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2b-big-array.c gcc-4.8.3-extelim-testcase/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2b-big-array.c
+--- gcc-4.8.3/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2b-big-array.c	2014-08-13 04:14:08.256015000 -0500
++++ gcc-4.8.3-extelim-testcase/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2b-big-array.c	2014-08-13 04:50:51.579014349 -0500
+@@ -3,7 +3,7 @@
+ #include <stdarg.h>
+ #include "tree-vect.h"
+ 
+-#define N 128
++#define N 64
+ signed char data_ch[N];
+ 
+ volatile int y = 0;
+diff -Naur gcc-4.9.1/gcc/config/rs6000/extelim.c gcc-4.9.1-extelim/gcc/config/rs6000/extelim.c
+--- gcc-4.9.1/gcc/config/rs6000/extelim.c	2014-09-13 04:40:43.929455001 -0500
++++ gcc-4.9.1-extelim/gcc/config/rs6000/extelim.c	2014-09-13 06:09:08.426454227 -0500
+@@ -617,8 +617,6 @@
+ static void
+ init_flags_vector (void)
+ {
+-  extelim_uid_t i;
+-  insn_flag_t * flags;
+   /* Get the maximum uid value. We'll use this
+      information to set up a vector of max_uid
+      length. Each element of the vector will hold
+@@ -3351,10 +3349,15 @@
+   return (bb_loop_depth(bb2) - bb_loop_depth(bb1));
+ }
+ 
+-/* The main interface to this optimization. */
++static bool
++gate_handle_extelim (void)
++{
++  return (optimize > 0 && flag_extelim);
++}
+ 
+-static void
+-extension_elimination (void)
++/* The main interface to this optimization. */
++static unsigned int
++rest_of_handle_extelim (void)
+ {
+   ext_record_t ext;
+   unsigned i;
+@@ -3365,7 +3368,7 @@
+   if (!find_extensions ())
+     {
+       finish_pass ();
+-      return;
++      return 0;
+     }
+ 
+   /* Insert sign extension at return points in
+@@ -3401,7 +3404,7 @@
+  if (!find_extensions ())
+     {
+       finish_pass ();
+-      return;
++      return 0;
+     }
+ 
+   if (dump_file)
+@@ -3462,6 +3465,7 @@
+                num_cand_transformed, num_cand,
+                ((float) num_cand_transformed / (float) num_cand) * 100);
+     }
++  return 0;
+ }
+ 
+ namespace {
+@@ -3489,24 +3493,11 @@
+   {}
+ 
+   /* opt_pass methods: */
+-  virtual bool gate (function *)
+-    {
+-      /* Run extelim pass when flag_extelim is set at optimization level > 0.  */
+-      return (optimize > 0 && flag_extelim);
+-    }
+-
+-  virtual unsigned int execute (function *);
++  bool gate () { return gate_handle_extelim (); }
++  unsigned int execute () { return rest_of_handle_extelim (); }
+ 
+ }; // class pass_rtl_extelim
+ 
+-/* Remove redundant extensions.  */
+-unsigned int
+-pass_rtl_extelim::execute (function *fun ATTRIBUTE_UNUSED)
+-{
+-  extension_elimination ();
+-  return 0;
+-}
+-
+ } // anon namespace
+ 
+ rtl_opt_pass *
+diff -Naur gcc-4.9.1/gcc/config/rs6000/extelim.c gcc-4.9.1-signed-overlfow-check/gcc/config/rs6000/extelim.c
+--- gcc-4.9.1/gcc/config/rs6000/extelim.c	2014-09-13 12:52:27.030100930 -0500
++++ gcc-4.9.1-signed-overlfow-check/gcc/config/rs6000/extelim.c	2014-09-14 04:03:07.405101000 -0500
+@@ -203,7 +203,7 @@
+ 
+ PROGRAM STRUCTURE:
+ 
+-extension elimination                            -- main entry point
++rest_of_handle_extelim                           -- main entry point
+  find extensions                                 -- identify extension candidates
+  extension duplication                           -- insert extension at strategic points to
+                                                     enable removal of extensions at more frequently
+@@ -3352,7 +3352,8 @@
+ static bool
+ gate_handle_extelim (void)
+ {
+-  return (optimize > 0 && flag_extelim);
++  return (optimize > 0 && flag_extelim
++          && !flag_wrapv && !flag_trapv && flag_strict_overflow);
+ }
+ 
+ /* The main interface to this optimization. */
+diff -Naur gcc-4.9.1/gcc/config/rs6000/extelim.c gcc-4.9.1-extelim-fix/gcc/config/rs6000/extelim.c
+--- gcc-4.9.1/gcc/config/rs6000/extelim.c	2014-09-25 07:43:12.451678000 -0500
++++ gcc-4.9.1-extelim-fix/gcc/config/rs6000/extelim.c	2014-09-25 07:50:41.455678000 -0500
+@@ -1799,9 +1799,9 @@
+          previous extension and extends to at least the extent of the original. */
+       enum machine_mode cand_from_mode = GET_MODE (XEXP (src, 0));
+       enum machine_mode cand_to_mode = GET_MODE (src);
+-      if (GET_MODE_BITSIZE (cand_from_mode) >=
++      if (GET_MODE_BITSIZE (cand_from_mode) <=
+           GET_MODE_BITSIZE (ext_from_mode)
+-          && (GET_MODE_BITSIZE (cand_to_mode) <=
++          && (GET_MODE_BITSIZE (cand_to_mode) >=
+               GET_MODE_BITSIZE (ext_to_mode)))
+         return true;
+     }
+diff -Naur gcc-4.9.2/gcc/testsuite/gcc.dg/sms-1.c gcc-4.9.2_extelim_tests_update/gcc/testsuite/gcc.dg/sms-1.c
+--- gcc-4.9.2/gcc/testsuite/gcc.dg/sms-1.c	2009-04-27 07:17:09.000000000 -0500
++++ gcc-4.9.2_extelim_tests_update/gcc/testsuite/gcc.dg/sms-1.c	2014-11-12 23:31:23.056244230 -0600
+@@ -2,6 +2,7 @@
+    due to not handling of subreg in the lhs that is fixed.  */
+ /* { dg-do run } */
+ /* { dg-options "-O2 -fmodulo-sched -fmodulo-sched-allow-regmoves -fdump-rtl-sms" } */
++/* { dg-additional-options "-fno-extelim" { target { powerpc*-*-* && lp64 } } } */
+ 
+ 
+ #include <limits.h>
+diff -Naur gcc-4.9.2/gcc/testsuite/gcc.dg/sms-6.c gcc-4.9.2_extelim_tests_update/gcc/testsuite/gcc.dg/sms-6.c
+--- gcc-4.9.2/gcc/testsuite/gcc.dg/sms-6.c	2014-02-19 09:44:11.000000000 -0600
++++ gcc-4.9.2_extelim_tests_update/gcc/testsuite/gcc.dg/sms-6.c	2014-11-13 01:03:01.877797261 -0600
+@@ -2,6 +2,7 @@
+ /* { dg-require-effective-target size32plus } */
+ /* { dg-options "-O2 -fmodulo-sched -fdump-rtl-sms --param sms-min-sc=1" } */
+ /* { dg-options "-O2 -fmodulo-sched -fdump-rtl-sms --param sms-min-sc=1 -fmodulo-sched-allow-regmoves" { target powerpc*-*-* } } */
++/* { dg-additional-options "-fno-extelim" { target { powerpc*-*-* && lp64 } } } */
+ 
+ extern void abort (void);
+ 
+diff -Naur gcc-4.9.2/gcc/config/rs6000/t-rs6000 gcc-4.9.2-patch/gcc/config/rs6000/t-rs6000
+--- gcc-4.9.2/gcc/config/rs6000/t-rs6000	2015-01-14 08:01:13.552172999 -0600
++++ gcc-4.9.2-patch/gcc/config/rs6000/t-rs6000	2015-01-14 08:03:02.656172977 -0600
+@@ -24,13 +24,9 @@
+ 	$(COMPILE) $<
+ 	$(POSTCOMPILE)
+ 
+-extelim.o: $(srcdir)/config/rs6000/extelim.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+-   $(TREE_H) $(TM_P_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) \
+-   insn-config.h $(FUNCTION_H) $(EXPR_H) $(INSN_ATTR_H) $(RECOG_H) \
+-   toplev.h $(TARGET_H) $(TIMEVAR_H) $(OPTABS_H) insn-codes.h  \
+-   output.h $(PARAMS_H) $(TREE_PASS_H) $(CGRAPH_H)
+-	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+-                $(srcdir)/config/rs6000/extelim.c
++extelim.o: $(srcdir)/config/rs6000/extelim.c 
++	$(COMPILE) $<
++	$(POSTCOMPILE)
+ 
+ $(srcdir)/config/rs6000/rs6000-tables.opt: $(srcdir)/config/rs6000/genopt.sh \
+   $(srcdir)/config/rs6000/rs6000-cpus.def
+diff -Naur gcc-4.9.2/gcc/context.c gcc-4.9.2-patch/gcc/context.c
+--- gcc-4.9.2/gcc/context.c	2014-01-02 16:23:26.000000000 -0600
++++ gcc-4.9.2-patch/gcc/context.c	2015-01-14 08:02:20.276171660 -0600
+@@ -20,6 +20,7 @@
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
++#include "tm.h"
+ #include "ggc.h"
+ #include "context.h"
+ #include "pass_manager.h"
+diff -Naur gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim-2.c gcc-4.9.2-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim-2.c
+--- gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim-2.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.2-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim-2.c	2015-01-15 06:49:00.041172999 -0600
+@@ -0,0 +1,24 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-options "-O2 -std=c99" } */
++/* { dg-final { scan-assembler "rlwinm \[0-9\]+,\[0-9\]+,\[0-9\]+,0xff"  { target { ilp32 } } } } */
++
++#define GET_MODULE(_id)         ((_id & 0x00003F00) >> 8)
++#define GET_IF(_id)             ((_id & 0x000000FF))
++#define GET_IF_ID(_module, _if) (((_module) << 8) | (_if))
++
++unsigned int dev;
++
++void testthebug(unsigned short i);
++
++void testbug(void)
++{
++  unsigned char  module;
++  unsigned char  interface;
++  unsigned short ifid;
++
++  module = GET_MODULE(dev);
++  interface = GET_IF(dev);
++  ifid = GET_IF_ID(module + 1, interface + 1);
++
++  testthebug(ifid);
++}
diff --git a/recipes-devtools/gcc/gcc-4.9/0005-uclibc-locale-no__x.patch b/recipes-devtools/gcc/gcc-4.9/0005-uclibc-locale-no__x.patch
new file mode 100644
index 0000000..dcbbfe4
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0005-uclibc-locale-no__x.patch
@@ -0,0 +1,257 @@
+From 6a3e8506a12c12728d8b29901defd738be43757f Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:42:36 +0400
+Subject: [PATCH 05/35] uclibc-locale-no__x
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ .../config/locale/uclibc/c++locale_internal.h      |   45 ++++++++++++++++++++
+ libstdc++-v3/config/locale/uclibc/c_locale.cc      |   14 ------
+ libstdc++-v3/config/locale/uclibc/c_locale.h       |    1 +
+ .../config/locale/uclibc/collate_members.cc        |    7 ---
+ libstdc++-v3/config/locale/uclibc/ctype_members.cc |    7 ---
+ .../config/locale/uclibc/messages_members.cc       |    7 +--
+ .../config/locale/uclibc/messages_members.h        |   18 +++-----
+ .../config/locale/uclibc/monetary_members.cc       |    4 --
+ .../config/locale/uclibc/numeric_members.cc        |    3 --
+ libstdc++-v3/config/locale/uclibc/time_members.cc  |    3 --
+ 10 files changed, 55 insertions(+), 54 deletions(-)
+
+diff --git a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
+index 2ae3e4a..e74fddf 100644
+--- a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
++++ b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
+@@ -60,4 +60,49 @@ extern "C" __typeof(wcsxfrm_l) __wcsxfrm_l;
+ extern "C" __typeof(wctype_l) __wctype_l;
+ #endif
+ 
++# define __nl_langinfo_l nl_langinfo_l
++# define __strcoll_l strcoll_l
++# define __strftime_l strftime_l
++# define __strtod_l strtod_l
++# define __strtof_l strtof_l
++# define __strtold_l strtold_l
++# define __strxfrm_l strxfrm_l
++# define __newlocale newlocale
++# define __freelocale freelocale
++# define __duplocale duplocale
++# define __uselocale uselocale
++
++# ifdef _GLIBCXX_USE_WCHAR_T
++#  define __iswctype_l iswctype_l
++#  define __towlower_l towlower_l
++#  define __towupper_l towupper_l
++#  define __wcscoll_l wcscoll_l
++#  define __wcsftime_l wcsftime_l
++#  define __wcsxfrm_l wcsxfrm_l
++#  define __wctype_l wctype_l
++# endif
++
++#else
++# define __nl_langinfo_l(N, L)       nl_langinfo((N))
++# define __strcoll_l(S1, S2, L)      strcoll((S1), (S2))
++# define __strtod_l(S, E, L)         strtod((S), (E))
++# define __strtof_l(S, E, L)         strtof((S), (E))
++# define __strtold_l(S, E, L)        strtold((S), (E))
++# define __strxfrm_l(S1, S2, N, L)   strxfrm((S1), (S2), (N))
++# warning should dummy __newlocale check for C|POSIX ?
++# define __newlocale(a, b, c)        NULL
++# define __freelocale(a)             ((void)0)
++# define __duplocale(a)              __c_locale()
++//# define __uselocale ?
++//
++# ifdef _GLIBCXX_USE_WCHAR_T
++#  define __iswctype_l(C, M, L)       iswctype((C), (M))
++#  define __towlower_l(C, L)          towlower((C))
++#  define __towupper_l(C, L)          towupper((C))
++#  define __wcscoll_l(S1, S2, L)      wcscoll((S1), (S2))
++//#  define __wcsftime_l(S, M, F, T, L)  wcsftime((S), (M), (F), (T))
++#  define __wcsxfrm_l(S1, S2, N, L)   wcsxfrm((S1), (S2), (N))
++#  define __wctype_l(S, L)            wctype((S))
++# endif
++
+ #endif // GLIBC 2.3 and later
+diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.cc b/libstdc++-v3/config/locale/uclibc/c_locale.cc
+index 5081dc1..21430d0 100644
+--- a/libstdc++-v3/config/locale/uclibc/c_locale.cc
++++ b/libstdc++-v3/config/locale/uclibc/c_locale.cc
+@@ -39,20 +39,6 @@
+ #include <langinfo.h>
+ #include <bits/c++locale_internal.h>
+ 
+-#ifndef __UCLIBC_HAS_XLOCALE__
+-#define __strtol_l(S, E, B, L)      strtol((S), (E), (B))
+-#define __strtoul_l(S, E, B, L)     strtoul((S), (E), (B))
+-#define __strtoll_l(S, E, B, L)     strtoll((S), (E), (B))
+-#define __strtoull_l(S, E, B, L)    strtoull((S), (E), (B))
+-#define __strtof_l(S, E, L)         strtof((S), (E))
+-#define __strtod_l(S, E, L)         strtod((S), (E))
+-#define __strtold_l(S, E, L)        strtold((S), (E))
+-#warning should dummy __newlocale check for C|POSIX ?
+-#define __newlocale(a, b, c)        NULL
+-#define __freelocale(a)             ((void)0)
+-#define __duplocale(a)              __c_locale()
+-#endif
+-
+ namespace std
+ {
+   template<>
+diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.h b/libstdc++-v3/config/locale/uclibc/c_locale.h
+index da07c1f..4bca5f1 100644
+--- a/libstdc++-v3/config/locale/uclibc/c_locale.h
++++ b/libstdc++-v3/config/locale/uclibc/c_locale.h
+@@ -68,6 +68,7 @@ namespace __gnu_cxx
+ {
+   extern "C" __typeof(uselocale) __uselocale;
+ }
++#define __uselocale uselocale
+ #endif
+ 
+ namespace std
+diff --git a/libstdc++-v3/config/locale/uclibc/collate_members.cc b/libstdc++-v3/config/locale/uclibc/collate_members.cc
+index c2664a7..ec5c329 100644
+--- a/libstdc++-v3/config/locale/uclibc/collate_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/collate_members.cc
+@@ -36,13 +36,6 @@
+ #include <locale>
+ #include <bits/c++locale_internal.h>
+ 
+-#ifndef __UCLIBC_HAS_XLOCALE__
+-#define __strcoll_l(S1, S2, L)      strcoll((S1), (S2))
+-#define __strxfrm_l(S1, S2, N, L)   strxfrm((S1), (S2), (N))
+-#define __wcscoll_l(S1, S2, L)      wcscoll((S1), (S2))
+-#define __wcsxfrm_l(S1, S2, N, L)   wcsxfrm((S1), (S2), (N))
+-#endif
+-
+ namespace std
+ {
+   // These are basically extensions to char_traits, and perhaps should
+diff --git a/libstdc++-v3/config/locale/uclibc/ctype_members.cc b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
+index 7294e3a..7b12861 100644
+--- a/libstdc++-v3/config/locale/uclibc/ctype_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
+@@ -38,13 +38,6 @@
+ #undef _LIBC
+ #include <bits/c++locale_internal.h>
+ 
+-#ifndef __UCLIBC_HAS_XLOCALE__
+-#define __wctype_l(S, L)           wctype((S))
+-#define __towupper_l(C, L)         towupper((C))
+-#define __towlower_l(C, L)         towlower((C))
+-#define __iswctype_l(C, M, L)      iswctype((C), (M))
+-#endif
+-
+ namespace std
+ {
+   // NB: The other ctype<char> specializations are in src/locale.cc and
+diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.cc b/libstdc++-v3/config/locale/uclibc/messages_members.cc
+index 13594d9..d7693b4 100644
+--- a/libstdc++-v3/config/locale/uclibc/messages_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/messages_members.cc
+@@ -39,13 +39,10 @@
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning fix gettext stuff
+ #endif
+-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
+-extern "C" char *__dcgettext(const char *domainname,
+-			     const char *msgid, int category);
+ #undef gettext
+-#define gettext(msgid) __dcgettext(NULL, msgid, LC_MESSAGES)
++#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
++#define gettext(msgid) dcgettext(NULL, msgid, LC_MESSAGES)
+ #else
+-#undef gettext
+ #define gettext(msgid) (msgid)
+ #endif
+ 
+diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.h b/libstdc++-v3/config/locale/uclibc/messages_members.h
+index 1424078..d89da33 100644
+--- a/libstdc++-v3/config/locale/uclibc/messages_members.h
++++ b/libstdc++-v3/config/locale/uclibc/messages_members.h
+@@ -36,15 +36,11 @@
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning fix prototypes for *textdomain funcs
+ #endif
+-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
+-extern "C" char *__textdomain(const char *domainname);
+-extern "C" char *__bindtextdomain(const char *domainname,
+-				  const char *dirname);
+-#else
+-#undef __textdomain
+-#undef __bindtextdomain
+-#define __textdomain(D)           ((void)0)
+-#define __bindtextdomain(D,P)     ((void)0)
++#ifndef __UCLIBC_HAS_GETTEXT_AWARENESS__
++#undef textdomain
++#undef bindtextdomain
++#define textdomain(D)           ((void)0)
++#define bindtextdomain(D,P)     ((void)0)
+ #endif
+ 
+   // Non-virtual member functions.
+@@ -70,7 +66,7 @@ extern "C" char *__bindtextdomain(const char *domainname,
+     messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc,
+ 			   const char* __dir) const
+     {
+-      __bindtextdomain(__s.c_str(), __dir);
++      bindtextdomain(__s.c_str(), __dir);
+       return this->do_open(__s, __loc);
+     }
+ 
+@@ -90,7 +86,7 @@ extern "C" char *__bindtextdomain(const char *domainname,
+     {
+       // No error checking is done, assume the catalog exists and can
+       // be used.
+-      __textdomain(__s.c_str());
++      textdomain(__s.c_str());
+       return 0;
+     }
+ 
+diff --git a/libstdc++-v3/config/locale/uclibc/monetary_members.cc b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+index aa52731..2e6f80a 100644
+--- a/libstdc++-v3/config/locale/uclibc/monetary_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+@@ -43,10 +43,6 @@
+ #warning tailor for stub locale support
+ #endif
+ 
+-#ifndef __UCLIBC_HAS_XLOCALE__
+-#define __nl_langinfo_l(N, L)         nl_langinfo((N))
+-#endif
+-
+ namespace std
+ {
+   // Construct and return valid pattern consisting of some combination of:
+diff --git a/libstdc++-v3/config/locale/uclibc/numeric_members.cc b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+index 883ec1a..2c70642 100644
+--- a/libstdc++-v3/config/locale/uclibc/numeric_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+@@ -41,9 +41,6 @@
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning tailor for stub locale support
+ #endif
+-#ifndef __UCLIBC_HAS_XLOCALE__
+-#define __nl_langinfo_l(N, L)         nl_langinfo((N))
+-#endif
+ 
+ namespace std
+ {
+diff --git a/libstdc++-v3/config/locale/uclibc/time_members.cc b/libstdc++-v3/config/locale/uclibc/time_members.cc
+index e0707d7..d848ed5 100644
+--- a/libstdc++-v3/config/locale/uclibc/time_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/time_members.cc
+@@ -40,9 +40,6 @@
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning tailor for stub locale support
+ #endif
+-#ifndef __UCLIBC_HAS_XLOCALE__
+-#define __nl_langinfo_l(N, L)         nl_langinfo((N))
+-#endif
+ 
+ namespace std
+ {
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0005.gcc.extelim_vrp_kugan-v1-49x.patch b/recipes-devtools/gcc/gcc-4.9/0005.gcc.extelim_vrp_kugan-v1-49x.patch
new file mode 100644
index 0000000..8d06b1c
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0005.gcc.extelim_vrp_kugan-v1-49x.patch
@@ -0,0 +1,709 @@
+# Problem Statement:
+  Eliminate sign and zero extensions in PPC generated code based on
+  Value Range Information.
+
+# Owned by:
+  Rohit
+
+# Referred from patch by:
+  Kugan Vivekanandarajah
+
+# Action:
+  * Backport r213749 and r213750 from trunk to remove
+    redundant sign/zero extensions during RTL expansion.
+  * Fix ENGR00340415 and add test case.
+  * Add code to eliminate sign/zero extension for ternary operation.
+
+diff -Naur gcc-4.9.2/gcc/calls.c gcc-4.9.2-kugan-extelim-patch/gcc/calls.c
+--- gcc-4.9.2/gcc/calls.c	2014-03-20 06:35:22.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/calls.c	2014-11-12 06:58:40.207947839 -0600
+@@ -1499,8 +1499,10 @@
+ 	      args[i].initial_value
+ 		= gen_lowpart_SUBREG (mode, args[i].value);
+ 	      SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
+-	      SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
+-					    args[i].unsignedp);
++	      if (promoted_for_signed_and_unsigned_p (args[i].tree_value, mode))
++		SUBREG_PROMOTED_SET (args[i].initial_value, SRP_SIGNED_AND_UNSIGNED);
++	      else
++		SUBREG_PROMOTED_SET (args[i].initial_value, args[i].unsignedp);
+ 	    }
+ 	}
+     }
+@@ -3375,7 +3377,7 @@
+ 
+ 	  target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
+ 	  SUBREG_PROMOTED_VAR_P (target) = 1;
+-	  SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
++	  SUBREG_PROMOTED_SET (target, unsignedp);
+ 	}
+ 
+       /* If size of args is variable or this was a constructor call for a stack
+diff -Naur gcc-4.9.2/gcc/cfgexpand.c gcc-4.9.2-kugan-extelim-patch/gcc/cfgexpand.c
+--- gcc-4.9.2/gcc/cfgexpand.c	2014-04-22 08:15:24.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/cfgexpand.c	2014-11-12 06:58:40.208947888 -0600
+@@ -3265,7 +3265,7 @@
+ 	      ;
+ 	    else if (promoted)
+ 	      {
+-		int unsignedp = SUBREG_PROMOTED_UNSIGNED_P (target);
++		int unsignedp = SUBREG_PROMOTED_SIGN (target);
+ 		/* If TEMP is a VOIDmode constant, use convert_modes to make
+ 		   sure that we properly convert it.  */
+ 		if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
+@@ -3277,7 +3277,13 @@
+ 					  GET_MODE (target), temp, unsignedp);
+ 		  }
+ 
+-		convert_move (SUBREG_REG (target), temp, unsignedp);
++		if ((SUBREG_PROMOTED_GET (target) == SRP_SIGNED_AND_UNSIGNED)
++		    && (GET_CODE (temp) == SUBREG)
++		    && (GET_MODE (target) == GET_MODE (temp))
++		    && (GET_MODE (SUBREG_REG (target)) == GET_MODE (SUBREG_REG (temp))))
++		  emit_move_insn (SUBREG_REG (target), SUBREG_REG (temp));
++		else
++		  convert_move (SUBREG_REG (target), temp, unsignedp);
+ 	      }
+ 	    else if (nontemporal && emit_storent_insn (target, temp))
+ 	      ;
+diff -Naur gcc-4.9.2/gcc/combine.c gcc-4.9.2-kugan-extelim-patch/gcc/combine.c
+--- gcc-4.9.2/gcc/combine.c	2014-07-08 10:43:39.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/combine.c	2014-11-12 06:58:40.211948210 -0600
+@@ -12433,7 +12433,7 @@
+       rsp = &reg_stat[regno];
+       if (rsp->last_set == insn)
+ 	{
+-	  if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
++	  if (SUBREG_PROMOTED_UNSIGNED_P (subreg))
+ 	    rsp->last_set_nonzero_bits &= GET_MODE_MASK (mode);
+ 	}
+ 
+diff -Naur gcc-4.9.2/gcc/expr.c gcc-4.9.2-kugan-extelim-patch/gcc/expr.c
+--- gcc-4.9.2/gcc/expr.c	2014-09-01 05:14:22.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/expr.c	2014-11-12 06:59:50.555951666 -0600
+@@ -67,6 +67,7 @@
+ #include "params.h"
+ #include "tree-ssa-address.h"
+ #include "cfgexpand.h"
++#include "tree-ssa.h"
+ 
+ /* Decide whether a function's arguments should be processed
+    from first to last or from last to first.
+@@ -344,7 +345,7 @@
+   if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from)
+       && (GET_MODE_PRECISION (GET_MODE (SUBREG_REG (from)))
+ 	  >= GET_MODE_PRECISION (to_mode))
+-      && SUBREG_PROMOTED_UNSIGNED_P (from) == unsignedp)
++      && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp))
+     from = gen_lowpart (to_mode, from), from_mode = to_mode;
+ 
+   gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
+@@ -718,7 +719,7 @@
+ 
+   if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
+       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode)
+-      && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp)
++      && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
+     x = gen_lowpart (mode, SUBREG_REG (x));
+ 
+   if (GET_MODE (x) != VOIDmode)
+@@ -5226,25 +5227,25 @@
+ 	  && GET_MODE_PRECISION (GET_MODE (target))
+ 	     == TYPE_PRECISION (TREE_TYPE (exp)))
+ 	{
+-	  if (TYPE_UNSIGNED (TREE_TYPE (exp))
+-	      != SUBREG_PROMOTED_UNSIGNED_P (target))
++	  if (!SUBREG_CHECK_PROMOTED_SIGN (target,
++					  TYPE_UNSIGNED (TREE_TYPE (exp))))
+ 	    {
+ 	      /* Some types, e.g. Fortran's logical*4, won't have a signed
+ 		 version, so use the mode instead.  */
+ 	      tree ntype
+ 		= (signed_or_unsigned_type_for
+-		   (SUBREG_PROMOTED_UNSIGNED_P (target), TREE_TYPE (exp)));
++		   (SUBREG_PROMOTED_SIGN (target), TREE_TYPE (exp)));
+ 	      if (ntype == NULL)
+ 		ntype = lang_hooks.types.type_for_mode
+ 		  (TYPE_MODE (TREE_TYPE (exp)),
+-		   SUBREG_PROMOTED_UNSIGNED_P (target));
++		   SUBREG_PROMOTED_SIGN (target));
+ 
+ 	      exp = fold_convert_loc (loc, ntype, exp);
+ 	    }
+ 
+ 	  exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode
+ 				  (GET_MODE (SUBREG_REG (target)),
+-				   SUBREG_PROMOTED_UNSIGNED_P (target)),
++				   SUBREG_PROMOTED_SIGN (target)),
+ 				  exp);
+ 
+ 	  inner_target = SUBREG_REG (target);
+@@ -5258,14 +5259,14 @@
+       if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
+ 	{
+ 	  temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
+-				temp, SUBREG_PROMOTED_UNSIGNED_P (target));
++				temp, SUBREG_PROMOTED_SIGN (target));
+ 	  temp = convert_modes (GET_MODE (SUBREG_REG (target)),
+ 			        GET_MODE (target), temp,
+-			        SUBREG_PROMOTED_UNSIGNED_P (target));
++				SUBREG_PROMOTED_SIGN (target));
+ 	}
+ 
+       convert_move (SUBREG_REG (target), temp,
+-		    SUBREG_PROMOTED_UNSIGNED_P (target));
++		    SUBREG_PROMOTED_SIGN (target));
+ 
+       return NULL_RTX;
+     }
+@@ -9232,6 +9233,35 @@
+ }
+ #undef REDUCE_BIT_FIELD
+ 
++/* Return TRUE if value in SSA is zero and sign extended for wider mode MODE
++   using value range information stored.  Return FALSE otherwise.
++
++   This is used to check if SUBREG is zero and sign extended and to set
++   promoted mode SRP_SIGNED_AND_UNSIGNED to SUBREG.  */
++
++bool
++promoted_for_signed_and_unsigned_p (tree ssa, enum machine_mode mode)
++{
++  wide_int min, max;
++
++  if (ssa == NULL_TREE
++      || TREE_CODE (ssa) != SSA_NAME
++      || !INTEGRAL_TYPE_P (TREE_TYPE (ssa))
++      || (TYPE_PRECISION (TREE_TYPE (ssa)) != GET_MODE_PRECISION (mode)))
++    return false;
++
++  /* Return FALSE if value_range is not recorded for SSA.  */
++  if (get_range_info (ssa, &min, &max) != VR_RANGE)
++    return false;
++
++  /* Return true (to set SRP_SIGNED_AND_UNSIGNED to SUBREG) if MSB of the
++     smaller mode is not set (i.e.  MSB of ssa is not set).  */
++  if (!wi::neg_p (min, SIGNED) && !wi::neg_p(max, SIGNED))
++    return true;
++  else
++    return false;
++
++}
+ 
+ /* Return TRUE if expression STMT is suitable for replacement.  
+    Never consider memory loads as replaceable, because those don't ever lead 
+@@ -9514,7 +9544,10 @@
+ 
+ 	  temp = gen_lowpart_SUBREG (mode, decl_rtl);
+ 	  SUBREG_PROMOTED_VAR_P (temp) = 1;
+-	  SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
++	  if (promoted_for_signed_and_unsigned_p (ssa_name, mode))
++	    SUBREG_PROMOTED_SET (temp, SRP_SIGNED_AND_UNSIGNED);
++	  else
++	    SUBREG_PROMOTED_SET (temp, unsignedp);
+ 	  return temp;
+ 	}
+ 
+diff -Naur gcc-4.9.2/gcc/expr.h gcc-4.9.2-kugan-extelim-patch/gcc/expr.h
+--- gcc-4.9.2/gcc/expr.h	2014-03-24 12:38:09.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/expr.h	2014-11-12 06:58:40.205947702 -0600
+@@ -446,6 +446,7 @@
+ 			       enum expand_modifier, rtx *, bool);
+ extern rtx expand_expr_real_2 (sepops, rtx, enum machine_mode,
+ 			       enum expand_modifier);
++extern bool promoted_for_signed_and_unsigned_p (tree, enum machine_mode);
+ 
+ /* Generate code for computing expression EXP.
+    An rtx for the computed value is returned.  The value is never null.
+diff -Naur gcc-4.9.2/gcc/function.c gcc-4.9.2-kugan-extelim-patch/gcc/function.c
+--- gcc-4.9.2/gcc/function.c	2014-07-10 05:41:15.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/function.c	2014-11-12 06:58:40.206947771 -0600
+@@ -3085,7 +3085,7 @@
+ 	  /* The argument is already sign/zero extended, so note it
+ 	     into the subreg.  */
+ 	  SUBREG_PROMOTED_VAR_P (tempreg) = 1;
+-	  SUBREG_PROMOTED_UNSIGNED_SET (tempreg, unsignedp);
++	  SUBREG_PROMOTED_SET (tempreg, unsignedp);
+ 	}
+ 
+       /* TREE_USED gets set erroneously during expand_assignment.  */
+diff -Naur gcc-4.9.2/gcc/ifcvt.c gcc-4.9.2-kugan-extelim-patch/gcc/ifcvt.c
+--- gcc-4.9.2/gcc/ifcvt.c	2014-09-30 05:33:25.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/ifcvt.c	2014-11-12 06:58:40.202947490 -0600
+@@ -1473,8 +1473,8 @@
+ 	  || byte_vtrue != byte_vfalse
+ 	  || (SUBREG_PROMOTED_VAR_P (vtrue)
+ 	      != SUBREG_PROMOTED_VAR_P (vfalse))
+-	  || (SUBREG_PROMOTED_UNSIGNED_P (vtrue)
+-	      != SUBREG_PROMOTED_UNSIGNED_P (vfalse)))
++	  || (SUBREG_PROMOTED_GET (vtrue)
++	      != SUBREG_PROMOTED_GET (vfalse)))
+ 	return NULL_RTX;
+ 
+       promoted_target = gen_reg_rtx (GET_MODE (reg_vtrue));
+@@ -1488,7 +1488,7 @@
+ 
+       target = gen_rtx_SUBREG (GET_MODE (vtrue), promoted_target, byte_vtrue);
+       SUBREG_PROMOTED_VAR_P (target) = SUBREG_PROMOTED_VAR_P (vtrue);
+-      SUBREG_PROMOTED_UNSIGNED_SET (target, SUBREG_PROMOTED_UNSIGNED_P (vtrue));
++      SUBREG_PROMOTED_SET (target, SUBREG_PROMOTED_GET (vtrue));
+       emit_move_insn (x, target);
+       return x;
+     }
+diff -Naur gcc-4.9.2/gcc/internal-fn.c gcc-4.9.2-kugan-extelim-patch/gcc/internal-fn.c
+--- gcc-4.9.2/gcc/internal-fn.c	2014-10-16 08:51:45.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/internal-fn.c	2014-11-12 06:58:40.196947034 -0600
+@@ -600,12 +600,12 @@
+ 	  if (GET_CODE (lopart0) == SUBREG)
+ 	    {
+ 	      SUBREG_PROMOTED_VAR_P (lopart0) = 1;
+-	      SUBREG_PROMOTED_UNSIGNED_SET (lopart0, 0);
++	      SUBREG_PROMOTED_SET (lopart0, 0);
+ 	    }
+ 	  if (GET_CODE (lopart1) == SUBREG)
+ 	    {
+ 	      SUBREG_PROMOTED_VAR_P (lopart1) = 1;
+-	      SUBREG_PROMOTED_UNSIGNED_SET (lopart1, 0);
++	      SUBREG_PROMOTED_SET (lopart1, 0);
+ 	    }
+ 	  tree halfstype = build_nonstandard_integer_type (hprec, 0);
+ 	  ops.op0 = make_tree (halfstype, lopart0);
+diff -Naur gcc-4.9.2/gcc/optabs.c gcc-4.9.2-kugan-extelim-patch/gcc/optabs.c
+--- gcc-4.9.2/gcc/optabs.c	2014-08-14 04:32:17.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/optabs.c	2014-11-12 06:58:40.193946790 -0600
+@@ -349,7 +349,7 @@
+      a promoted object differs from our extension.  */
+   if (! no_extend
+       || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
+-	  && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
++	  && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
+     return convert_modes (mode, oldmode, op, unsignedp);
+ 
+   /* If MODE is no wider than a single word, we return a lowpart or paradoxical
+diff -Naur gcc-4.9.2/gcc/rtlanal.c gcc-4.9.2-kugan-extelim-patch/gcc/rtlanal.c
+--- gcc-4.9.2/gcc/rtlanal.c	2014-03-26 02:38:30.000000000 -0500
++++ gcc-4.9.2-kugan-extelim-patch/gcc/rtlanal.c	2014-11-12 06:58:40.195946953 -0600
+@@ -670,7 +670,7 @@
+     return true;
+ 
+   if (GET_CODE (op) == SUBREG
+-      && SUBREG_PROMOTED_UNSIGNED_P (op))
++      && SUBREG_PROMOTED_SIGN (op))
+     return true;
+ 
+   return false;
+@@ -4299,7 +4299,7 @@
+ 	 been zero-extended, we know that at least the high-order bits
+ 	 are zero, though others might be too.  */
+ 
+-      if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x) > 0)
++      if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x))
+ 	nonzero = GET_MODE_MASK (GET_MODE (x))
+ 		  & cached_nonzero_bits (SUBREG_REG (x), GET_MODE (x),
+ 					 known_x, known_mode, known_ret);
+@@ -4609,7 +4609,7 @@
+ 	 and we are looking at it in a wider mode, we know that at least the
+ 	 high-order bits are known to be sign bit copies.  */
+ 
+-      if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
++      if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_SIGNED_P (x))
+ 	{
+ 	  num0 = cached_num_sign_bit_copies (SUBREG_REG (x), mode,
+ 					     known_x, known_mode, known_ret);
+diff -Naur gcc-4.9.2/gcc/rtl.h gcc-4.9.2-kugan-extelim-patch/gcc/rtl.h
+--- gcc-4.9.2/gcc/rtl.h	2014-01-23 02:24:38.000000000 -0600
++++ gcc-4.9.2-kugan-extelim-patch/gcc/rtl.h	2014-11-12 06:58:40.209947977 -0600
+@@ -1390,29 +1390,75 @@
+ #define SUBREG_PROMOTED_VAR_P(RTX)					\
+   (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED", (RTX), SUBREG)->in_struct)
+ 
+-#define SUBREG_PROMOTED_UNSIGNED_SET(RTX, VAL)				\
+-do {									\
+-  rtx const _rtx = RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_SET",	\
+-				    (RTX), SUBREG);			\
+-  if ((VAL) < 0)							\
+-    _rtx->volatil = 1;							\
+-  else {								\
+-    _rtx->volatil = 0;							\
+-    _rtx->unchanging = (VAL);						\
+-  }									\
+-} while (0)
+-
+ /* Valid for subregs which are SUBREG_PROMOTED_VAR_P().  In that case
+    this gives the necessary extensions:
+-   0  - signed
+-   1  - normal unsigned
++   0  - signed (SPR_SIGNED)
++   1  - normal unsigned (SPR_UNSIGNED)
++   2  - value is both sign and unsign extended for mode
++	(SPR_SIGNED_AND_UNSIGNED).
+    -1 - pointer unsigned, which most often can be handled like unsigned
+         extension, except for generating instructions where we need to
+-	emit special code (ptr_extend insns) on some architectures.  */
++	emit special code (ptr_extend insns) on some architectures
++	(SPR_POINTER). */
++
++const int SRP_POINTER = -1;
++const int SRP_SIGNED = 0;
++const int SRP_UNSIGNED = 1;
++const int SRP_SIGNED_AND_UNSIGNED = 2;
++
++/* Sets promoted mode for SUBREG_PROMOTED_VAR_P().  */
++#define SUBREG_PROMOTED_SET(RTX, VAL)		                        \
++do {								        \
++  rtx const _rtx = RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SET",		\
++                                    (RTX), SUBREG);			\
++  switch (VAL)								\
++  {									\
++    case SRP_POINTER:							\
++      _rtx->volatil = 0;						\
++      _rtx->unchanging = 0;						\
++      break;								\
++    case SRP_SIGNED:							\
++      _rtx->volatil = 0;						\
++      _rtx->unchanging = 1;						\
++      break;								\
++    case SRP_UNSIGNED:							\
++      _rtx->volatil = 1;						\
++      _rtx->unchanging = 0;						\
++      break;								\
++    case SRP_SIGNED_AND_UNSIGNED:					\
++      _rtx->volatil = 1;						\
++      _rtx->unchanging = 1;						\
++      break;								\
++  }									\
++} while (0)
+ 
++/* Gets the value stored in promoted mode for SUBREG_PROMOTED_VAR_P(),
++   including SRP_SIGNED_AND_UNSIGNED if promoted for
++   both signed and unsigned.  */
++#define SUBREG_PROMOTED_GET(RTX)	\
++  (2 * (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_GET", (RTX), SUBREG)->volatil)\
++   + (RTX)->unchanging - 1)
++
++/* Returns sign of promoted mode for SUBREG_PROMOTED_VAR_P().  */
++#define SUBREG_PROMOTED_SIGN(RTX)	\
++  ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGN", (RTX), SUBREG)->volatil) ? 1\
++   : (RTX)->unchanging - 1)
++
++/* Predicate to check if RTX of SUBREG_PROMOTED_VAR_P() is promoted
++   for SIGNED type.  */
++#define SUBREG_PROMOTED_SIGNED_P(RTX)	\
++  (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGNED_P", (RTX), SUBREG)->unchanging)
++
++/* Predicate to check if RTX of SUBREG_PROMOTED_VAR_P() is promoted
++   for UNSIGNED type.  */
+ #define SUBREG_PROMOTED_UNSIGNED_P(RTX)	\
+-  ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil) \
+-   ? -1 : (int) (RTX)->unchanging)
++  (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil)
++
++/* Checks if RTX of SUBREG_PROMOTED_VAR_P() is promoted for given SIGN.  */
++#define SUBREG_CHECK_PROMOTED_SIGN(RTX, SIGN)	\
++((SIGN) == SRP_POINTER ? SUBREG_PROMOTED_GET (RTX) == SRP_POINTER	\
++ : (SIGN) == SRP_SIGNED ? SUBREG_PROMOTED_SIGNED_P (RTX)		\
++ : SUBREG_PROMOTED_UNSIGNED_P (RTX))
+ 
+ /* True if the subreg was generated by LRA for reload insns.  Such
+    subregs are valid only during LRA.  */
+diff -Naur gcc-4.9.2/gcc/simplify-rtx.c gcc-4.9.2-kugan-extelim-patch/gcc/simplify-rtx.c
+--- gcc-4.9.2/gcc/simplify-rtx.c	2014-11-11 05:07:43.178952003 -0600
++++ gcc-4.9.2-kugan-extelim-patch/gcc/simplify-rtx.c	2014-11-12 06:58:40.209947977 -0600
+@@ -1335,7 +1335,7 @@
+ 	 target mode is the same as the variable's promotion.  */
+       if (GET_CODE (op) == SUBREG
+ 	  && SUBREG_PROMOTED_VAR_P (op)
+-	  && ! SUBREG_PROMOTED_UNSIGNED_P (op)
++	  && SUBREG_PROMOTED_SIGNED_P (op)
+ 	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+ 	{
+ 	  temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+@@ -1402,7 +1402,7 @@
+ 	 target mode is the same as the variable's promotion.  */
+       if (GET_CODE (op) == SUBREG
+ 	  && SUBREG_PROMOTED_VAR_P (op)
+-	  && SUBREG_PROMOTED_UNSIGNED_P (op) > 0
++	  && SUBREG_PROMOTED_UNSIGNED_P (op)
+ 	  && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+ 	{
+ 	  temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
+@@ -5990,7 +5990,7 @@
+ 	{
+ 	  newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
+ 	  if (SUBREG_PROMOTED_VAR_P (op)
+-	      && SUBREG_PROMOTED_UNSIGNED_P (op) >= 0
++	      && SUBREG_PROMOTED_SIGN (op) >= 0
+ 	      && GET_MODE_CLASS (outermode) == MODE_INT
+ 	      && IN_RANGE (GET_MODE_SIZE (outermode),
+ 			   GET_MODE_SIZE (innermode),
+@@ -5998,8 +5998,7 @@
+ 	      && subreg_lowpart_p (newx))
+ 	    {
+ 	      SUBREG_PROMOTED_VAR_P (newx) = 1;
+-	      SUBREG_PROMOTED_UNSIGNED_SET
+-		(newx, SUBREG_PROMOTED_UNSIGNED_P (op));
++	      SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
+ 	    }
+ 	  return newx;
+ 	}
+diff -Naur gcc-4.9.2/gcc/testsuite/gcc.dg/zero_sign_ext_test.c gcc-4.9.2-kugan-extelim-patch/gcc/testsuite/gcc.dg/zero_sign_ext_test.c
+--- gcc-4.9.2/gcc/testsuite/gcc.dg/zero_sign_ext_test.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.2-kugan-extelim-patch/gcc/testsuite/gcc.dg/zero_sign_ext_test.c	2014-11-12 06:58:40.200947342 -0600
+@@ -0,0 +1,136 @@
++extern void abort (void);
++
++/* { dg-options "-O2" } */
++/* { dg-do run } */
++
++#define TYPE_MAX(type, sign)	\
++  ((!sign) ? ((1 << (sizeof (type) * 8 - 1)) - 1) :	\
++   ((1 << (sizeof (type) * 8)) - 1))
++#define TYPE_MIN(type, sign)	\
++  ((!sign) ? -(1 << (sizeof (type) * 8 - 1)) : 0)
++
++#define TEST_FN(NAME, ARG_TYPE, RET_TYPE, CAST_TYPE, VAL, VR_MIN, VR_MAX)\
++  __attribute__((noinline, noclone)) RET_TYPE				\
++      NAME (ARG_TYPE arg){						\
++      RET_TYPE ret = VAL;						\
++      if (arg + 1 < VR_MIN || arg + 1 > VR_MAX) return ret;		\
++      /* Value Range of arg at this point will be  [VR_min, VR_max].  */\
++      arg = arg + VAL;							\
++      ret = (CAST_TYPE)arg;						\
++      return arg;							\
++  }
++
++/* Signed to signed conversion with value in-range.  */
++TEST_FN (foo1, short, short, char, 1, TYPE_MIN (char, 0), TYPE_MAX (char, 0));
++TEST_FN (foo2, short, short, char, 1, TYPE_MIN (char, 0) + 1,\
++	TYPE_MAX (char, 0) - 1);
++
++/* Signed to signed conversion with value not in-range.  */
++TEST_FN (foo3, short, short, char, -1, TYPE_MIN (short, 0) + 1,  100);
++TEST_FN (foo4, short, short, char, 1, 12, TYPE_MAX (short, 0) + 1);
++
++/* Unsigned to unsigned conversion with value in-range.  */
++TEST_FN (foo5, unsigned short, unsigned short, unsigned char, 1,\
++	TYPE_MIN (char, 1) + 1, TYPE_MAX (char, 1) - 1);
++TEST_FN (foo6, unsigned short, unsigned short, unsigned char, 1,\
++	TYPE_MIN (char, 1), TYPE_MAX (char, 1));
++
++/* Unsigned to unsigned conversion with value not in-range.  */
++TEST_FN (foo7, unsigned short, unsigned short, unsigned char, 1,\
++	TYPE_MIN (short, 1) + 1, TYPE_MAX (short, 1) - 1);
++TEST_FN (foo8, unsigned short, unsigned short, unsigned char, 1,\
++	TYPE_MIN (short, 1), TYPE_MAX (short, 1));
++
++/* Signed to unsigned conversion with value range positive.  */
++TEST_FN (foo9, short, short, unsigned char, -1, 1,\
++	TYPE_MAX (char, 1) - 1);
++TEST_FN (foo10, short, short, unsigned char, 1, 0,\
++	TYPE_MAX (char, 1));
++
++/* Signed to unsigned conversion with value range negative.  */
++TEST_FN (foo11, short, short, unsigned char, 1,\
++	TYPE_MIN (char, 0) + 1, TYPE_MAX (char, 0) - 1);
++TEST_FN (foo12, short, short, unsigned char, 1,\
++	TYPE_MIN (char, 0), TYPE_MAX (char, 0));
++
++/* Unsigned to Signed conversion with value range in signed equiv range.  */
++TEST_FN (foo13, unsigned short, unsigned short, char, 1,\
++	TYPE_MIN (char, 1) + 1, TYPE_MAX (char, 0) - 1);
++TEST_FN (foo14, unsigned short, unsigned short, char, 1,\
++	TYPE_MIN (char, 1), TYPE_MAX (char, 0));
++
++/* Unsigned to Signed conversion with value range not-in signed range.  */
++TEST_FN (foo15, unsigned short, unsigned short, char, 1,\
++	TYPE_MIN (char, 1) + 1, TYPE_MAX (char, 1) - 1);
++TEST_FN (foo16, unsigned short, unsigned short, char, 1,\
++	TYPE_MIN (char, 1), TYPE_MAX (char, 1));
++
++int main ()
++{
++  /* Signed to signed conversion with value in-range.  */
++  /* arg + 1.  */
++  if (foo1 (-32) != -31)
++    abort ();
++  /* arg + 1.  */
++  if (foo2 (32) != 33)
++    abort ();
++
++  /* Signed to signed conversion with value not in-range.  */
++  /* arg - 1.  */
++  if (foo3 (-512) != -513)
++    abort ();
++  /* arg + 1.  */
++  if (foo4 (512) != 513)
++    abort ();
++
++  /* Unsigned to unsigned conversion with value in-range.  */
++  /* arg + 1.  */
++  if (foo5 (64) != 65)
++    abort ();
++  /* arg + 1.  */
++  if (foo6 (64) != 65)
++    abort ();
++
++  /* Unsigned to unsigned conversion with value not in-range.  */
++  /* arg + 1.  */
++  if (foo7 (512) != 513)
++    abort ();
++  /* arg + 1.  */
++  if (foo8 (512) != 513)
++    abort ();
++
++  /* Signed to unsigned conversion with value range positive.  */
++  /* arg - 1.  */
++  if (foo9 (2) != 1)
++    abort ();
++  /* arg + 1.  */
++  if (foo10 (2) != 3)
++    abort ();
++
++  /* Signed to unsigned conversion with value range negative.  */
++  /* arg + 1.  */
++  if (foo11 (-125) != -124)
++    abort ();
++  /* arg + 1.  */
++  if (foo12 (-125) != -124)
++    abort ();
++
++  /* Unsigned to Signed conversion with value range in signed equiv range.  */
++  /* arg + 1.  */
++  if (foo13 (125) != 126)
++    abort ();
++  /* arg + 1.  */
++  if (foo14 (125) != 126)
++    abort ();
++
++  /* Unsigned to Signed conversion with value range not-in signed range.  */
++  /* arg + 1.  */
++  if (foo15 (250) != 251)
++    abort ();
++  /* arg + 1.  */
++  if (foo16 (250) != 251)
++    abort ();
++
++  return 0;
++}
++
+diff -Naur gcc-4.9.2-kugan-extelim-patch/gcc/expr.c gcc-4.9.2-kugan-extelim-patch-wideint/gcc/expr.c
+--- gcc-4.9.2-kugan-extelim-patch/gcc/expr.c	2014-11-12 06:59:50.555951666 -0600
++++ gcc-4.9.2-kugan-extelim-patch-wideint/gcc/expr.c	2014-11-12 09:15:55.581951625 -0600
+@@ -9242,7 +9242,7 @@
+ bool
+ promoted_for_signed_and_unsigned_p (tree ssa, enum machine_mode mode)
+ {
+-  wide_int min, max;
++  double_int min, max;
+ 
+   if (ssa == NULL_TREE
+       || TREE_CODE (ssa) != SSA_NAME
+@@ -9256,7 +9256,7 @@
+ 
+   /* Return true (to set SRP_SIGNED_AND_UNSIGNED to SUBREG) if MSB of the
+      smaller mode is not set (i.e.  MSB of ssa is not set).  */
+-  if (!wi::neg_p (min, SIGNED) && !wi::neg_p(max, SIGNED))
++  if (!min.is_negative () && !max.is_negative ())
+     return true;
+   else
+     return false;
+diff -Naur gcc-4.9.2/gcc/cfgexpand.c gcc-4.9.2-patch/gcc/cfgexpand.c
+--- gcc-4.9.2/gcc/cfgexpand.c	2014-11-19 11:04:17.743217000 -0600
++++ gcc-4.9.2-patch/gcc/cfgexpand.c	2014-11-19 12:58:35.510217000 -0600
+@@ -3279,6 +3279,7 @@
+ 
+ 		if ((SUBREG_PROMOTED_GET (target) == SRP_SIGNED_AND_UNSIGNED)
+ 		    && (GET_CODE (temp) == SUBREG)
++		    && SUBREG_PROMOTED_VAR_P (temp)
+ 		    && (GET_MODE (target) == GET_MODE (temp))
+ 		    && (GET_MODE (SUBREG_REG (target)) == GET_MODE (SUBREG_REG (temp))))
+ 		  emit_move_insn (SUBREG_REG (target), SUBREG_REG (temp));
+--- gcc-4.9.2/gcc/expr.c	2014-11-19 15:06:13.333217000 -0600
++++ gcc-4.9.2-patch/gcc/expr.c	2014-11-22 04:38:45.998447007 -0600
+@@ -7973,6 +7973,7 @@
+   int unsignedp = TYPE_UNSIGNED (type);
+   enum machine_mode mode = TYPE_MODE (type);
+   enum machine_mode orig_mode = mode;
++  bool promoted = false;
+ 
+   /* If we cannot do a conditional move on the mode, try doing it
+      with the promoted mode. */
+@@ -8019,6 +8020,12 @@
+       comparison_mode = TYPE_MODE (TREE_TYPE (treeop0));
+     }
+ 
++  if (GET_MODE (op1) == GET_MODE (op2)
++      && (GET_MODE_SIZE (mode) > GET_MODE_SIZE (orig_mode))
++      && SUBREG_PROMOTED_VAR_P (op1)
++      && SUBREG_PROMOTED_VAR_P (op2))
++    promoted = true;
++  
+   if (GET_MODE (op1) != mode)
+     op1 = gen_lowpart (mode, op1);
+ 
+@@ -8035,10 +8042,14 @@
+      and return.  */
+   if (insn)
+     {
++      rtx target;
+       rtx seq = get_insns ();
+       end_sequence ();
+       emit_insn (seq);
+-      return convert_modes (orig_mode, mode, temp, 0);
++      target = convert_modes (orig_mode, mode, temp, 0);
++      if (promoted)
++        SUBREG_PROMOTED_VAR_P (target) = 1;
++      return target;
+     }
+ 
+   /* Otherwise discard the sequence and fall back to code with
+diff -Naur gcc-4.8.3/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim.c gcc-4.8.3-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim.c
+--- gcc-4.8.3/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.8.3-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-extelim.c	2014-12-05 02:51:47.985670000 -0600
+@@ -0,0 +1,46 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-options "-O2 -std=c99" } */
++/* { dg-final { scan-assembler-times "rlwinm" 2 { target { ilp32 } } } } */
++/* { dg-final { scan-assembler-times "rldicl" 2 { target { lp64 } } } } */
++
++int hipBugTest_c1 ();
++
++int hipBugTest_c1 ()
++{
++  const int iN = 16;
++
++  signed char pcIn[iN];
++  unsigned char pucOut[iN];
++
++  for (int i = 0; i < iN; i++)
++  {
++    pcIn[i] = (signed char) (i - 11);
++    pucOut[i] = 0;
++  }
++
++  for (int i = 0; i < iN; i++)
++  {
++    const unsigned char ucGain = 3;
++    const unsigned char ucLimit = 100;
++
++    unsigned char ucIn;
++    unsigned char ucErr;
++    unsigned int uiVal;
++
++    if (pcIn[i] < 0)
++      ucIn = (unsigned char) ( pcIn[i] * -1);
++    else
++      ucIn = (unsigned char) pcIn[i];
++
++    uiVal = ucIn - 3;
++    uiVal = uiVal * (unsigned int) ucGain;
++
++    if (uiVal > ucLimit)
++      ucErr = ucLimit;
++    else
++      ucErr = (unsigned char)uiVal;
++
++    pucOut[i] = ucErr;
++  }
++  return pucOut[0];
++}
diff --git a/recipes-devtools/gcc/gcc-4.9/0006-uclibc-locale-wchar_fix.patch b/recipes-devtools/gcc/gcc-4.9/0006-uclibc-locale-wchar_fix.patch
new file mode 100644
index 0000000..3406859
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0006-uclibc-locale-wchar_fix.patch
@@ -0,0 +1,68 @@
+From 225511a3aeb193a916b3999f0b640a392caa67cd Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:45:57 +0400
+Subject: [PATCH 06/35] uclibc-locale-wchar_fix
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ libstdc++-v3/config/locale/uclibc/monetary_members.cc |    4 ++--
+ libstdc++-v3/config/locale/uclibc/numeric_members.cc  |   13 +++++++++++++
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/libstdc++-v3/config/locale/uclibc/monetary_members.cc b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+index 2e6f80a..31ebb9f 100644
+--- a/libstdc++-v3/config/locale/uclibc/monetary_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+@@ -401,7 +401,7 @@ namespace std
+ # ifdef __UCLIBC_HAS_XLOCALE__
+ 	  _M_data->_M_decimal_point = __cloc->decimal_point_wc;
+ 	  _M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
+-# else
++# elif defined __UCLIBC_HAS_LOCALE__
+ 	  _M_data->_M_decimal_point = __global_locale->decimal_point_wc;
+ 	  _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
+ # endif
+@@ -556,7 +556,7 @@ namespace std
+ # ifdef __UCLIBC_HAS_XLOCALE__
+ 	  _M_data->_M_decimal_point = __cloc->decimal_point_wc;
+ 	  _M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
+-# else
++# elif defined __UCLIBC_HAS_LOCALE__
+ 	  _M_data->_M_decimal_point = __global_locale->decimal_point_wc;
+ 	  _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
+ # endif
+diff --git a/libstdc++-v3/config/locale/uclibc/numeric_members.cc b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+index 2c70642..d5c8961 100644
+--- a/libstdc++-v3/config/locale/uclibc/numeric_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+@@ -127,12 +127,25 @@ namespace std
+ 	{
+ 	  // Named locale.
+ 	  // NB: In the GNU model wchar_t is always 32 bit wide.
++#ifdef __UCLIBC_MJN3_ONLY__
++#warning fix this... should be numeric
++#endif
++#ifdef __UCLIBC__
++# ifdef __UCLIBC_HAS_XLOCALE__
++	  _M_data->_M_decimal_point = __cloc->decimal_point_wc;
++	  _M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
++# elif defined __UCLIBC_HAS_LOCALE__
++	  _M_data->_M_decimal_point = __global_locale->decimal_point_wc;
++	  _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
++# endif
++#else
+ 	  union { char *__s; wchar_t __w; } __u;
+ 	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc);
+ 	  _M_data->_M_decimal_point = __u.__w;
+ 
+ 	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc);
+ 	  _M_data->_M_thousands_sep = __u.__w;
++#endif
+ 
+ 	  if (_M_data->_M_thousands_sep == L'\0')
+ 	    _M_data->_M_grouping = "";
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0006.gcc.opt-array-offset-49x.patch b/recipes-devtools/gcc/gcc-4.9/0006.gcc.opt-array-offset-49x.patch
new file mode 100644
index 0000000..5b55faa
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0006.gcc.opt-array-offset-49x.patch
@@ -0,0 +1,366 @@
+# Problem Statement:
+  Implements a GIMPLE pass to optimize array access by factoring
+  out expressions that calculate address offset from
+  multiple array access.
+
+  Optimization enabled with flag '-fopt-array-offset'.
+
+# Owned by:
+  Edmar Wienskoski
+
+diff -Naur gcc-4.9.1/gcc/common.opt gcc-4.9.1-opt-array-offset/gcc/common.opt
+--- gcc-4.9.1/gcc/common.opt	2014-04-07 08:27:39.000000000 -0500
++++ gcc-4.9.1-opt-array-offset/gcc/common.opt	2014-09-13 07:22:56.153455179 -0500
+@@ -1591,6 +1591,10 @@
+ Common Report Var(flag_omit_frame_pointer) Optimization
+ When possible do not generate stack frames
+ 
++fopt-array-offset
++Common Report Var(flag_opt_array_offset)
++Expand array offset address calculations
++
+ fopt-info
+ Common Report Var(flag_opt_info) Optimization
+ Enable all optimization info dumps on stderr
+diff -Naur gcc-4.9.1/gcc/Makefile.in gcc-4.9.1-opt-array-offset/gcc/Makefile.in
+--- gcc-4.9.1/gcc/Makefile.in	2014-04-15 03:04:17.000000000 -0500
++++ gcc-4.9.1-opt-array-offset/gcc/Makefile.in	2014-09-13 07:22:56.155455135 -0500
+@@ -1316,6 +1316,7 @@
+ 	modulo-sched.o \
+ 	omega.o \
+ 	omp-low.o \
++	opt-array-offset.o \
+ 	optabs.o \
+ 	options-save.o \
+ 	opts-global.o \
+diff -Naur gcc-4.9.1/gcc/opt-array-offset.c gcc-4.9.1-opt-array-offset/gcc/opt-array-offset.c
+--- gcc-4.9.1/gcc/opt-array-offset.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-opt-array-offset/gcc/opt-array-offset.c	2014-09-13 08:07:07.031454886 -0500
+@@ -0,0 +1,305 @@
++/* Optimizing array element access
++   Copyright (C) 2011
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC 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, or (at your option) any
++later version.
++
++GCC 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 GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++
++/* This is a GIMPLE pass over basic block which coverts the stmts:
++        
++        a = b +/- c1;
++	c = a * c2;
++        
++   to:
++   
++        a = b * c2;
++        c = a +/- c1 * c2;
++
++   in effect expanding the multiplication across addition/substraction.
++
++   Motivating example:
++   Consider the following simple integer array access:
++   
++        a[i] = c;
++        a[i + 1] = c;
++
++   The following GIMPLE equivalent will be generated:
++
++        off_1 = i * 4;
++        a_i = a + off_1;
++	*a_i = c;
++
++	off_1 = i + 1;
++	off_2 = off_1 * 4;
++	a_i1 = a + off_2;
++	*a_i1 = c;
++
++   Notice that a_i1 could simply be a_i + 4. But the calcuation of i+1
++   is preventing CSE to perform. This pass will essentially convert the
++   second expr into:
++
++        off_1 = i * 4;
++        off_2 = off_1 + 4;
++        a_i1 = a + off_2;
++        ....
++
++   Thus allowing the previous index i calculation to be reuse. off_1 + 4
++   would also be combined into a_i if offset addressing mode is available.
++   This also have side effect of avoiding redundant sign extension on
++   i+1 for LP64 model where native integer size is different from pointer size.
++
++   The algorithm iterates through all the basic blocks looking for
++   the above pattern. Care is taken to make sure off_1 only
++   has the single use otherwise the transformation cannot be perform.
++*/
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++
++#include "tree.h"
++#include "gimple-pretty-print.h"
++#include "basic-block.h"
++#include "tree-ssa-alias.h"
++#include "internal-fn.h"
++#include "gimple-expr.h"
++#include "is-a.h"
++#include "gimple.h"
++#include "gimple-iterator.h"
++#include "gimple-ssa.h"
++#include "tree-phinodes.h"
++#include "ssa-iterators.h"
++#include "tree-pass.h"
++#include "flags.h"
++
++#include "alloc-pool.h"
++#include "target.h"
++#include "tree-pretty-print.h"
++
++/*
++  We are looking for:
++  a = b +/- c1
++  c = a * c2 (stmt incoming)
++  d = &arr + c
++*/
++static bool
++is_candidate (gimple stmt)
++{
++  tree mul_result = gimple_get_lhs (stmt);
++  tree rhs1, rhs2;
++  gimple rhs1_stmt, use_stmt;
++  use_operand_p use_p;
++  imm_use_iterator imm_iter;
++
++  /* check for a * c2 */
++  if (gimple_assign_rhs_code (stmt) != MULT_EXPR)
++    return false;
++
++  rhs1 = gimple_assign_rhs1 (stmt);
++  rhs2 = gimple_assign_rhs2 (stmt);
++
++  if (TREE_CODE (rhs2) != INTEGER_CST)
++    return false;
++  
++  /* check for b + c1 */
++  if (TREE_CODE (rhs1) == SSA_NAME)
++    {
++      rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
++      if (is_gimple_assign (rhs1_stmt))
++	{
++	  tree rhs1_2;
++	  tree plusminus_result;
++
++	  if (gimple_assign_rhs_code (rhs1_stmt) != PLUS_EXPR
++	      && gimple_assign_rhs_code (rhs1_stmt) != MINUS_EXPR)
++	    return false;
++
++	  rhs1_2 = gimple_assign_rhs2 (rhs1_stmt);
++	  if (TREE_CODE (rhs1_2) != INTEGER_CST)
++	    return false;
++
++	  /* make sure there are no other uses of a 
++	     e.g. if a is used as an indcution variable 
++	     we cannot modified it
++	  */
++	  plusminus_result = gimple_get_lhs (rhs1_stmt);
++	  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, plusminus_result)
++	    {
++	      use_stmt = USE_STMT (use_p);
++	      
++	      /* ignore PHI node */
++	      if (is_gimple_assign (use_stmt) &&
++		  (gimple_code (use_stmt) == GIMPLE_PHI))
++		continue;
++	      if (use_stmt != stmt)
++		return false;
++	    }
++
++#if 0
++	  if (gimple_bb(rhs1_stmt) != gimple_bb(stmt))
++	    return false;
++#endif
++        }
++      else
++	return false;
++    }
++  else
++    return false;
++
++  /* now look for uses of c that is a pointer use */
++  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
++    {
++      enum tree_code use_code;
++
++      use_stmt = USE_STMT (use_p);
++      
++      if (is_gimple_debug (use_stmt))
++	continue;
++      
++      if (gimple_bb (use_stmt) != gimple_bb (stmt))
++	return false;
++
++      if (!is_gimple_assign (use_stmt))
++	return false;
++
++      use_code = gimple_assign_rhs_code (use_stmt);
++      if (use_code != POINTER_PLUS_EXPR)
++	return false;
++    }
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "Found candidate:\n");
++      print_gimple_stmt (dump_file, rhs1_stmt, 0, TDF_SLIM);
++      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
++      print_gimple_stmt (dump_file, use_stmt, 0, TDF_SLIM);
++    }
++
++  return true;
++}
++
++/* Do the actual transformation:
++  a = b + c1 ==> a = b * c2
++  c = a * c2 ==> c = a + c1*c2
++*/
++static bool
++expand_plusminus_mult (gimple stmt)
++{
++  tree c1, c2, mul_result;
++  gimple rhs1_stmt;
++
++  /* get c2 */
++  c2 = gimple_assign_rhs2 (stmt);
++
++  /* get c1 */
++  rhs1_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
++  c1 = gimple_assign_rhs2 (rhs1_stmt);
++
++  /* form c1 * c2 */
++  mul_result = double_int_to_tree (TREE_TYPE(c2), 
++		      (tree_to_double_int (c1) * tree_to_double_int (c2)));
++
++  /* a = b + c1 ==> a = b * c2 */
++  gimple_assign_set_rhs2 (rhs1_stmt, c2);
++  gimple_assign_set_rhs_code (rhs1_stmt, MULT_EXPR);
++  update_stmt (rhs1_stmt);
++
++  /* c = a * c2 ==> c = a + c1*c2 */
++  gimple_assign_set_rhs2 (stmt, mul_result);
++  /* MINUS_EXPR has already been embedded into c1*c2 */
++  gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
++  update_stmt (stmt);
++
++  return true;
++}
++
++static bool
++gate_opt_array_offset (void)
++{
++  return flag_opt_array_offset && optimize;
++}
++
++static unsigned int
++execute_opt_array_offset ()
++{
++  basic_block bb;
++
++  FOR_EACH_BB_FN (bb, cfun)
++    {
++      gimple_stmt_iterator gsi;
++
++      for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next(&gsi))
++      {
++        gimple stmt = gsi_stmt (gsi);
++	//tree lhs,rhs1,rhs2,rhs3;
++        //enum tree_code code;
++	  
++        /* only interested in assign statement */
++        if (is_gimple_assign (stmt))
++        {
++	   /* find stmts calculating array offset */
++	  if (is_candidate (stmt))
++	    /* convert stmt */
++	    expand_plusminus_mult(stmt);
++	    
++        }
++      }
++    }
++
++  return 0;
++}
++
++namespace {
++
++const pass_data pass_data_opt_array_offset =
++{
++  GIMPLE_PASS,				/* type */
++  "opt_array_offset",			/* name */
++  OPTGROUP_NONE,			/* optinfo_flags */
++  true,					/* has_gate */
++  true,					/* has_execute */
++  TV_NONE,				/* tv_id */
++  PROP_ssa,				/* properties_required */
++  0,					/* properties_provided */
++  0,					/* properties_destroyed */
++  0,					/* todo_flags_start */
++  ( TODO_verify_ssa
++  | TODO_verify_stmts
++  | TODO_update_ssa ),                 /* todo_flags_finish */
++};
++
++class pass_opt_array_offset : public gimple_opt_pass
++{
++public:
++  pass_opt_array_offset (gcc::context *ctxt)
++    : gimple_opt_pass (pass_data_opt_array_offset, ctxt)
++  {}
++
++  /* opt_pass methods: */
++  bool gate () { return gate_opt_array_offset (); }
++  unsigned int execute () { return execute_opt_array_offset (); }
++
++}; // class pass_tracer
++
++} // anon namespace
++
++gimple_opt_pass *
++make_pass_opt_array_offset (gcc::context *ctxt)
++{
++  return new pass_opt_array_offset (ctxt);
++}
+diff -Naur gcc-4.9.1/gcc/passes.def gcc-4.9.1-opt-array-offset/gcc/passes.def
+--- gcc-4.9.1/gcc/passes.def	2014-01-17 11:50:10.000000000 -0600
++++ gcc-4.9.1-opt-array-offset/gcc/passes.def	2014-09-13 07:22:56.155455135 -0500
+@@ -250,6 +250,7 @@
+       NEXT_PASS (pass_phiopt);
+       NEXT_PASS (pass_fold_builtins);
+       NEXT_PASS (pass_optimize_widening_mul);
++      NEXT_PASS (pass_opt_array_offset);
+       NEXT_PASS (pass_tail_calls);
+       NEXT_PASS (pass_rename_ssa_copies);
+       /* FIXME: If DCE is not run before checking for uninitialized uses,
+diff -Naur gcc-4.9.1/gcc/tree-pass.h gcc-4.9.1-opt-array-offset/gcc/tree-pass.h
+--- gcc-4.9.1/gcc/tree-pass.h	2014-01-02 16:23:26.000000000 -0600
++++ gcc-4.9.1-opt-array-offset/gcc/tree-pass.h	2014-09-13 07:22:56.156455113 -0500
+@@ -415,6 +415,7 @@
+ extern gimple_opt_pass *make_pass_cse_sincos (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_optimize_bswap (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_optimize_widening_mul (gcc::context *ctxt);
++extern gimple_opt_pass *make_pass_opt_array_offset (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_warn_function_return (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_warn_function_noreturn (gcc::context *ctxt);
+ extern gimple_opt_pass *make_pass_cselim (gcc::context *ctxt);
diff --git a/recipes-devtools/gcc/gcc-4.9/0007-uclibc-locale-update.patch b/recipes-devtools/gcc/gcc-4.9/0007-uclibc-locale-update.patch
new file mode 100644
index 0000000..5851123
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0007-uclibc-locale-update.patch
@@ -0,0 +1,542 @@
+From 6ffe7c46f52d27864c3df3663e16ec9ddee71e8f Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:46:58 +0400
+Subject: [PATCH 07/35] uclibc-locale-update
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ .../config/locale/uclibc/c++locale_internal.h      |    3 +
+ libstdc++-v3/config/locale/uclibc/c_locale.cc      |   74 +++++++++-----------
+ libstdc++-v3/config/locale/uclibc/c_locale.h       |   42 ++++++-----
+ libstdc++-v3/config/locale/uclibc/ctype_members.cc |   51 ++++++++++----
+ .../config/locale/uclibc/messages_members.h        |   12 ++--
+ .../config/locale/uclibc/monetary_members.cc       |   34 +++++----
+ .../config/locale/uclibc/numeric_members.cc        |    5 ++
+ libstdc++-v3/config/locale/uclibc/time_members.cc  |   18 +++--
+ libstdc++-v3/config/locale/uclibc/time_members.h   |   17 +++--
+ 9 files changed, 158 insertions(+), 98 deletions(-)
+
+diff --git a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
+index e74fddf..971a6b4 100644
+--- a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
++++ b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
+@@ -31,6 +31,9 @@
+ 
+ #include <bits/c++config.h>
+ #include <clocale>
++#include <cstdlib>
++#include <cstring>
++#include <cstddef>
+ 
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning clean this up
+diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.cc b/libstdc++-v3/config/locale/uclibc/c_locale.cc
+index 21430d0..1b9d8e1 100644
+--- a/libstdc++-v3/config/locale/uclibc/c_locale.cc
++++ b/libstdc++-v3/config/locale/uclibc/c_locale.cc
+@@ -39,23 +39,20 @@
+ #include <langinfo.h>
+ #include <bits/c++locale_internal.h>
+ 
+-namespace std
+-{
++_GLIBCXX_BEGIN_NAMESPACE(std)
++
+   template<>
+     void
+     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
+ 		   const __c_locale& __cloc)
+     {
+-      if (!(__err & ios_base::failbit))
+-	{
+-	  char* __sanity;
+-	  errno = 0;
+-	  float __f = __strtof_l(__s, &__sanity, __cloc);
+-          if (__sanity != __s && errno != ERANGE)
+-	    __v = __f;
+-	  else
+-	    __err |= ios_base::failbit;
+-	}
++      char* __sanity;
++      errno = 0;
++      float __f = __strtof_l(__s, &__sanity, __cloc);
++      if (__sanity != __s && errno != ERANGE)
++	__v = __f;
++      else
++	__err |= ios_base::failbit;
+     }
+ 
+   template<>
+@@ -63,16 +60,13 @@ namespace std
+     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
+ 		   const __c_locale& __cloc)
+     {
+-      if (!(__err & ios_base::failbit))
+-	{
+-	  char* __sanity;
+-	  errno = 0;
+-	  double __d = __strtod_l(__s, &__sanity, __cloc);
+-          if (__sanity != __s && errno != ERANGE)
+-	    __v = __d;
+-	  else
+-	    __err |= ios_base::failbit;
+-	}
++      char* __sanity;
++      errno = 0;
++      double __d = __strtod_l(__s, &__sanity, __cloc);
++      if (__sanity != __s && errno != ERANGE)
++	__v = __d;
++      else
++	__err |= ios_base::failbit;
+     }
+ 
+   template<>
+@@ -80,16 +74,13 @@ namespace std
+     __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
+ 		   const __c_locale& __cloc)
+     {
+-      if (!(__err & ios_base::failbit))
+-	{
+-	  char* __sanity;
+-	  errno = 0;
+-	  long double __ld = __strtold_l(__s, &__sanity, __cloc);
+-          if (__sanity != __s && errno != ERANGE)
+-	    __v = __ld;
+-	  else
+-	    __err |= ios_base::failbit;
+-	}
++      char* __sanity;
++      errno = 0;
++      long double __ld = __strtold_l(__s, &__sanity, __cloc);
++      if (__sanity != __s && errno != ERANGE)
++	__v = __ld;
++      else
++	__err |= ios_base::failbit;
+     }
+ 
+   void
+@@ -110,17 +101,18 @@ namespace std
+   void
+   locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
+   {
+-    if (_S_get_c_locale() != __cloc)
++    if (__cloc && _S_get_c_locale() != __cloc)
+       __freelocale(__cloc);
+   }
+ 
+   __c_locale
+   locale::facet::_S_clone_c_locale(__c_locale& __cloc)
+   { return __duplocale(__cloc); }
+-} // namespace std
+ 
+-namespace __gnu_cxx
+-{
++_GLIBCXX_END_NAMESPACE
++
++_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
++
+   const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
+     {
+       "LC_CTYPE",
+@@ -138,9 +130,11 @@ namespace __gnu_cxx
+       "LC_IDENTIFICATION"
+ #endif
+     };
+-}
+ 
+-namespace std
+-{
++_GLIBCXX_END_NAMESPACE
++
++_GLIBCXX_BEGIN_NAMESPACE(std)
++
+   const char* const* const locale::_S_categories = __gnu_cxx::category_names;
+-}  // namespace std
++
++_GLIBCXX_END_NAMESPACE
+diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.h b/libstdc++-v3/config/locale/uclibc/c_locale.h
+index 4bca5f1..64a6d46 100644
+--- a/libstdc++-v3/config/locale/uclibc/c_locale.h
++++ b/libstdc++-v3/config/locale/uclibc/c_locale.h
+@@ -39,21 +39,23 @@
+ #pragma GCC system_header
+ 
+ #include <cstring>              // get std::strlen
+-#include <cstdio>               // get std::snprintf or std::sprintf
++#include <cstdio>               // get std::vsnprintf or std::vsprintf
+ #include <clocale>
+ #include <langinfo.h>		// For codecvt
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning fix this
+ #endif
+-#ifdef __UCLIBC_HAS_LOCALE__
++#ifdef _GLIBCXX_USE_ICONV
+ #include <iconv.h>		// For codecvt using iconv, iconv_t
+ #endif
+-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
+-#include <libintl.h> 		// For messages
++#ifdef HAVE_LIBINTL_H
++#include <libintl.h>		// For messages
+ #endif
++#include <cstdarg>
+ 
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning what is _GLIBCXX_C_LOCALE_GNU for
++// psm: used in os/gnu-linux/ctype_noninline.h
+ #endif
+ #define _GLIBCXX_C_LOCALE_GNU 1
+ 
+@@ -78,23 +80,25 @@ namespace std
+ #else
+   typedef int*			__c_locale;
+ #endif
+-
+-  // Convert numeric value of type _Tv to string and return length of
+-  // string.  If snprintf is available use it, otherwise fall back to
+-  // the unsafe sprintf which, in general, can be dangerous and should
++  // Convert numeric value of type double to string and return length of
++  // string.  If vsnprintf is available use it, otherwise fall back to
++  // the unsafe vsprintf which, in general, can be dangerous and should
+   // be avoided.
+-  template<typename _Tv>
+-    int
+-    __convert_from_v(char* __out,
+-		     const int __size __attribute__ ((__unused__)),
+-		     const char* __fmt,
+-#ifdef __UCLIBC_HAS_XCLOCALE__
+-		     _Tv __v, const __c_locale& __cloc, int __prec)
++    inline int
++    __convert_from_v(const __c_locale&
++#ifndef __UCLIBC_HAS_XCLOCALE__
++	__cloc __attribute__ ((__unused__))
++#endif
++		     ,
++		     char* __out,
++		     const int __size,
++		     const char* __fmt, ...)
+     {
++      va_list __args;
++#ifdef __UCLIBC_HAS_XCLOCALE__
++
+       __c_locale __old = __gnu_cxx::__uselocale(__cloc);
+ #else
+-		     _Tv __v, const __c_locale&, int __prec)
+-    {
+ # ifdef __UCLIBC_HAS_LOCALE__
+       char* __old = std::setlocale(LC_ALL, NULL);
+       char* __sav = new char[std::strlen(__old) + 1];
+@@ -103,7 +107,9 @@ namespace std
+ # endif
+ #endif
+ 
+-      const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
++      va_start(__args, __fmt);
++      const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
++      va_end(__args);
+ 
+ #ifdef __UCLIBC_HAS_XCLOCALE__
+       __gnu_cxx::__uselocale(__old);
+diff --git a/libstdc++-v3/config/locale/uclibc/ctype_members.cc b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
+index 7b12861..13e011d 100644
+--- a/libstdc++-v3/config/locale/uclibc/ctype_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
+@@ -33,16 +33,20 @@
+ 
+ // Written by Benjamin Kosnik <bkoz@redhat.com>
+ 
++#include <features.h>
++#ifdef __UCLIBC_HAS_LOCALE__
+ #define _LIBC
+ #include <locale>
+ #undef _LIBC
++#else
++#include <locale>
++#endif
+ #include <bits/c++locale_internal.h>
+ 
+-namespace std
+-{
++_GLIBCXX_BEGIN_NAMESPACE(std)
++
+   // NB: The other ctype<char> specializations are in src/locale.cc and
+   // various /config/os/* files.
+-  template<>
+     ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
+     : ctype<char>(0, false, __refs)
+     {
+@@ -57,6 +61,8 @@ namespace std
+ #endif
+ 	}
+     }
++    ctype_byname<char>::~ctype_byname()
++    { }
+ 
+ #ifdef _GLIBCXX_USE_WCHAR_T
+   ctype<wchar_t>::__wmask_type
+@@ -138,17 +144,33 @@ namespace std
+   ctype<wchar_t>::
+   do_is(mask __m, wchar_t __c) const
+   {
+-    // Highest bitmask in ctype_base == 10, but extra in "C"
+-    // library for blank.
++    // The case of __m == ctype_base::space is particularly important,
++    // due to its use in many istream functions.  Therefore we deal with
++    // it first, exploiting the knowledge that on GNU systems _M_bit[5]
++    // is the mask corresponding to ctype_base::space.  NB: an encoding
++    // change would not affect correctness!
++
+     bool __ret = false;
+-    const size_t __bitmasksize = 11;
+-    for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
+-      if (__m & _M_bit[__bitcur]
+-	  && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
+-	{
+-	  __ret = true;
+-	  break;
+-	}
++    if (__m == _M_bit[5])
++      __ret = __iswctype_l(__c, _M_wmask[5], _M_c_locale_ctype);
++    else
++      {
++	// Highest bitmask in ctype_base == 10, but extra in "C"
++	// library for blank.
++	const size_t __bitmasksize = 11;
++	for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
++	  if (__m & _M_bit[__bitcur])
++	    {
++	      if (__iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
++		{
++		  __ret = true;
++		  break;
++		}
++	      else if (__m == _M_bit[__bitcur])
++		break;
++	    }
++      }
++
+     return __ret;
+   }
+ 
+@@ -290,4 +312,5 @@ namespace std
+ #endif
+   }
+ #endif //  _GLIBCXX_USE_WCHAR_T
+-}
++
++_GLIBCXX_END_NAMESPACE
+diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.h b/libstdc++-v3/config/locale/uclibc/messages_members.h
+index d89da33..067657a 100644
+--- a/libstdc++-v3/config/locale/uclibc/messages_members.h
++++ b/libstdc++-v3/config/locale/uclibc/messages_members.h
+@@ -53,12 +53,16 @@
+   template<typename _CharT>
+      messages<_CharT>::messages(__c_locale __cloc, const char* __s,
+ 				size_t __refs)
+-     : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)),
+-     _M_name_messages(__s)
++     : facet(__refs), _M_c_locale_messages(NULL),
++     _M_name_messages(NULL)
+      {
+-       char* __tmp = new char[std::strlen(__s) + 1];
+-       std::strcpy(__tmp, __s);
++       const size_t __len = std::strlen(__s) + 1;
++       char* __tmp = new char[__len];
++       std::memcpy(__tmp, __s, __len);
+        _M_name_messages = __tmp;
++
++       // Last to avoid leaking memory if new throws.
++       _M_c_locale_messages = _S_clone_c_locale(__cloc);
+      }
+ 
+   template<typename _CharT>
+diff --git a/libstdc++-v3/config/locale/uclibc/monetary_members.cc b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+index 31ebb9f..7679b9c 100644
+--- a/libstdc++-v3/config/locale/uclibc/monetary_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
+@@ -33,9 +33,14 @@
+ 
+ // Written by Benjamin Kosnik <bkoz@redhat.com>
+ 
++#include <features.h>
++#ifdef __UCLIBC_HAS_LOCALE__
+ #define _LIBC
+ #include <locale>
+ #undef _LIBC
++#else
++#include <locale>
++#endif
+ #include <bits/c++locale_internal.h>
+ 
+ #ifdef __UCLIBC_MJN3_ONLY__
+@@ -206,7 +211,7 @@ namespace std
+ 	  }
+ 	break;
+       default:
+-	;
++	__ret = pattern();
+       }
+     return __ret;
+   }
+@@ -390,7 +395,9 @@ namespace std
+ 	  __c_locale __old = __uselocale(__cloc);
+ #else
+ 	  // Switch to named locale so that mbsrtowcs will work.
+-	  char* __old = strdup(setlocale(LC_ALL, NULL));
++  	  char* __old = setlocale(LC_ALL, NULL);
++          const size_t __llen = strlen(__old) + 1;
++          char* __sav = new char[__llen];
+ 	  setlocale(LC_ALL, __name);
+ #endif
+ 
+@@ -477,8 +484,8 @@ namespace std
+ #ifdef __UCLIBC_HAS_XLOCALE__
+ 	      __uselocale(__old);
+ #else
+-	      setlocale(LC_ALL, __old);
+-	      free(__old);
++	      setlocale(LC_ALL, __sav);
++	      delete [] __sav;
+ #endif
+ 	      __throw_exception_again;
+ 	    }
+@@ -498,8 +505,8 @@ namespace std
+ #ifdef __UCLIBC_HAS_XLOCALE__
+ 	  __uselocale(__old);
+ #else
+-	  setlocale(LC_ALL, __old);
+-	  free(__old);
++	  setlocale(LC_ALL, __sav);
++	  delete [] __sav;
+ #endif
+ 	}
+     }
+@@ -545,8 +552,11 @@ namespace std
+ 	  __c_locale __old = __uselocale(__cloc);
+ #else
+ 	  // Switch to named locale so that mbsrtowcs will work.
+-	  char* __old = strdup(setlocale(LC_ALL, NULL));
+-	  setlocale(LC_ALL, __name);
++          char* __old = setlocale(LC_ALL, NULL);
++          const size_t __llen = strlen(__old) + 1;
++          char* __sav = new char[__llen];
++          memcpy(__sav, __old, __llen);
++          setlocale(LC_ALL, __name);
+ #endif
+ 
+ #ifdef __UCLIBC_MJN3_ONLY__
+@@ -633,8 +643,8 @@ namespace std
+ #ifdef __UCLIBC_HAS_XLOCALE__
+ 	      __uselocale(__old);
+ #else
+-	      setlocale(LC_ALL, __old);
+-	      free(__old);
++	      setlocale(LC_ALL, __sav);
++	      delete [] __sav;
+ #endif
+               __throw_exception_again;
+ 	    }
+@@ -653,8 +663,8 @@ namespace std
+ #ifdef __UCLIBC_HAS_XLOCALE__
+ 	  __uselocale(__old);
+ #else
+-	  setlocale(LC_ALL, __old);
+-	  free(__old);
++	  setlocale(LC_ALL, __sav);
++	  delete [] __sav;
+ #endif
+ 	}
+     }
+diff --git a/libstdc++-v3/config/locale/uclibc/numeric_members.cc b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+index d5c8961..8ae8969 100644
+--- a/libstdc++-v3/config/locale/uclibc/numeric_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
+@@ -33,9 +33,14 @@
+ 
+ // Written by Benjamin Kosnik <bkoz@redhat.com>
+ 
++#include <features.h>
++#ifdef __UCLIBC_HAS_LOCALE__
+ #define _LIBC
+ #include <locale>
+ #undef _LIBC
++#else
++#include <locale>
++#endif
+ #include <bits/c++locale_internal.h>
+ 
+ #ifdef __UCLIBC_MJN3_ONLY__
+diff --git a/libstdc++-v3/config/locale/uclibc/time_members.cc b/libstdc++-v3/config/locale/uclibc/time_members.cc
+index d848ed5..f24d53e 100644
+--- a/libstdc++-v3/config/locale/uclibc/time_members.cc
++++ b/libstdc++-v3/config/locale/uclibc/time_members.cc
+@@ -53,11 +53,14 @@ namespace std
+       const size_t __len = __strftime_l(__s, __maxlen, __format, __tm,
+ 					_M_c_locale_timepunct);
+ #else
+-      char* __old = strdup(setlocale(LC_ALL, NULL));
++      char* __old = setlocale(LC_ALL, NULL);
++      const size_t __llen = strlen(__old) + 1;
++      char* __sav = new char[__llen];
++      memcpy(__sav, __old, __llen);
+       setlocale(LC_ALL, _M_name_timepunct);
+       const size_t __len = strftime(__s, __maxlen, __format, __tm);
+-      setlocale(LC_ALL, __old);
+-      free(__old);
++      setlocale(LC_ALL, __sav);
++      delete [] __sav;
+ #endif
+       // Make sure __s is null terminated.
+       if (__len == 0)
+@@ -207,11 +210,14 @@ namespace std
+       const size_t __len = __wcsftime_l(__s, __maxlen, __format, __tm,
+ 					_M_c_locale_timepunct);
+ #else
+-      char* __old = strdup(setlocale(LC_ALL, NULL));
++      char* __old = setlocale(LC_ALL, NULL);
++      const size_t __llen = strlen(__old) + 1;
++      char* __sav = new char[__llen];
++      memcpy(__sav, __old, __llen);
+       setlocale(LC_ALL, _M_name_timepunct);
+       const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
+-      setlocale(LC_ALL, __old);
+-      free(__old);
++      setlocale(LC_ALL, __sav);
++      delete [] __sav;
+ #endif
+       // Make sure __s is null terminated.
+       if (__len == 0)
+diff --git a/libstdc++-v3/config/locale/uclibc/time_members.h b/libstdc++-v3/config/locale/uclibc/time_members.h
+index ba8e858..1665dde 100644
+--- a/libstdc++-v3/config/locale/uclibc/time_members.h
++++ b/libstdc++-v3/config/locale/uclibc/time_members.h
+@@ -50,12 +50,21 @@
+     __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
+ 				     size_t __refs)
+     : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
+-    _M_name_timepunct(__s)
++    _M_name_timepunct(NULL)
+     {
+-      char* __tmp = new char[std::strlen(__s) + 1];
+-      std::strcpy(__tmp, __s);
++      const size_t __len = std::strlen(__s) + 1;
++      char* __tmp = new char[__len];
++      std::memcpy(__tmp, __s, __len);
+       _M_name_timepunct = __tmp;
+-      _M_initialize_timepunct(__cloc);
++
++      try
++	{ _M_initialize_timepunct(__cloc); }
++      catch(...)
++	{
++	  delete [] _M_name_timepunct;
++	  __throw_exception_again;
++	}
++
+     }
+ 
+   template<typename _CharT>
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0007.gcc.aeabi-49x.patch b/recipes-devtools/gcc/gcc-4.9/0007.gcc.aeabi-49x.patch
new file mode 100644
index 0000000..c146493
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0007.gcc.aeabi-49x.patch
@@ -0,0 +1,440 @@
+diff -Naur gcc-4.9.0/config.sub gcc-4.9.0-aeabi/config.sub
+--- gcc-4.9.0/config.sub	2013-10-01 11:50:56.000000000 -0500
++++ gcc-4.9.0-aeabi/config.sub	2014-06-13 01:58:12.718371980 -0500
+@@ -1364,7 +1364,7 @@
+ 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
++	      | -udi* | -eabi* | -aeabi* | -lites* | -ieee* | -go32* | -aux* \
+ 	      | -chorusos* | -chorusrdb* | -cegcc* \
+ 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ 	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+diff -Naur gcc-4.9.0/gcc/config/rs6000/e500mc.h gcc-4.9.0-aeabi/gcc/config/rs6000/e500mc.h
+--- gcc-4.9.0/gcc/config/rs6000/e500mc.h	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.0-aeabi/gcc/config/rs6000/e500mc.h	2014-06-13 01:58:12.696372480 -0500
+@@ -0,0 +1,342 @@
++/* Core target definitions for GNU compiler
++   for IBM RS/6000 PowerPC targeted to embedded ELF systems.
++   Copyright (C) 1995, 1996, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
++   Contributed by Cygnus Support.
++
++   This file is part of GCC.
++
++   GCC 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, or (at your
++   option) any later version.
++
++   GCC 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 GCC; see the file COPYING3.  If not see
++   <http://www.gnu.org/licenses/>.  */
++
++/* Add -meabi to target flags.  */
++#undef TARGET_DEFAULT
++#define TARGET_DEFAULT 0
++
++#ifdef RS6000_BI_ARCH
++#define DEFAULT_ARCH64_P (TARGET_DEFAULT & OPTION_MASK_64BIT)
++#define RS6000BI_ARCH_P 1
++#endif
++
++#ifdef IN_LIBGCC2
++#undef TARGET_64BIT
++#ifdef __powerpc64__
++#define TARGET_64BIT 1
++#else
++#define TARGET_64BIT 0
++#endif
++#endif
++
++
++
++
++#undef	ASM_DEFAULT_SPEC
++#undef	ASM_SPEC
++#undef	LINK_OS_LINUX_SPEC
++
++#ifndef	RS6000_BI_ARCH
++#define	ASM_DEFAULT_SPEC "-mppc%{m64:64}"
++#define	ASM_SPEC	 "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
++#define	LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}"
++#else
++#if DEFAULT_ARCH64_P
++#define	ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
++#define	ASM_SPEC	 "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
++#define	LINK_OS_LINUX_SPEC "%{m32:%(link_os_linux_spec32)}%{!m32:%(link_os_linux_spec64)}"
++#else
++#define	ASM_DEFAULT_SPEC "-mppc%{m64:64}"
++#define	ASM_SPEC	 "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
++#define	LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}"
++#endif
++#endif
++
++#define ASM_SPEC32 "-a32 %{n} %{T} %{Ym,*} %{Yd,*} \
++%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
++%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
++%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
++    %{mcall-freebsd: -mbig} \
++    %{mcall-i960-old: -mlittle} \
++    %{mcall-linux: -mbig} \
++    %{mcall-gnu: -mbig} \
++    %{mcall-netbsd: -mbig} \
++}}}}"
++
++#define ASM_SPEC64 "-a64"
++
++#define ASM_SPEC_COMMON "%(asm_cpu) \
++%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \
++%{v:-V} %{Qy:} %{!Qn:-Qy} %{Wa,*:%*} \
++%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
++
++#undef	SUBSUBTARGET_EXTRA_SPECS
++#define SUBSUBTARGET_EXTRA_SPECS \
++  { "asm_spec_common",		ASM_SPEC_COMMON },			\
++  { "asm_spec32",		ASM_SPEC32 },				\
++  { "asm_spec64",		ASM_SPEC64 },				\
++
++#undef	MULTILIB_DEFAULTS
++#if DEFAULT_ARCH64_P
++#define MULTILIB_DEFAULTS { "m64" }
++#else
++#define MULTILIB_DEFAULTS { "m32" }
++#endif
++
++#define POWERPC_LINUX
++
++/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
++#undef  ADJUST_FIELD_ALIGN
++#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
++  ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)	\
++   ? 128								\
++   : (TARGET_64BIT							\
++      && TARGET_ALIGN_NATURAL == 0					\
++      && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)	\
++   ? MIN ((COMPUTED), 32)						\
++   : (COMPUTED))
++
++/* PowerPC64 Linux increases natural record alignment to doubleword if
++   the first field is an FP double, only if in power alignment mode.  */
++#undef  ROUND_TYPE_ALIGN
++#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)			\
++  ((TARGET_64BIT							\
++    && (TREE_CODE (STRUCT) == RECORD_TYPE				\
++	|| TREE_CODE (STRUCT) == UNION_TYPE				\
++	|| TREE_CODE (STRUCT) == QUAL_UNION_TYPE)			\
++    && TARGET_ALIGN_NATURAL == 0)					\
++   ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED)	\
++   : MAX ((COMPUTED), (SPECIFIED)))
++
++/* Use the default for compiling target libs.  */
++#ifdef IN_TARGET_LIBS
++#undef TARGET_ALIGN_NATURAL
++#define TARGET_ALIGN_NATURAL 1
++#endif
++
++/* Indicate that jump tables go in the text section.  */
++#undef  JUMP_TABLES_IN_TEXT_SECTION
++#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
++
++/* The linux ppc64 ABI isn't explicit on whether aggregates smaller
++   than a doubleword should be padded upward or downward.  You could
++   reasonably assume that they follow the normal rules for structure
++   layout treating the parameter area as any other block of memory,
++   then map the reg param area to registers.  i.e. pad upward.
++   Setting both of the following defines results in this behavior.
++   Setting just the first one will result in aggregates that fit in a
++   doubleword being padded downward, and others being padded upward.
++   Not a bad idea as this results in struct { int x; } being passed
++   the same way as an int.  */
++#define AGGREGATE_PADDING_FIXED TARGET_64BIT
++#define AGGREGATES_PAD_UPWARD_ALWAYS 0
++
++/* Specify padding for the last element of a block move between
++   registers and memory.  FIRST is nonzero if this is the only
++   element.  */
++#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
++  (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
++
++#undef  TARGET_OS_CPP_BUILTINS
++#define TARGET_OS_CPP_BUILTINS()			\
++  do							\
++    {							\
++      if (TARGET_64BIT)					\
++	{						\
++	  builtin_define ("__PPC__");			\
++	  builtin_define ("__PPC64__");			\
++	  builtin_define ("__powerpc__");		\
++	  builtin_define ("__powerpc64__");		\
++	  builtin_assert ("cpu=powerpc64");		\
++	  builtin_assert ("machine=powerpc64");		\
++	}						\
++      else						\
++	{						\
++	  builtin_define_std ("PPC");			\
++	  builtin_define ("__embedded__");		\
++	  builtin_assert ("system=embedded");		\
++	  builtin_assert ("cpu=powerpc");		\
++	  builtin_assert ("machine=powerpc");		\
++	  TARGET_OS_SYSV_CPP_BUILTINS ();		\
++	}						\
++    }							\
++  while (0)
++
++/* Must be at least as big as our pointer type.  */
++#undef	SIZE_TYPE
++#define	SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
++
++#undef	PTRDIFF_TYPE
++#define	PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
++
++#undef	WCHAR_TYPE
++#define	WCHAR_TYPE (TARGET_64BIT ? "int" : "long int")
++#undef  WCHAR_TYPE_SIZE
++#define WCHAR_TYPE_SIZE 32
++
++#ifdef __powerpc64__
++/* _init and _fini functions are built from bits spread across many
++   object files, each potentially with a different TOC pointer.  For
++   that reason, place a nop after the call so that the linker can
++   restore the TOC pointer if a TOC adjusting call stub is needed.  */
++#if DOT_SYMBOLS
++#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
++  asm (SECTION_OP "\n"					\
++"	bl ." #FUNC "\n"				\
++"	nop\n"						\
++"	.previous");
++#else
++#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
++  asm (SECTION_OP "\n"					\
++"	bl " #FUNC "\n"					\
++"	nop\n"						\
++"	.previous");
++#endif
++#endif
++
++/* FP save and restore routines.  */
++#undef  SAVE_FP_PREFIX
++#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
++#undef  SAVE_FP_SUFFIX
++#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
++#undef  RESTORE_FP_PREFIX
++#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
++#undef  RESTORE_FP_SUFFIX
++#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
++
++/* Dwarf2 debugging.  */
++#undef  PREFERRED_DEBUGGING_TYPE
++#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
++
++/* This is how to declare the size of a function.  */
++#undef	ASM_DECLARE_FUNCTION_SIZE
++#define	ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)			\
++  do									\
++    {									\
++      if (!flag_inhibit_size_directive)					\
++	{								\
++	  fputs ("\t.size\t", (FILE));					\
++	  if (TARGET_64BIT && DOT_SYMBOLS)				\
++	    putc ('.', (FILE));						\
++	  assemble_name ((FILE), (FNAME));				\
++	  fputs (",.-", (FILE));					\
++	  rs6000_output_function_entry (FILE, FNAME);			\
++	  putc ('\n', (FILE));						\
++	}								\
++    }									\
++  while (0)
++
++/* Return nonzero if this entry is to be written into the constant
++   pool in a special way.  We do so if this is a SYMBOL_REF, LABEL_REF
++   or a CONST containing one of them.  If -mfp-in-toc (the default),
++   we also do this for floating-point constants.  We actually can only
++   do this if the FP formats of the target and host machines are the
++   same, but we can't check that since not every file that uses
++   GO_IF_LEGITIMATE_ADDRESS_P includes real.h.  We also do this when
++   we can write the entry into the TOC and the entry is not larger
++   than a TOC entry.  */
++
++#undef  ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
++#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE)			\
++  (TARGET_TOC								\
++   && (GET_CODE (X) == SYMBOL_REF					\
++       || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS	\
++	   && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF)		\
++       || GET_CODE (X) == LABEL_REF					\
++       || (GET_CODE (X) == CONST_INT 					\
++	   && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode))	\
++       || (GET_CODE (X) == CONST_DOUBLE					\
++	   && ((TARGET_64BIT						\
++		&& (TARGET_MINIMAL_TOC					\
++		    || (SCALAR_FLOAT_MODE_P (GET_MODE (X))		\
++			&& ! TARGET_NO_FP_IN_TOC)))			\
++	       || (!TARGET_64BIT					\
++		   && !TARGET_NO_FP_IN_TOC				\
++		   && !TARGET_RELOCATABLE				\
++		   && SCALAR_FLOAT_MODE_P (GET_MODE (X))		\
++		   && BITS_PER_WORD == HOST_BITS_PER_INT)))))
++
++/* Select a format to encode pointers in exception handling data.  CODE
++   is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
++   true if the symbol may be affected by dynamic relocations.  */
++#undef	ASM_PREFERRED_EH_DATA_FORMAT
++#define	ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
++  ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE)			\
++   ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel		\
++      | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4))		\
++   : DW_EH_PE_absptr)
++
++/* For backward compatibility, we must continue to use the AIX
++   structure return convention.  */
++#undef DRAFT_V4_STRUCT_RET
++#define DRAFT_V4_STRUCT_RET 0
++
++#define TARGET_ASM_FILE_END rs6000_elf_file_end
++
++#define LINK_GCC_C_SEQUENCE_SPEC \
++  "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
++
++/* Use --as-needed -lgcc_s for eh support.  */
++#ifdef HAVE_LD_AS_NEEDED
++#define USE_LD_AS_NEEDED 1
++#endif
++
++#undef	TARGET_AIX
++#define	TARGET_AIX TARGET_64BIT
++
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC "-maix-struct-return"
++
++#undef RS6000_ABI_NAME
++#define RS6000_ABI_NAME "linux"
++
++#define INVALID_64BIT "-m%s not supported in this configuration"
++#define INVALID_32BIT INVALID_64BIT
++
++#undef SUBSUBTARGET_OVERRIDE_OPTIONS
++#define SUBSUBTARGET_OVERRIDE_OPTIONS		\
++  do						\
++    {						\
++      if (!global_options_set.x_rs6000_alignment_flags)	\
++	rs6000_alignment_flags = MASK_ALIGN_NATURAL;		\
++      if (TARGET_64BIT)					\
++	{							\
++	  if (DEFAULT_ABI != ABI_AIX)				\
++	    {							\
++	      rs6000_current_abi = ABI_AIX;			\
++	      error (INVALID_64BIT, "call");			\
++	    }							\
++	  dot_symbols = !strcmp (rs6000_abi_name, "aixdesc");	\
++	  if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE)	\
++	    {							\
++	      rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE;	\
++	      error (INVALID_64BIT, "relocatable");		\
++	    }							\
++	  if (rs6000_isa_flags & OPTION_MASK_EABI)		\
++	    {							\
++	      rs6000_isa_flags &= ~OPTION_MASK_EABI;		\
++	    }							\
++	  if (TARGET_PROTOTYPE)					\
++	    {							\
++	      TARGET_PROTOTYPE = 0;				\
++	      error (INVALID_64BIT, "prototype");		\
++	    }							\
++	  if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0)	\
++	    {							\
++	      rs6000_isa_flags |= OPTION_MASK_POWERPC64;	\
++	      error ("-m64 requires a PowerPC64 cpu");		\
++	    }							\
++	}							\
++    }						\
++  while (0)
++/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit
++   process.  */
++#define OS_MISSING_POWERPC64 !TARGET_64BIT
+diff -Naur gcc-4.9.0/gcc/config/rs6000/sysv4.h gcc-4.9.0-aeabi/gcc/config/rs6000/sysv4.h
+--- gcc-4.9.0/gcc/config/rs6000/sysv4.h	2014-02-10 08:46:24.000000000 -0600
++++ gcc-4.9.0-aeabi/gcc/config/rs6000/sysv4.h	2014-06-13 02:00:07.797371712 -0500
+@@ -538,6 +538,9 @@
+ #define CC1_SECURE_PLT_DEFAULT_SPEC ""
+ #endif
+ 
++#undef CC1_EXTRA_SPEC
++#define CC1_EXTRA_SPEC ""
++
+ /* Pass -G xxx to the compiler.  */
+ #define	CC1_SPEC "%{G*} %(cc1_cpu)" \
+ "%{meabi: %{!mcall-*: -mcall-sysv }} \
+@@ -551,7 +554,7 @@
+ %{msdata: -msdata=default} \
+ %{mno-sdata: -msdata=none} \
+ %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
+-%{profile: -p}"
++%{profile: -p}" CC1_EXTRA_SPEC
+ 
+ /* Default starting address if specified.  */
+ #define LINK_START_SPEC "\
+diff -Naur gcc-4.9.0/gcc/config/rs6000/t-ppc-e500mc gcc-4.9.0-aeabi/gcc/config/rs6000/t-ppc-e500mc
+--- gcc-4.9.0/gcc/config/rs6000/t-ppc-e500mc	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.0-aeabi/gcc/config/rs6000/t-ppc-e500mc	2014-06-13 01:58:12.696372480 -0500
+@@ -0,0 +1,15 @@
++# Multilibs for powerpc embedded ELF targets.
++
++MULTILIB_OPTIONS	= m32/m64
++
++MULTILIB_DIRNAMES	= 32 64
++
++MULTILIB_EXCEPTIONS	= 
++
++MULTILIB_EXTRA_OPTS	= mno-eabi mstrict-align
++
++MULTILIB_MATCHES	= ${MULTILIB_MATCHES_FLOAT} \
++			  ${MULTILIB_MATCHES_ENDIAN}
++
++softfp_wrap_start := '\#ifndef __powerpc64__'
++softfp_wrap_end := '\#endif'
+diff -Naur gcc-4.9.0/gcc/config.gcc gcc-4.9.0-aeabi/gcc/config.gcc
+--- gcc-4.9.0/gcc/config.gcc	2014-03-12 05:13:07.000000000 -0500
++++ gcc-4.9.0-aeabi/gcc/config.gcc	2014-06-13 01:58:12.697372447 -0500
+@@ -2239,6 +2239,23 @@
+ 	extra_options="${extra_options} rs6000/sysv4.opt"
+ 	tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+ 	;;
++powerpc-*-aeabi)
++	tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h"
++	extra_options="${extra_options} rs6000/sysv4.opt"
++	tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
++	case ${enable_targets}:${cpu_is_64bit} in
++	  *powerpc64* | all:* | *:yes)
++	  if test x$cpu_is_64bit = xyes; then
++	    tm_file="${tm_file} rs6000/default64.h"
++	  fi
++	  tm_file="rs6000/biarch64.h ${tm_file}"
++	  ;;
++	esac
++	if test x$enable_powerpc_e500mc_aeabi = xyes; then
++	  tm_file="${tm_file} rs6000/e500mc.h"
++	  tmake_file="${tmake_file} rs6000/t-ppc-e500mc"
++	fi
++	;;
+ powerpc-*-eabialtivec*)
+ 	tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabialtivec.h"
+ 	extra_options="${extra_options} rs6000/sysv4.opt"
+diff -Naur gcc-4.9.0/libgcc/config.host gcc-4.9.0-aeabi/libgcc/config.host
+--- gcc-4.9.0/libgcc/config.host	2014-03-27 10:40:31.000000000 -0500
++++ gcc-4.9.0-aeabi/libgcc/config.host	2014-06-13 01:58:12.718371981 -0500
+@@ -975,6 +975,10 @@
+ 	tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ 	extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
+ 	;;
++powerpc-*-aeabi*)
++ 	tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit rs6000/t-ldbl128 t-softfp"
++	extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
++	;;
+ powerpc-*-rtems*)
+ 	tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
+ 	extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
diff --git a/recipes-devtools/gcc/gcc-4.9/0008-missing-execinfo_h.patch b/recipes-devtools/gcc/gcc-4.9/0008-missing-execinfo_h.patch
new file mode 100644
index 0000000..2823809
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0008-missing-execinfo_h.patch
@@ -0,0 +1,28 @@
+From 9f2158451981cf0a80cfabdc79ae31bb6976a801 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:48:10 +0400
+Subject: [PATCH 08/35] missing-execinfo_h
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ boehm-gc/include/gc.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h
+index c51e017..a7ba8dc 100644
+--- a/boehm-gc/include/gc.h
++++ b/boehm-gc/include/gc.h
+@@ -503,7 +503,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb));
+ #if defined(__linux__) || defined(__GLIBC__)
+ # include <features.h>
+ # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
+-     && !defined(__ia64__)
++     && !defined(__ia64__) && !defined(__UCLIBC__)
+ #   ifndef GC_HAVE_BUILTIN_BACKTRACE
+ #     define GC_HAVE_BUILTIN_BACKTRACE
+ #   endif
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0008.gcc.fix_regalloc_for_482.patch b/recipes-devtools/gcc/gcc-4.9/0008.gcc.fix_regalloc_for_482.patch
new file mode 100644
index 0000000..e806d0b
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0008.gcc.fix_regalloc_for_482.patch
@@ -0,0 +1,23 @@
+Index: lra-assigns.c
+===================================================================
+--- src_gcc/gcc/lra-assigns.c	(revision 200944)
++++ src_gcc/gcc/lra-assigns.c	(working copy)
+@@ -194,15 +194,15 @@ reload_pseudo_compare_func (const void *
+   if ((diff = (ira_class_hard_regs_num[cl1]
+ 	       - ira_class_hard_regs_num[cl2])) != 0)
+     return diff;
+-  if ((diff = (regno_assign_info[regno_assign_info[r2].first].freq
+-	       - regno_assign_info[regno_assign_info[r1].first].freq)) != 0)
+-    return diff;
+   /* Allocate bigger pseudos first to avoid register file
+      fragmentation.  */
+   if ((diff
+        = (ira_reg_class_max_nregs[cl2][lra_reg_info[r2].biggest_mode]
+ 	  - ira_reg_class_max_nregs[cl1][lra_reg_info[r1].biggest_mode])) != 0)
+     return diff;
++  if ((diff = (regno_assign_info[regno_assign_info[r2].first].freq
++	       - regno_assign_info[regno_assign_info[r1].first].freq)) != 0)
++    return diff;
+   /* Put pseudos from the thread nearby.  */
+   if ((diff = regno_assign_info[r1].first - regno_assign_info[r2].first) != 0)
+     return diff;
diff --git a/recipes-devtools/gcc/gcc-4.9/0009-c99-snprintf.patch b/recipes-devtools/gcc/gcc-4.9/0009-c99-snprintf.patch
new file mode 100644
index 0000000..7168778
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0009-c99-snprintf.patch
@@ -0,0 +1,28 @@
+From e393e076f1ab82d25e1aa04d6edea27b41d3eb06 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:49:03 +0400
+Subject: [PATCH 09/35] c99-snprintf
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ libstdc++-v3/include/c_std/cstdio |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libstdc++-v3/include/c_std/cstdio b/libstdc++-v3/include/c_std/cstdio
+index e85bd83..6af839a 100644
+--- a/libstdc++-v3/include/c_std/cstdio
++++ b/libstdc++-v3/include/c_std/cstdio
+@@ -139,7 +139,7 @@ namespace std
+   using ::vsprintf;
+ } // namespace std
+ 
+-#if _GLIBCXX_USE_C99
++#if _GLIBCXX_USE_C99 || defined(__UCLIBC__)
+ 
+ #undef snprintf
+ #undef vfscanf
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0009.gcc.rm_slow_tests-47.patch b/recipes-devtools/gcc/gcc-4.9/0009.gcc.rm_slow_tests-47.patch
new file mode 100644
index 0000000..fa02d2d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0009.gcc.rm_slow_tests-47.patch
@@ -0,0 +1,67 @@
+diff -ruN gcc-20110708/gcc/testsuite/gfortran.dg/cray_pointers_8.f90 gcc-20110708-fixed/gcc/testsuite/gfortran.dg/cray_pointers_8.f90
+--- gcc-20110708/gcc/testsuite/gfortran.dg/cray_pointers_8.f90	2011-07-08 11:13:40.530334001 -0500
++++ gcc-20110708-fixed/gcc/testsuite/gfortran.dg/cray_pointers_8.f90	1969-12-31 18:00:00.000000000 -0600
+@@ -1,63 +0,0 @@
+-! { dg-do run }
+-! { dg-options "-fcray-pointer -ffloat-store" }
+-!
+-! Test the fix for PR36528 in which the Cray pointer was not passed
+-! correctly to 'euler' so that an undefined reference to fcn was
+-! generated by the linker.
+-!
+-! Reported by Tobias Burnus  <burnus@gcc.gnu.org>
+-! from http://groups.google.com/group/comp.lang.fortran/msg/86b65bad78e6af78
+-!
+-real function p1(x)
+-  real, intent(in) :: x
+-  p1 = x
+-end
+-
+-real function euler(xp,xk,dx,f)
+-  real, intent(in) :: xp, xk, dx
+-  interface
+-    real function f(x)
+-      real, intent(in) :: x
+-    end function
+-  end interface
+-  real x, y
+-  y = 0.0
+-  x = xp
+-  do while (x .le. xk)
+-    y = y + f(x)*dx
+-    x = x + dx
+-  end do
+-  euler = y
+-end
+-program main
+-  interface
+-    real function p1 (x)
+-      real, intent(in) :: x
+-    end function
+-    real function fcn (x)
+-      real, intent(in) :: x
+-    end function
+-    real function euler (xp,xk,dx,f)
+-      real, intent(in) :: xp, xk ,dx
+-      interface
+-        real function f(x)
+-          real, intent(in) :: x
+-        end function
+-      end interface
+-    end function
+-  end interface
+-  real x, xp, xk, dx, y, z
+-  pointer (pfcn, fcn)
+-  pfcn = loc(p1)
+-  xp = 0.0
+-  xk = 1.0
+-  dx = 0.0005
+-  y = 0.0
+-  x = xp
+-  do while (x .le. xk)
+-    y = y + fcn(x)*dx
+-    x = x + dx
+-  end do
+-  z = euler(0.0,1.0,0.0005,fcn)
+-  if (abs (y - z) .gt. 1e-6) call abort
+-end
diff --git a/recipes-devtools/gcc/gcc-4.9/0010-c99-complex-ugly-hack.patch b/recipes-devtools/gcc/gcc-4.9/0010-c99-complex-ugly-hack.patch
new file mode 100644
index 0000000..b628571
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0010-c99-complex-ugly-hack.patch
@@ -0,0 +1,29 @@
+From 73f69d806e2c9561a54995223431a1076cfd6164 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:49:57 +0400
+Subject: [PATCH 10/35] c99-complex-ugly-hack
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [embedded specific]
+---
+ libstdc++-v3/configure |    3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
+index c57a751..a1333e2 100755
+--- a/libstdc++-v3/configure
++++ b/libstdc++-v3/configure
+@@ -18734,6 +18734,9 @@ $as_echo_n "checking for ISO C99 support to TR1 in <complex.h>... " >&6; }
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ #include <complex.h>
++#ifdef __UCLIBC__
++#error ugly hack to make sure configure test fails here for cross until uClibc supports the complex funcs
++#endif
+ int
+ main ()
+ {
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0010.gcc.fix_mingw32.patch b/recipes-devtools/gcc/gcc-4.9/0010.gcc.fix_mingw32.patch
new file mode 100644
index 0000000..5354723
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0010.gcc.fix_mingw32.patch
@@ -0,0 +1,12 @@
+diff -Naur gcc-4.8.3/gcc/configure gcc-4.8.3-fix-mingw32/gcc/configure
+--- gcc-4.8.3/gcc/configure	2014-04-28 05:05:29.000000000 -0500
++++ gcc-4.8.3-fix-mingw32/gcc/configure	2014-07-21 01:17:32.114371914 -0500
+@@ -11209,7 +11209,7 @@
+ 	CXX="${CXX_FOR_BUILD}" CXXFLAGS="${CXXFLAGS_FOR_BUILD}" \
+ 	LD="${LD_FOR_BUILD}" LDFLAGS="${LDFLAGS_FOR_BUILD}" \
+ 	GMPINC="" CPPFLAGS="${CPPFLAGS} -DGENERATOR_FILE" \
+-	${realsrcdir}/configure \
++	${realsrcdir}/configure --with-gnu-ld --with-gnu-as --enable-targets=all \
+ 		--enable-languages=${enable_languages-all} \
+ 		--target=$target_alias --host=$build_alias --build=$build_alias
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0011-index_macro.patch b/recipes-devtools/gcc/gcc-4.9/0011-index_macro.patch
new file mode 100644
index 0000000..8ee79b0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0011-index_macro.patch
@@ -0,0 +1,44 @@
+From b037953e40312b45ab84ed0a3ad882bb5e413101 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:51:02 +0400
+Subject: [PATCH 11/35] index_macro
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ libstdc++-v3/include/ext/rope       |    3 +++
+ libstdc++-v3/include/ext/ropeimpl.h |    3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope
+index 38eb1e8..158d21a 100644
+--- a/libstdc++-v3/include/ext/rope
++++ b/libstdc++-v3/include/ext/rope
+@@ -55,6 +55,9 @@
+ #include <bits/gthr.h>
+ #include <tr1/functional>
+ 
++/* cope w/ index defined as macro, SuSv3 proposal */
++#undef index
++
+ # ifdef __GC
+ #   define __GC_CONST const
+ # else
+diff --git a/libstdc++-v3/include/ext/ropeimpl.h b/libstdc++-v3/include/ext/ropeimpl.h
+index d7b5cbd..b9b3acb 100644
+--- a/libstdc++-v3/include/ext/ropeimpl.h
++++ b/libstdc++-v3/include/ext/ropeimpl.h
+@@ -48,6 +48,9 @@
+ #include <ext/memory> // For uninitialized_copy_n
+ #include <ext/numeric> // For power
+ 
++/* cope w/ index defined as macro, SuSv3 proposal */
++#undef index
++
+ namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+ {
+ _GLIBCXX_BEGIN_NAMESPACE_VERSION
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0011.gcc.no_power_builtins-48.patch b/recipes-devtools/gcc/gcc-4.9/0011.gcc.no_power_builtins-48.patch
new file mode 100644
index 0000000..20e929f
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0011.gcc.no_power_builtins-48.patch
@@ -0,0 +1,24 @@
+--- gcc-4.7.1/gcc/config/rs6000/rs6000-c.c-orig	2012-07-12 15:10:29.165238074 -0500
++++ gcc-4.7.1/gcc/config/rs6000/rs6000-c.c	2012-07-12 15:12:18.928238388 -0500
+@@ -306,17 +306,17 @@
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCGR");
+   if ((flags & OPTION_MASK_POWERPC64) != 0)
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC64");
+-  if ((flags & OPTION_MASK_MFCRF) != 0)
++  if ((flags & OPTION_MASK_MFCRF) != 0 && rs6000_cpu != PROCESSOR_PPCE6500)
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR4");
+-  if ((flags & OPTION_MASK_POPCNTB) != 0)
++  if ((flags & OPTION_MASK_POPCNTB) != 0 && rs6000_cpu != PROCESSOR_PPCE5500 && rs6000_cpu != PROCESSOR_PPCE6500)
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5");
+   if ((flags & OPTION_MASK_FPRND) != 0)
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5X");
+-  if ((flags & OPTION_MASK_CMPB) != 0)
++  if ((flags & OPTION_MASK_CMPB) != 0 && rs6000_cpu != PROCESSOR_PPCE5500 && rs6000_cpu != PROCESSOR_PPCE6500)
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6");
+   if ((flags & OPTION_MASK_MFPGPR) != 0)
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6X");
+-  if ((flags & OPTION_MASK_POPCNTD) != 0)
++  if ((flags & OPTION_MASK_POPCNTD) != 0 && rs6000_cpu != PROCESSOR_PPCE5500 && rs6000_cpu != PROCESSOR_PPCE6500)
+     rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR7");
+   if ((flags & OPTION_MASK_SOFT_FLOAT) != 0)
+     rs6000_define_or_undefine_macro (define_p, "_SOFT_FLOAT");
diff --git a/recipes-devtools/gcc/gcc-4.9/0012.gcc.ld_unaligned-460.patch b/recipes-devtools/gcc/gcc-4.9/0012.gcc.ld_unaligned-460.patch
new file mode 100644
index 0000000..c5aff93
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0012.gcc.ld_unaligned-460.patch
@@ -0,0 +1,32 @@
+gcc.ld_unaligned-460
+
+Optimization:
+Allows a "ld" of an address that is world aligned. There is a penalty
+performance, but it still beats a pair of "lwz".
+
+Index: gcc-4.4-e500mc64-20090322/gcc/config/rs6000/rs6000.c
+===================================================================
+--- gcc-4.4-e500mc64-20090322/gcc/config/rs6000/rs6000.c	(revision 137727)
++++ gcc-4.4-e500mc64-20090322/gcc/config/rs6000/rs6000.c	(working copy)
+@@ -10640,7 +10667,9 @@
+       else if (bytes >= 8 && TARGET_POWERPC64
+ 	       /* 64-bit loads and stores require word-aligned
+ 		  displacements.  */
+-	       && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
++	       && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)
++		   || rs6000_cpu == PROCESSOR_PPCE5500
++		   || rs6000_cpu == PROCESSOR_PPCE6500))
+ 	{
+ 	  clear_bytes = 8;
+ 	  mode = DImode;
+@@ -10775,7 +10808,9 @@
+       else if (bytes >= 8 && TARGET_POWERPC64
+ 	       /* 64-bit loads and stores require word-aligned
+ 		  displacements.  */
+-	       && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
++	       && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)
++		   || rs6000_cpu == PROCESSOR_PPCE5500
++		   || rs6000_cpu == PROCESSOR_PPCE6500))
+ 	{
+ 	  move_bytes = 8;
+ 	  mode = DImode;
diff --git a/recipes-devtools/gcc/gcc-4.9/0013-libstdc-namespace.patch b/recipes-devtools/gcc/gcc-4.9/0013-libstdc-namespace.patch
new file mode 100644
index 0000000..4a3efde
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0013-libstdc-namespace.patch
@@ -0,0 +1,54 @@
+From 104e4d66208f2726b14d2f5eebce90700cbc83c8 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:54:02 +0400
+Subject: [PATCH 13/35] libstdc++-namespace
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ libstdc++-v3/config/locale/uclibc/messages_members.h |    4 +++-
+ libstdc++-v3/config/locale/uclibc/time_members.h     |    4 +++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.h b/libstdc++-v3/config/locale/uclibc/messages_members.h
+index 067657a..dd76a6c 100644
+--- a/libstdc++-v3/config/locale/uclibc/messages_members.h
++++ b/libstdc++-v3/config/locale/uclibc/messages_members.h
+@@ -32,7 +32,8 @@
+ //
+ 
+ // Written by Benjamin Kosnik <bkoz@redhat.com>
+-
++namespace std
++{
+ #ifdef __UCLIBC_MJN3_ONLY__
+ #warning fix prototypes for *textdomain funcs
+ #endif
+@@ -116,3 +117,4 @@
+ 	   this->_S_create_c_locale(this->_M_c_locale_messages, __s);
+ 	 }
+      }
++}
+diff --git a/libstdc++-v3/config/locale/uclibc/time_members.h b/libstdc++-v3/config/locale/uclibc/time_members.h
+index 1665dde..905c433 100644
+--- a/libstdc++-v3/config/locale/uclibc/time_members.h
++++ b/libstdc++-v3/config/locale/uclibc/time_members.h
+@@ -33,7 +33,8 @@
+ //
+ 
+ // Written by Benjamin Kosnik <bkoz@redhat.com>
+-
++namespace std
++{
+   template<typename _CharT>
+     __timepunct<_CharT>::__timepunct(size_t __refs)
+     : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
+@@ -75,3 +76,4 @@
+       delete _M_data;
+       _S_destroy_c_locale(_M_c_locale_timepunct);
+     }
++}
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0013.gcc.local_unaligned_altivec.patch b/recipes-devtools/gcc/gcc-4.9/0013.gcc.local_unaligned_altivec.patch
new file mode 100644
index 0000000..92ca909
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0013.gcc.local_unaligned_altivec.patch
@@ -0,0 +1,32 @@
+gcc.local_unaligned_altivec
+
+Optimization:
+On Altivec targets, make all char arrays 128 bits aligned (instead of 
+32 bits aligned)
+
+diff -Naur gcc-4.8.3/gcc/config/rs6000/rs6000.c gcc-4.8.3-local_unaligned_altivec/gcc/config/rs6000/rs6000.c
+--- gcc-4.8.3/gcc/config/rs6000/rs6000.c	2014-09-12 07:30:11.089024245 -0500
++++ gcc-4.8.3-local_unaligned_altivec/gcc/config/rs6000/rs6000.c	2014-09-12 07:32:21.384037349 -0500
+@@ -5853,8 +5853,8 @@
+       if (TREE_CODE (type) == ARRAY_TYPE
+ 	  && TYPE_MODE (TREE_TYPE (type)) == QImode)
+ 	{
+-	  if (align < BITS_PER_WORD)
+-	    align = BITS_PER_WORD;
++	  if (align < (TARGET_ALTIVEC ? 128 : BITS_PER_WORD))
++	    align = (TARGET_ALTIVEC ? 128 : BITS_PER_WORD);
+ 	}
+     }
+ 
+diff -Naur gcc-4.8.3/gcc/testsuite/gcc.dg/stack-usage-1.c gcc-4.8.3-local_unaligned_altivec/gcc/testsuite/gcc.dg/stack-usage-1.c
+--- gcc-4.8.3/gcc/testsuite/gcc.dg/stack-usage-1.c	2014-04-04 09:17:55.000000000 -0500
++++ gcc-4.8.3-local_unaligned_altivec/gcc/testsuite/gcc.dg/stack-usage-1.c	2014-09-12 07:35:23.139055629 -0500
+@@ -46,7 +46,7 @@
+ #elif defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) \
+       || defined (__POWERPC__) || defined (PPC) || defined (_IBMR2)
+ #  if defined (__ALTIVEC__)
+-#    if defined (__APPLE__)
++#    if defined (__APPLE__) || defined (__APPLE_ALTIVEC__)
+ #      define SIZE 204
+ #    else
+ #      define SIZE 220
diff --git a/recipes-devtools/gcc/gcc-4.9/0014-sh-pr24836.patch b/recipes-devtools/gcc/gcc-4.9/0014-sh-pr24836.patch
new file mode 100644
index 0000000..cb8fd52
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0014-sh-pr24836.patch
@@ -0,0 +1,45 @@
+From edc9acb181810f234b6b9f7d2820b0e4f6a1eeaf Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:54:48 +0400
+Subject: [PATCH 14/35] sh-pr24836
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+
+http://sourceforge.net/mailarchive/forum.php?thread_id=8959304&forum_id=5348
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24836
+---
+ gcc/configure    |    2 +-
+ gcc/configure.ac |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gcc/configure b/gcc/configure
+index e12a180..135bbf5 100755
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -23378,7 +23378,7 @@ foo:	.long	25
+ 	tls_first_minor=14
+ 	tls_as_opt="-m64 -Aesame --fatal-warnings"
+ 	;;
+-  sh-*-* | sh[34]-*-*)
++  sh-*-* | sh[34]*-*-*)
+     conftest_s='
+ 	.section ".tdata","awT",@progbits
+ foo:	.long	25
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index eba3577..6363a21 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -3141,7 +3141,7 @@ foo:	.long	25
+ 	tls_first_minor=14
+ 	tls_as_opt="-m64 -Aesame --fatal-warnings"
+ 	;;
+-  sh-*-* | sh[34]-*-*)
++  sh-*-* | sh[34]*-*-*)
+     conftest_s='
+ 	.section ".tdata","awT",@progbits
+ foo:	.long	25
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0014.gcc.soft_float-470.patch b/recipes-devtools/gcc/gcc-4.9/0014.gcc.soft_float-470.patch
new file mode 100644
index 0000000..b71c094
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0014.gcc.soft_float-470.patch
@@ -0,0 +1,16 @@
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc	2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc	2011-05-11 20:02:23.000000000 -0500
+@@ -45,10 +45,10 @@
+ #include <regression/common_type.hpp>
+ 
+ #ifndef ITERATIONS
+-#define ITERATIONS 5000
++#define ITERATIONS 2
+ #endif
+ #ifndef KEYS
+-#define KEYS 10000
++#define KEYS 5
+ #endif
+ int
+ main(int argc, char* a_p_argv[])
diff --git a/recipes-devtools/gcc/gcc-4.9/0015-arm-Use-TARGET_ENDIAN_OPTION-for-determining-MULTILI.patch b/recipes-devtools/gcc/gcc-4.9/0015-arm-Use-TARGET_ENDIAN_OPTION-for-determining-MULTILI.patch
new file mode 100644
index 0000000..37c46fc
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0015-arm-Use-TARGET_ENDIAN_OPTION-for-determining-MULTILI.patch
@@ -0,0 +1,47 @@
+From 50e5366005b0f6af27378e2a5c3cb9f9936a7e62 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:58:36 +0400
+Subject: [PATCH 15/35] arm: Use TARGET_ENDIAN_OPTION for determining
+ MULTILIB_DEFAULTS
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/config/arm/linux-elf.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: gcc-4.9.2/gcc/config/arm/coff.h
+===================================================================
+--- gcc-4.9.2.orig/gcc/config/arm/coff.h
++++ gcc-4.9.2/gcc/config/arm/coff.h
+@@ -32,8 +32,11 @@
+ #define TARGET_DEFAULT (MASK_APCS_FRAME)
+ 
+ #ifndef MULTILIB_DEFAULTS
++#ifndef TARGET_ENDIAN_OPTION
++#define TARGET_ENDIAN_OPTION "mlittle-endian"
++#endif
+ #define MULTILIB_DEFAULTS \
+-  { "marm", "mlittle-endian", "mfloat-abi=soft", "mno-thumb-interwork" }
++  { "marm", TARGET_ENDIAN_OPTION, "mfloat-abi=soft", "mno-thumb-interwork" }
+ #endif
+ \f
+ /* This is COFF, but prefer stabs.  */
+Index: gcc-4.9.2/gcc/config/arm/elf.h
+===================================================================
+--- gcc-4.9.2.orig/gcc/config/arm/elf.h
++++ gcc-4.9.2/gcc/config/arm/elf.h
+@@ -116,8 +116,11 @@
+ #endif
+ 
+ #ifndef MULTILIB_DEFAULTS
++#ifndef TARGET_ENDIAN_OPTION
++#define TARGET_ENDIAN_OPTION "mlittle-endian"
++#endif
+ #define MULTILIB_DEFAULTS \
+-  { "marm", "mlittle-endian", "mfloat-abi=soft", "mno-thumb-interwork", "fno-leading-underscore" }
++  { "marm", TARGET_ENDIAN_OPTION, "mfloat-abi=soft", "mno-thumb-interwork", "fno-leading-underscore" }
+ #endif
+ \f
+ #define TARGET_ASM_FILE_START_APP_OFF true
diff --git a/recipes-devtools/gcc/gcc-4.9/0015.gcc.case_values-48.patch b/recipes-devtools/gcc/gcc-4.9/0015.gcc.case_values-48.patch
new file mode 100644
index 0000000..94e2922
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0015.gcc.case_values-48.patch
@@ -0,0 +1,43 @@
+# Problem Statement:
+  Option 'case-values-threshold' has been integrated in to GCC v4.8.1 mainline
+  Set PowerPC target specific threshold value to generate jump tables for 
+  switch statement.
+
+# Owned by:
+  Rohit
+
+diff -Naur gcc-4.8.1/gcc/config/rs6000/rs6000.c gcc-4.8.1-case-value/gcc/config/rs6000/rs6000.c
+--- gcc-4.8.1/gcc/config/rs6000/rs6000.c	2013-07-30 06:31:20.052002899 -0500
++++ gcc-4.8.1-case-value/gcc/config/rs6000/rs6000.c	2013-07-30 06:56:15.329004807 -0500
+@@ -1458,6 +1458,9 @@
+ #undef TARGET_SET_CURRENT_FUNCTION
+ #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
+ 
++#undef TARGET_CASE_VALUES_THRESHOLD
++#define TARGET_CASE_VALUES_THRESHOLD rs6000_case_values_threshold
++
+ #undef TARGET_LEGITIMATE_CONSTANT_P
+ #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
+ 
+@@ -28639,6 +28642,21 @@
+     }
+ }
+ 
++/* Implement `CASE_VALUES_THRESHOLD'.  */
++/* Supply the default for --param case-values-threshold=0  */
++
++static unsigned int
++rs6000_case_values_threshold (void)
++{
++  if (rs6000_cpu == PROCESSOR_PPC8540
++      || rs6000_cpu == PROCESSOR_PPCE500MC
++      || rs6000_cpu == PROCESSOR_PPCE5500
++      || rs6000_cpu == PROCESSOR_PPCE6500)
++    return 8;
++
++  return 4;
++}
++
+ \f
+ /* Save the current options */
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0016-gcc-poison-system-directories.patch b/recipes-devtools/gcc/gcc-4.9/0016-gcc-poison-system-directories.patch
new file mode 100644
index 0000000..475ef96
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0016-gcc-poison-system-directories.patch
@@ -0,0 +1,190 @@
+From 160397ef3c3331099af028f1b8d3e085b07d88ad Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 08:59:00 +0400
+Subject: [PATCH 16/35] gcc: poison-system-directories
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [distribution: codesourcery]
+---
+ gcc/Makefile.in     |    2 +-
+ gcc/common.opt      |    4 ++++
+ gcc/config.in       |    6 ++++++
+ gcc/configure       |   20 ++++++++++++++++++--
+ gcc/configure.ac    |   10 ++++++++++
+ gcc/doc/invoke.texi |    9 +++++++++
+ gcc/gcc.c           |    2 ++
+ gcc/incpath.c       |   19 +++++++++++++++++++
+ 8 files changed, 69 insertions(+), 3 deletions(-)
+
+Index: gcc-4.9-20140316/gcc/common.opt
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/common.opt
++++ gcc-4.9-20140316/gcc/common.opt
+@@ -603,6 +603,10 @@ Wpedantic
+ Common Var(pedantic) Warning
+ Issue warnings needed for strict compliance to the standard
+ 
++Wpoison-system-directories
++Common Var(flag_poison_system_directories) Init(1) Warning
++Warn for -I and -L options using system directories if cross compiling
++
+ Wshadow
+ Common Var(warn_shadow) Warning
+ Warn when one local variable shadows another
+Index: gcc-4.9-20140316/gcc/config.in
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/config.in
++++ gcc-4.9-20140316/gcc/config.in
+@@ -138,6 +138,12 @@
+ #endif
+ 
+ 
++/* Define to warn for use of native system header directories */
++#ifndef USED_FOR_TARGET
++#undef ENABLE_POISON_SYSTEM_DIRECTORIES
++#endif
++
++
+ /* Define if you want all operations on RTL (the basic data structure of the
+    optimizer and back end) to be checked for dynamic type safety at runtime.
+    This is quite expensive. */
+Index: gcc-4.9-20140316/gcc/configure
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/configure
++++ gcc-4.9-20140316/gcc/configure
+@@ -928,6 +928,7 @@ with_system_zlib
+ enable_maintainer_mode
+ enable_link_mutex
+ enable_version_specific_runtime_libs
++enable_poison_system_directories
+ enable_plugin
+ enable_host_shared
+ enable_libquadmath_support
+@@ -1648,6 +1649,8 @@ Optional Features:
+   --enable-version-specific-runtime-libs
+                           specify that runtime libraries should be installed
+                           in a compiler-specific directory
++  --enable-poison-system-directories
++                          warn for use of native system header directories
+   --enable-plugin         enable plugin support
+   --enable-host-shared    build host code as shared libraries
+   --disable-libquadmath-support
+@@ -27702,6 +27705,19 @@ if test "${enable_version_specific_runti
+ fi
+ 
+ 
++# Check whether --enable-poison-system-directories was given.
++if test "${enable_poison_system_directories+set}" = set; then :
++  enableval=$enable_poison_system_directories;
++else
++  enable_poison_system_directories=no
++fi
++
++if test "x${enable_poison_system_directories}" = "xyes"; then
++
++$as_echo "#define ENABLE_POISON_SYSTEM_DIRECTORIES 1" >>confdefs.h
++
++fi
++
+ # Substitute configuration variables
+ 
+ 
+Index: gcc-4.9-20140316/gcc/configure.ac
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/configure.ac
++++ gcc-4.9-20140316/gcc/configure.ac
+@@ -5366,6 +5366,16 @@ AC_ARG_ENABLE(version-specific-runtime-l
+                 [specify that runtime libraries should be
+                  installed in a compiler-specific directory])])
+ 
++AC_ARG_ENABLE([poison-system-directories],
++             AS_HELP_STRING([--enable-poison-system-directories],
++                            [warn for use of native system header directories]),,
++             [enable_poison_system_directories=no])
++if test "x${enable_poison_system_directories}" = "xyes"; then
++  AC_DEFINE([ENABLE_POISON_SYSTEM_DIRECTORIES],
++           [1],
++           [Define to warn for use of native system header directories])
++fi
++
+ # Substitute configuration variables
+ AC_SUBST(subdirs)
+ AC_SUBST(srcdir)
+Index: gcc-4.9-20140316/gcc/doc/invoke.texi
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/doc/invoke.texi
++++ gcc-4.9-20140316/gcc/doc/invoke.texi
+@@ -260,6 +260,7 @@ Objective-C and Objective-C++ Dialects}.
+ -Woverlength-strings  -Wpacked  -Wpacked-bitfield-compat  -Wpadded @gol
+ -Wparentheses  -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
+ -Wpointer-arith  -Wno-pointer-to-int-cast @gol
++-Wno-poison-system-directories @gol
+ -Wredundant-decls  -Wno-return-local-addr @gol
+ -Wreturn-type  -Wsequence-point  -Wshadow @gol
+ -Wsign-compare  -Wsign-conversion -Wfloat-conversion @gol
+@@ -4230,6 +4231,14 @@ headers---for that, @option{-Wunknown-pr
+  for most targets, it is made up of code and thus requires the stack
+  to be made executable in order for the program to work properly.
+ 
++@item -Wno-poison-system-directories
++@opindex Wno-poison-system-directories
++Do not warn for @option{-I} or @option{-L} options using system
++directories such as @file{/usr/include} when cross compiling.  This
++option is intended for use in chroot environments when such
++directories contain the correct headers and libraries for the target
++system rather than the host.
++
+ @item -Wfloat-equal
+ @opindex Wfloat-equal
+ @opindex Wno-float-equal
+Index: gcc-4.9-20140316/gcc/gcc.c
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/gcc.c
++++ gcc-4.9-20140316/gcc/gcc.c
+@@ -764,6 +764,8 @@ proper position among the other output f
+    "%{fuse-ld=*:-fuse-ld=%*}\
+     %X %{o*} %{e*} %{N} %{n} %{r}\
+     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} " VTABLE_VERIFICATION_SPEC " \
++    %{Wno-poison-system-directories:--no-poison-system-directories}\
++    %{Werror=poison-system-directories:--error-poison-system-directories}\
+     %{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\
+     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
+     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
+Index: gcc-4.9-20140316/gcc/incpath.c
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/incpath.c
++++ gcc-4.9-20140316/gcc/incpath.c
+@@ -28,6 +28,7 @@
+ #include "intl.h"
+ #include "incpath.h"
+ #include "cppdefault.h"
++#include "diagnostic-core.h"
+ 
+ /* Microsoft Windows does not natively support inodes.
+    VMS has non-numeric inodes.  */
+@@ -382,6 +383,24 @@ merge_include_chains (const char *sysroo
+ 	}
+       fprintf (stderr, _("End of search list.\n"));
+     }
++
++#ifdef ENABLE_POISON_SYSTEM_DIRECTORIES
++  if (flag_poison_system_directories)
++    {
++       struct cpp_dir *p;
++
++       for (p = heads[QUOTE]; p; p = p->next)
++         {
++          if ((!strncmp (p->name, "/usr/include", 12))
++              || (!strncmp (p->name, "/usr/local/include", 18))
++              || (!strncmp (p->name, "/usr/X11R6/include", 18)))
++            warning (OPT_Wpoison_system_directories,
++                     "include location \"%s\" is unsafe for "
++                     "cross-compilation",
++                     p->name);
++         }
++    }
++#endif
+ }
+ 
+ /* Use given -I paths for #include "..." but not #include <...>, and
diff --git a/recipes-devtools/gcc/gcc-4.9/0016.gcc.fix_pr63854_pass_manager.patch b/recipes-devtools/gcc/gcc-4.9/0016.gcc.fix_pr63854_pass_manager.patch
new file mode 100644
index 0000000..3595b8f
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0016.gcc.fix_pr63854_pass_manager.patch
@@ -0,0 +1,22 @@
+# Problem Statement:
+  Windows toolchain gave an ICE in pass manager.
+
+# Owned by:
+  Rohit
+
+# Referred from patch by:
+  David Malcolm
+
+# Action:
+  * Backport r217807 trunk to add all_late_ipa_passes to GCC_PASS_LISTS
+
+--- trunk/gcc/pass_manager.h	2014/11/19 20:21:19	217806
++++ trunk/gcc/pass_manager.h	2014/11/19 20:26:57	217807
+@@ -29,6 +29,7 @@
+   DEF_PASS_LIST (all_lowering_passes) \
+   DEF_PASS_LIST (all_small_ipa_passes) \
+   DEF_PASS_LIST (all_regular_ipa_passes) \
++  DEF_PASS_LIST (all_late_ipa_passes) \
+   DEF_PASS_LIST (all_passes)
+ 
+ #define DEF_PASS_LIST(LIST) PASS_LIST_NO_##LIST,
diff --git a/recipes-devtools/gcc/gcc-4.9/0017-gcc-poison-dir-extend.patch b/recipes-devtools/gcc/gcc-4.9/0017-gcc-poison-dir-extend.patch
new file mode 100644
index 0000000..9e81efd
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0017-gcc-poison-dir-extend.patch
@@ -0,0 +1,39 @@
+From e99c9c97266d6d3e8cac798aa91408250c4d60cf Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:00:34 +0400
+Subject: [PATCH 17/35] gcc-poison-dir-extend
+
+Add /sw/include and /opt/include based on the original
+zecke-no-host-includes.patch patch.  The original patch checked for
+/usr/include, /sw/include and /opt/include and then triggered a failure and
+aborted.
+
+Instead, we add the two missing items to the current scan.  If the user
+wants this to be a failure, they can add "-Werror=poison-system-directories".
+
+Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/incpath.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/incpath.c b/gcc/incpath.c
+index cd41c78..eac4a92 100644
+--- a/gcc/incpath.c
++++ b/gcc/incpath.c
+@@ -393,7 +393,9 @@ merge_include_chains (const char *sysroot, cpp_reader *pfile, int verbose)
+          {
+           if ((!strncmp (p->name, "/usr/include", 12))
+               || (!strncmp (p->name, "/usr/local/include", 18))
+-              || (!strncmp (p->name, "/usr/X11R6/include", 18)))
++              || (!strncmp (p->name, "/usr/X11R6/include", 18))
++              || (!strncmp (p->name, "/sw/include", 11))
++              || (!strncmp (p->name, "/opt/include", 12)))
+             warning (OPT_Wpoison_system_directories,
+                      "include location \"%s\" is unsafe for "
+                      "cross-compilation",
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0017.gcc.builtin_isel_doc.patch b/recipes-devtools/gcc/gcc-4.9/0017.gcc.builtin_isel_doc.patch
new file mode 100644
index 0000000..cf71d4d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0017.gcc.builtin_isel_doc.patch
@@ -0,0 +1,109 @@
+--- gcc-4.5-2011.03/gcc/doc/extend.texi	2013-08-07 14:06:33.409961113 -0500
++++ gcc-4.5-2011.03/gcc/doc/extend.texi-new	2013-08-07 14:04:49.121960015 -0500
+@@ -11957,6 +11957,106 @@
+ int __builtin_bswap16 (int);
+ @end smallexample
+ 
++GCC also provides a family of builtins on PowerPC to explicitly use
++the @code{isel} instruction.  While GCC can and does generate
++@code{isel} instructions normally, the builtins enable you to
++explicitly force generation of these instructions.  The builtins are
++only available when compiling for processors that support the
++@code{isel} instruction; they compile to a code sequence of
++@code{cmpw} followed by @code{isel}.
++
++@table @code
++@item int __builtin_iseleq (int @var{x}, int @var{y}, int @var{a}, int @var{b})
++@itemx int __builtin_iseleq (unsigned int @var{x}, unsigned int @var{y}, int @var{a}, int @var{b})
++@itemx int __builtin_iseleq (void *@var{x}, void *@var{y}, int @var{a}, int @var{b})
++@itemx unsigned int __builtin_iseleq (int @var{x}, int @var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx unsigned int __builtin_iseleq (unsigned int @var{x}, unsigned int @var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx unsigned int __builtin_iseleq (void *@var{x}, void *@var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx void *__builtin_iseleq (int @var{x}, int @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_iseleq (unsigned int @var{x}, unsigned int @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_iseleq (void *@var{x}, void *@var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} and @var{y} are equal, otherwise return @var{b}.
++
++@item int __builtin_isellt (int @var{x}, int @var{y}, int @var{a}, int @var{b})
++@itemx unsigned int __builtin_isellt (int @var{x}, int @var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx void *__builtin_isellt (int @var{x}, int @var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is less than @var{y}, otherwise return @var{b}.
++Note that this uses signed comparison.
++
++@item int __builtin_iselgt (int @var{x}, int @var{y}, int @var{a}, int @var{b})
++@itemx unsigned int __builtin_iselgt (int @var{x}, int @var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx void *__builtin_iselgt (int @var{x}, int @var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is greater than @var{y}, otherwise return @var{b}.
++Note that this uses signed comparison.
++
++@item int __builtin_iselltu (unsigned int @var{x}, unsigned int @var{y}, int @var{a}, int @var{b})
++@itemx int __builtin_iselltu (void *@var{x}, void *@var{y}, int @var{a}, int @var{b})
++@itemx unsigned int __builtin_iselltu (unsigned int @var{x}, unsigned int @var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx unsigned int __builtin_iselltu (void *@var{x}, void *@var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx void *__builtin_iselltu (unsigned int @var{x}, unsigned int @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_iselltu (void *@var{x}, void *@var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is less than @var{y}, otherwise return @var{b}
++In contrast to @code{__builtin_isellt}, this uses unsigned comparison.
++
++@item int __builtin_iselgtu (unsigned int @var{x}, unsigned int @var{y}, int @var{a}, int @var{b})
++@itemx int __builtin_iselgtu (void *@var{x}, void *@var{y}, int @var{a}, int @var{b})
++@itemx unsigned int __builtin_iselgtu (unsigned int @var{x}, unsigned int @var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx unsigned int __builtin_iselgtu (void *@var{x}, void *@var{y}, unsigned int @var{a}, unsigned int @var{b})
++@itemx void *__builtin_iselgtu (unsigned int @var{x}, unsigned int @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_iselgtu (void *@var{x}, void *@var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is greater than @var{y}, otherwise return @var{b}
++In contrast to @code{__builtin_iselgt}, this uses unsigned comparison.
++
++@end table
++
++Builtins that do 64-bit comparisons (i.e. using @code{cmpd} instead of
++@code{cmpw}) are also available on 64-bit processors supporting
++@code{isel}.
++
++@table @code
++@item long __builtin_isel64eq (long @var{x}, long @var{y}, long @var{a}, long @var{b})
++@itemx long __builtin_isel64eq (unsigned long @var{x}, unsigned long @var{y}, long @var{a}, long @var{b})
++@itemx long __builtin_isel64eq (void *@var{x}, void *@var{y}, long @var{a}, long @var{b})
++@itemx unsigned long __builtin_isel64eq (long @var{x}, long @var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx unsigned long __builtin_isel64eq (unsigned long @var{x}, unsigned long @var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx unsigned long __builtin_isel64eq (void *@var{x}, void *@var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx void *__builtin_isel64eq (long @var{x}, long @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_isel64eq (unsigned long @var{x}, unsigned long @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_isel64eq (void *@var{x}, void *@var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} and @var{y} are equal, otherwise return @var{b}.
++
++@item long __builtin_isel64lt (long @var{x}, long @var{y}, long @var{a}, long @var{b})
++@itemx unsigned long __builtin_isel64lt (long @var{x}, long @var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx void *__builtin_isel64lt (long @var{x}, long @var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is less than @var{y}, otherwise return @var{b}.
++Note that this uses signed comparison.
++
++@item long __builtin_isel64gt (long @var{x}, long @var{y}, long @var{a}, long @var{b})
++@itemx unsigned long __builtin_isel64gt (long @var{x}, long @var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx void *__builtin_isel64gt (long @var{x}, long @var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is greater than @var{y}, otherwise return @var{b}.
++Note that this uses signed comparison.
++
++@item long __builtin_isel64ltu (unsigned long @var{x}, unsigned long @var{y}, long @var{a}, long @var{b})
++@itemx long __builtin_isel64ltu (void *@var{x}, void *@var{y}, long @var{a}, long @var{b})
++@itemx unsigned long __builtin_isel64ltu (unsigned long @var{x}, unsigned long @var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx unsigned long __builtin_isel64ltu (void *@var{x}, void *@var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx void *__builtin_isel64ltu (unsigned long @var{x}, unsigned long @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_isel64ltu (void *@var{x}, void *@var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is less than @var{y}, otherwise return @var{b}
++In contrast to @code{__builtin_isel64lt}, this uses unsigned comparison.
++
++@item long __builtin_isel64gtu (unsigned long @var{x}, unsigned long @var{y}, long @var{a}, long @var{b})
++@itemx long __builtin_isel64gtu (void *@var{x}, void *@var{y}, long @var{a}, long @var{b})
++@itemx unsigned long __builtin_isel64gtu (unsigned long @var{x}, unsigned long @var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx unsigned long __builtin_isel64gtu (void *@var{x}, void *@var{y}, unsigned long @var{a}, unsigned long @var{b})
++@itemx void *__builtin_isel64gtu (unsigned long @var{x}, unsigned long @var{y}, void *@var{a}, void *@var{b})
++@itemx void *__builtin_isel64gtu (void *@var{x}, void *@var{y}, void *@var{a}, void *@var{b})
++Return @var{a} if @var{x} is greater than @var{y}, otherwise return @var{b}
++In contrast to @code{__builtin_isel64gt}, this uses unsigned comparison.
++
++@end table
++
+ @node RX Built-in Functions
+ @subsection RX Built-in Functions
+ GCC supports some of the RX instructions which cannot be expressed in
diff --git a/recipes-devtools/gcc/gcc-4.9/0018-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch b/recipes-devtools/gcc/gcc-4.9/0018-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch
new file mode 100644
index 0000000..a28cafd
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0018-gcc-4.3.3-SYSROOT_CFLAGS_FOR_TARGET.patch
@@ -0,0 +1,73 @@
+From 56207fa2923e8edf774e98ffac82666091076be3 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:08:31 +0400
+Subject: [PATCH 18/35] gcc-4.3.3: SYSROOT_CFLAGS_FOR_TARGET
+
+Before committing, I noticed that PR/32161 was marked as a dup of PR/32009, but my previous patch did not fix it.
+
+This alternative patch is better because it lets you just use CFLAGS_FOR_TARGET to set the compilation flags for libgcc. Since bootstrapped target libraries are never compiled with the native compiler, it makes little sense to use different flags for stage1 and later stages. And it also makes little sense to use a different variable than CFLAGS_FOR_TARGET.
+
+Other changes I had to do include:
+
+- moving the creation of default CFLAGS_FOR_TARGET from Makefile.am to configure.ac, because otherwise the BOOT_CFLAGS are substituted into CFLAGS_FOR_TARGET (which is "-O2 -g $(CFLAGS)") via $(CFLAGS). It is also cleaner this way though.
+
+- passing the right CFLAGS to configure scripts as exported environment variables
+
+I also stopped passing LIBCFLAGS to configure scripts since they are unused in the whole src tree. And I updated the documentation as H-P reminded me to do.
+
+Bootstrapped/regtested i686-pc-linux-gnu, will commit to 4.4 shortly. Ok for 4.3?
+
+Signed-off-by: Paolo Bonzini  <bonzini@gnu.org>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ configure |   32 ++++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/configure b/configure
+index 1b76c90..e4dce7c 100755
+--- a/configure
++++ b/configure
+@@ -6772,6 +6772,38 @@ fi
+ 
+ 
+ 
++# During gcc bootstrap, if we use some random cc for stage1 then CFLAGS
++# might be empty or "-g".  We don't require a C++ compiler, so CXXFLAGS
++# might also be empty (or "-g", if a non-GCC C++ compiler is in the path).
++# We want to ensure that TARGET libraries (which we know are built with
++# gcc) are built with "-O2 -g", so include those options when setting
++# CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET.
++if test "x$CFLAGS_FOR_TARGET" = x; then
++  CFLAGS_FOR_TARGET=$CFLAGS
++  case " $CFLAGS " in
++    *" -O2 "*) ;;
++    *) CFLAGS_FOR_TARGET="-O2 $CFLAGS" ;;
++  esac
++  case " $CFLAGS " in
++    *" -g "* | *" -g3 "*) ;;
++    *) CFLAGS_FOR_TARGET="-g $CFLAGS" ;;
++  esac
++fi
++
++
++if test "x$CXXFLAGS_FOR_TARGET" = x; then
++  CXXFLAGS_FOR_TARGET=$CXXFLAGS
++  case " $CXXFLAGS " in
++    *" -O2 "*) ;;
++    *) CXXFLAGS_FOR_TARGET="-O2 $CXXFLAGS" ;;
++  esac
++  case " $CXXFLAGS " in
++    *" -g "* | *" -g3 "*) ;;
++    *) CXXFLAGS_FOR_TARGET="-g $CXXFLAGS" ;;
++  esac
++fi
++
++
+ # Handle --with-headers=XXX.  If the value is not "yes", the contents of
+ # the named directory are copied to $(tooldir)/sys-include.
+ if test x"${with_headers}" != x && test x"${with_headers}" != xno ; then
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0018.gcc.experimental_move.patch b/recipes-devtools/gcc/gcc-4.9/0018.gcc.experimental_move.patch
new file mode 100644
index 0000000..3cb2aa6
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0018.gcc.experimental_move.patch
@@ -0,0 +1,32 @@
+diff -ruN gcc-4.4.0/gcc/config/rs6000/rs6000.c gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.c
+--- gcc-4.4.0/gcc/config/rs6000/rs6000.c	2009-03-17 15:18:21.000000000 -0500
++++ gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.c	2009-12-04 10:36:44.000000000 -0600
+@@ -11032,6 +11059,14 @@
+ 	  mode = SImode;
+ 	  gen_func.mov = gen_movsi;
+ 	}
++      else if (TARGET_COPY_UNALIGNED && bytes == 3 && offset > 0)
++	{
++	  /* We generate a single unaligned SI move instead of 2 (HI, QI) */
++	  move_bytes = 3;
++	  mode = SImode;
++	  gen_func.mov = gen_movsi;
++	  offset--;
++	}
+       else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
+ 	{			/* move 2 bytes */
+ 	  move_bytes = 2;
+diff -ruN gcc-4.4.0/gcc/config/rs6000/rs6000.opt gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.opt
+--- gcc-4.4.0/gcc/config/rs6000/rs6000.opt	2009-02-20 09:20:38.000000000 -0600
++++ gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.opt	2009-09-30 13:51:17.000000000 -0500
+@@ -201,6 +201,10 @@
+ Target RejectNegative Joined
+ -misel=yes/no	Deprecated option.  Use -misel/-mno-isel instead
+ 
++mcopy-unaligned
++Target Report Var(TARGET_COPY_UNALIGNED)
++Generate unaligned word load and stores to move 3 bytes
++
+ mspe
+ Target
+ Generate SPE SIMD instructions on E500
diff --git a/recipes-devtools/gcc/gcc-4.9/0019-64-bit-multilib-hack.patch b/recipes-devtools/gcc/gcc-4.9/0019-64-bit-multilib-hack.patch
new file mode 100644
index 0000000..058be0c
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0019-64-bit-multilib-hack.patch
@@ -0,0 +1,82 @@
+From 18fde5740b09324dfb9cf41e9849672573ff5fa0 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:10:06 +0400
+Subject: [PATCH 19/35] 64-bit multilib hack.
+
+GCC has internal multilib handling code but it assumes a very specific rigid directory
+layout. The build system implementation of multilib layout is very generic and allows
+complete customisation of the library directories.
+
+This patch is a partial solution to allow any custom directories to be passed into gcc
+and handled correctly. It forces gcc to use the base_libdir (which is the current
+directory, "."). We need to do this for each multilib that is configured as we don't
+know which compiler options may be being passed into the compiler. Since we have a compiler
+per mulitlib at this point that isn't an issue.
+
+The one problem is the target compiler is only going to work for the default multlilib at
+this point. Ideally we'd figure out which multilibs were being enabled with which paths
+and be able to patch these entries with a complete set of correct paths but this we
+don't have such code at this point. This is something the target gcc recipe should do
+and override these platform defaults in its build config.
+
+RP 15/8/11
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Signed-off-by: Elvis Dowson <elvis.dowson@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/config/i386/t-linux64   |    6 ++----
+ gcc/config/mips/t-linux64   |   10 +++-------
+ gcc/config/rs6000/t-linux64 |    5 ++---
+ 3 files changed, 7 insertions(+), 14 deletions(-)
+
+Index: gcc-4.9-20140316/gcc/config/i386/t-linux64
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/config/i386/t-linux64
++++ gcc-4.9-20140316/gcc/config/i386/t-linux64
+@@ -32,7 +32,5 @@
+ #
+ comma=,
+ MULTILIB_OPTIONS    = $(subst $(comma),/,$(TM_MULTILIB_CONFIG))
+-MULTILIB_DIRNAMES   = $(patsubst m%, %, $(subst /, ,$(MULTILIB_OPTIONS)))
+-MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-linux-gnu)
+-MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:i386-linux-gnu)
+-MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-linux-gnux32)
++MULTILIB_DIRNAMES = . .
++MULTILIB_OSDIRNAMES = ../$(shell basename $(base_libdir)) ../$(shell basename $(base_libdir))
+Index: gcc-4.9-20140316/gcc/config/mips/t-linux64
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/config/mips/t-linux64
++++ gcc-4.9-20140316/gcc/config/mips/t-linux64
+@@ -17,10 +17,6 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ MULTILIB_OPTIONS = mabi=n32/mabi=32/mabi=64
+-MULTILIB_DIRNAMES = n32 32 64
+-MIPS_EL = $(if $(filter %el, $(firstword $(subst -, ,$(target)))),el)
+-MIPS_SOFT = $(if $(strip $(filter MASK_SOFT_FLOAT_ABI, $(target_cpu_default)) $(filter soft, $(with_float))),soft)
+-MULTILIB_OSDIRNAMES = \
+-	../lib32$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \
+-	../lib$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \
+-	../lib64$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT))
++MULTILIB_DIRNAMES = . . .
++MULTILIB_OSDIRNAMES = ../$(shell basename $(base_libdir)) ../$(shell basename $(base_libdir)) ../$(shell basename $(base_libdir))
++
+Index: gcc-4.9-20140316/gcc/config/rs6000/t-linux64
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/config/rs6000/t-linux64
++++ gcc-4.9-20140316/gcc/config/rs6000/t-linux64
+@@ -26,10 +26,9 @@
+ # MULTILIB_OSDIRNAMES according to what is found on the target.
+ 
+ MULTILIB_OPTIONS    := m64/m32
+-MULTILIB_DIRNAMES   := 64 32
++MULTILIB_DIRNAMES   := . .
+ MULTILIB_EXTRA_OPTS := 
+-MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu)
+-MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
++MULTILIB_OSDIRNAMES := ../$(shell basename $(base_libdir)) ../$(shell basename $(base_libdir))
+ 
+ rs6000-linux.o: $(srcdir)/config/rs6000/rs6000-linux.c
+ 	$(COMPILE) $<
diff --git a/recipes-devtools/gcc/gcc-4.9/0019.gcc.e5500_mfocr.patch b/recipes-devtools/gcc/gcc-4.9/0019.gcc.e5500_mfocr.patch
new file mode 100644
index 0000000..63ee3cf
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0019.gcc.e5500_mfocr.patch
@@ -0,0 +1,181 @@
+# Problem: Although gcc is prepared to avoid "mfocr" instructions
+  (which takes 5 cycles in our parts and 2 cycles on IBM parts). This
+  instruction is used on the mentioned program. What is suspicious
+  about it, is that the code compiled for 32 bits does not use the
+  instruction. So, it could be a omission in the previous
+  implementation, or a bug, or a new opportunity.
+# Reported by: Performance team (PARC)
+# Owned by: Ping Hu
+# Action:
+    * 'mfocr' flag problem: that 'mfocr' flag was uncorrectly set for E5500,
+      which caused the 'mfocr' instructions generated even on E5500.
+    * avoid generating 'mfcr' and 'mfocr' instructions: due to the fact
+      that both instructions are expensive on Freescale processors.
+    * A target specific flag, -mslow-mfocr, can be used to avoid generating
+      'mfcr' and 'mfocr' instructions in 64-bit mode, thus restoring legacy
+      operations if desired.
+
+diff -ruN gcc-4.6.2-clean/gcc/config/rs6000/rs6000.c gcc-4.6.2/gcc/config/rs6000/rs6000.c
+--- gcc-4.6.2-clean/gcc/config/rs6000/rs6000.c	2011-11-22 11:11:47.479144000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.c	2011-11-29 16:23:45.074279998 -0600
+@@ -1885,6 +1885,7 @@
+    POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
+ };
+ 
++
+ /* Look up a processor name for -mcpu=xxx and -mtune=xxx.  Return -1 if the
+    name is invalid.  */
+ 
+@@ -2902,6 +2903,10 @@
+       || rs6000_cpu == PROCESSOR_PPCE6500)
+     target_flags &= ~MASK_PPC_GPOPT;
+ 
++  if (rs6000_cpu == PROCESSOR_PPCE5500)
++      target_flags &= ~MASK_MFCRF;
++
++
+   /* store_one_arg depends on expand_block_move to handle at least the
+      size of reg_parm_stack_space.  */
+   if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
+diff -ruN gcc-4.6.2-clean/gcc/config/rs6000/rs6000.md gcc-4.6.2/gcc/config/rs6000/rs6000.md
+--- gcc-4.6.2-clean/gcc/config/rs6000/rs6000.md	2011-11-22 11:11:47.036144001 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.md	2011-11-29 16:24:04.705280001 -0600
+@@ -215,6 +215,8 @@
+ ; (one with a '.') will compare; and the size used for arithmetic carries.
+ (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
+ 
++(define_mode_iterator P2 [(SI "TARGET_32BIT || TARGET_SLOW_MFOCR") (DI "TARGET_64BIT")])
++
+ ; Any hardware-supported floating-point mode
+ (define_mode_iterator FP [
+   (SF "TARGET_HARD_FLOAT 
+@@ -2208,9 +2210,9 @@
+ 
+ (define_insn ""
+   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+-	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
++	(compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" "r,r"))
+ 		    (const_int 0)))
+-   (clobber (match_scratch:P 2 "=r,r"))]
++   (clobber (match_scratch:P2 2 "=r,r"))]
+   ""
+   "@
+    neg. %2,%1
+@@ -2220,12 +2222,12 @@
+ 
+ (define_split
+   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+-	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
++	(compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" ""))
+ 		    (const_int 0)))
+-   (clobber (match_scratch:P 2 ""))]
++   (clobber (match_scratch:P2 2 ""))]
+   "reload_completed"
+   [(set (match_dup 2)
+-	(neg:P (match_dup 1)))
++	(neg:P2 (match_dup 1)))
+    (set (match_dup 0)
+ 	(compare:CC (match_dup 2)
+ 		    (const_int 0)))]
+@@ -2233,10 +2235,10 @@
+ 
+ (define_insn ""
+   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+-	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
++	(compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" "r,r"))
+ 		    (const_int 0)))
+-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
+-	(neg:P (match_dup 1)))]
++   (set (match_operand:P2 0 "gpc_reg_operand" "=r,r")
++	(neg:P2 (match_dup 1)))]
+   ""
+   "@
+    neg. %0,%1
+@@ -2246,13 +2248,13 @@
+ 
+ (define_split
+   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+-	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
++	(compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" ""))
+ 		    (const_int 0)))
+-   (set (match_operand:P 0 "gpc_reg_operand" "")
+-	(neg:P (match_dup 1)))]
++   (set (match_operand:P2 0 "gpc_reg_operand" "")
++	(neg:P2 (match_dup 1)))]
+   "reload_completed"
+   [(set (match_dup 0)
+-	(neg:P (match_dup 1)))
++	(neg:P2 (match_dup 1)))
+    (set (match_dup 2)
+ 	(compare:CC (match_dup 0)
+ 		    (const_int 0)))]
+@@ -15286,31 +15288,31 @@
+   [(set_attr "length" "12")])
+ 
+ (define_insn_and_split "*gtu<mode>"
+-  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+-	(gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
+-	       (match_operand:P 2 "reg_or_short_operand" "rI")))]
++  [(set (match_operand:P2 0 "gpc_reg_operand" "=r")
++	(gtu:P2 (match_operand:P2 1 "gpc_reg_operand" "r")
++	        (match_operand:P2 2 "reg_or_short_operand" "rI")))]
+   ""
+   "#"
+   ""
+-  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
+-   (set (match_dup 0) (neg:P (match_dup 0)))]
++  [(set (match_dup 0) (neg:P2 (gtu:P2 (match_dup 1) (match_dup 2))))
++   (set (match_dup 0) (neg:P2 (match_dup 0)))]
+   "")
+ 
+ (define_insn_and_split "*gtu<mode>_compare"
+   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ 	(compare:CC
+-	 (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
+-		 (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
++	 (gtu:P2 (match_operand:P2 1 "gpc_reg_operand" "r,r")
++		 (match_operand:P2 2 "reg_or_short_operand" "rI,rI"))
+ 	 (const_int 0)))
+-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
+-	(gtu:P (match_dup 1) (match_dup 2)))]
++   (set (match_operand:P2 0 "gpc_reg_operand" "=r,r")
++	(gtu:P2 (match_dup 1) (match_dup 2)))]
+   ""
+   "#"
+   ""
+-  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
++  [(set (match_dup 0) (neg:P2 (gtu:P2 (match_dup 1) (match_dup 2))))
+    (parallel [(set (match_dup 3)
+-		   (compare:CC (neg:P (match_dup 0)) (const_int 0)))
+-	      (set (match_dup 0) (neg:P (match_dup 0)))])]
++		   (compare:CC (neg:P2 (match_dup 0)) (const_int 0)))
++	      (set (match_dup 0) (neg:P2 (match_dup 0)))])]
+   "")
+ 
+ (define_insn_and_split "*plus_gtu<mode>"
+@@ -15345,9 +15347,9 @@
+   "")
+ 
+ (define_insn "*neg_gtu<mode>"
+-  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+-	(neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
+-		      (match_operand:P 2 "reg_or_short_operand" "rI"))))]
++  [(set (match_operand:P2 0 "gpc_reg_operand" "=r")
++	(neg:P2 (gtu:P2 (match_operand:P2 1 "gpc_reg_operand" "r")
++		      	(match_operand:P2 2 "reg_or_short_operand" "rI"))))]
+   ""
+   "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
+   [(set_attr "type" "two")
+--- gcc-4.6.2-clean/gcc/config/rs6000/rs6000.opt	2011-11-22 11:11:47.480143999 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.opt	2011-11-29 16:24:16.322280634 -0600
+@@ -381,6 +381,10 @@
+ Target
+ Generate SPE SIMD instructions on E500
+ 
++mslow-mfocr
++Target Report Var(TARGET_SLOW_MFOCR)
++Generate slow mfocr instructions
++
+ mpaired
+ Target Var(rs6000_paired_float) Save
+ Generate PPC750CL paired-single instructions
diff --git a/recipes-devtools/gcc/gcc-4.9/0020-optional-libstdc.patch b/recipes-devtools/gcc/gcc-4.9/0020-optional-libstdc.patch
new file mode 100644
index 0000000..5b46614
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0020-optional-libstdc.patch
@@ -0,0 +1,98 @@
+From 307c8ff3ef666b7bd5ac733863f2fbb27a9d521e Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:12:56 +0400
+Subject: [PATCH 20/35] optional libstdc
+
+gcc-runtime builds libstdc++ separately from gcc-cross-*. Its configure tests using g++
+will not run correctly since by default the linker will try to link against libstdc++
+which shouldn't exist yet. We need an option to disable -lstdc++
+option whilst leaving -lc, -lgcc and other automatic library dependencies added by gcc
+driver. This patch adds such an option which only disables the -lstdc++.
+
+A "standard" gcc build uses xgcc and hence avoids this. We should ask upstream how to
+do this officially, the likely answer is don't build libstdc++ separately.
+
+RP 29/6/10
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [embedded specific]
+---
+ gcc/c-family/c.opt  |    4 ++++
+ gcc/cp/g++spec.c    |    1 +
+ gcc/doc/invoke.texi |    9 +++++++--
+ gcc/gcc.c           |    1 +
+ 4 files changed, 13 insertions(+), 2 deletions(-)
+
+Index: gcc-4.9-20140316/gcc/c-family/c.opt
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/c-family/c.opt
++++ gcc-4.9-20140316/gcc/c-family/c.opt
+@@ -1323,6 +1323,10 @@ nostdinc++
+ C++ ObjC++
+ Do not search standard system include directories for C++
+ 
++nostdlib++
++Driver
++Do not link standard C++ runtime library
++
+ o
+ C ObjC C++ ObjC++ Joined Separate
+ ; Documented in common.opt
+Index: gcc-4.9-20140316/gcc/cp/g++spec.c
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/cp/g++spec.c
++++ gcc-4.9-20140316/gcc/cp/g++spec.c
+@@ -138,6 +138,7 @@ lang_specific_driver (struct cl_decoded_
+       switch (decoded_options[i].opt_index)
+ 	{
+ 	case OPT_nostdlib:
++	case OPT_nostdlib__:
+ 	case OPT_nodefaultlibs:
+ 	  library = -1;
+ 	  break;
+Index: gcc-4.9-20140316/gcc/doc/invoke.texi
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/doc/invoke.texi
++++ gcc-4.9-20140316/gcc/doc/invoke.texi
+@@ -193,6 +193,7 @@ in the following sections.
+ -fvisibility-inlines-hidden @gol
+ -fvtable-verify=@var{std|preinit|none} @gol
+ -fvtv-counts -fvtv-debug @gol
++-nostdlib++ @gol
+ -fvisibility-ms-compat @gol
+ -fext-numeric-literals @gol
+ -Wabi  -Wconversion-null  -Wctor-dtor-privacy @gol
+@@ -457,7 +458,7 @@ Objective-C and Objective-C++ Dialects}.
+ -nostartfiles  -nodefaultlibs  -nostdlib -pie -rdynamic @gol
+ -s  -static -static-libgcc -static-libstdc++ @gol
+ -static-libasan -static-libtsan -static-liblsan -static-libubsan @gol
+--shared -shared-libgcc  -symbolic @gol
++-shared -shared-libgcc  -symbolic -nostdlib++ @gol
+ -T @var{script}  -Wl,@var{option}  -Xlinker @var{option} @gol
+ -u @var{symbol}}
+ 
+@@ -10285,6 +10286,11 @@ These entries are usually resolved by en
+ libc.  These entry points should be supplied through some other
+ mechanism when this option is specified.
+ 
++@item -nostdlib++
++@opindex nostdlib++
++Do not use the standard system C++ runtime libraries when linking.
++Only the libraries you specify will be passed to the linker.
++
+ @cindex @option{-lgcc}, use with @option{-nostdlib}
+ @cindex @option{-nostdlib} and unresolved references
+ @cindex unresolved references and @option{-nostdlib}
+Index: gcc-4.9-20140316/gcc/gcc.c
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/gcc.c
++++ gcc-4.9-20140316/gcc/gcc.c
+@@ -772,6 +772,7 @@ proper position among the other output f
+     %(mflib) " STACK_SPLIT_SPEC "\
+     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
+     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
++    %{!nostdlib++:}\
+     %{!nostdlib:%{!nostartfiles:%E}} %{T*} }}}}}}"
+ #endif
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0020.gcc.load_on_store_bypass-48x.patch b/recipes-devtools/gcc/gcc-4.9/0020.gcc.load_on_store_bypass-48x.patch
new file mode 100644
index 0000000..dbdc5b7
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0020.gcc.load_on_store_bypass-48x.patch
@@ -0,0 +1,137 @@
+# Problem Statement
+ This patch implements option -fbypass-load-on-store
+
+ A load on store collision causes the load to to be replayed if the store has not completed.
+ Under -fbypass-load-on-store, GCC will attempt to avoid a load on store collision by trying
+ to space the load away from the store by scheduling upto 14 instructions in between, to
+ prevent the load from executing too early.
+
+# Owned by:
+  Russo John
+
+# Action:
+
+ * -fbypass-load-on-store is enabled under -fschedule-insns
+ * Cores supported: e5500, e6500, e500mc
+ * Ref: Load-on-Store Collision Avoidance by Software Stall of Load. James Yang. May 18, 2010
+
+ Rev2:
+ * Scheduler is switched off at -O0. Re-work the test case.
+
+diff -Naur gcc-4.8.3/gcc/common.opt gcc-4.8.3-load-on-store-bypass/gcc/common.opt
+--- gcc-4.8.3/gcc/common.opt	2013-03-14 04:13:36.000000000 -0500
++++ gcc-4.8.3-load-on-store-bypass/gcc/common.opt	2014-09-12 05:06:22.086156403 -0500
+@@ -889,6 +889,10 @@
+ Common Report Var(flag_btr_bb_exclusive) Optimization
+ Restrict target load migration not to re-use registers in any basic block
+ 
++fbypass-load-on-store
++Common Report Var(flag_bypass_load_on_store) Optimization
++Bypass load on store collision
++
+ fcall-saved-
+ Common Joined RejectNegative Var(common_deferred_options) Defer
+ -fcall-saved-<register>	Mark <register> as being preserved across functions
+diff -Naur gcc-4.8.3/gcc/config/rs6000/e500mc64.md gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e500mc64.md
+--- gcc-4.8.3/gcc/config/rs6000/e500mc64.md	2013-01-10 14:38:27.000000000 -0600
++++ gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e500mc64.md	2014-09-12 05:06:22.087156402 -0500
+@@ -189,3 +189,5 @@
+   (and (eq_attr "type" "ddiv")
+        (eq_attr "cpu" "ppce500mc64"))
+   "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*34")
++
++(define_bypass 15 "e500mc64_store" "e500mc64_load" "rs6000_bypass_load_on_store_collision_p")
+diff -Naur gcc-4.8.3/gcc/config/rs6000/e500mc.md gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e500mc.md
+--- gcc-4.8.3/gcc/config/rs6000/e500mc.md	2013-01-10 14:38:27.000000000 -0600
++++ gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e500mc.md	2014-09-12 05:06:22.088156403 -0500
+@@ -198,3 +198,5 @@
+   (and (eq_attr "type" "ddiv")
+        (eq_attr "cpu" "ppce500mc"))
+   "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*65")
++
++(define_bypass 15 "e500mc_store" "e500mc_load" "rs6000_bypass_load_on_store_collision_p")
+diff -Naur gcc-4.8.3/gcc/config/rs6000/e5500.md gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e5500.md
+--- gcc-4.8.3/gcc/config/rs6000/e5500.md	2013-01-10 14:38:27.000000000 -0600
++++ gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e5500.md	2014-09-12 05:06:22.088156403 -0500
+@@ -174,3 +174,5 @@
+   (and (eq_attr "type" "cr_logical,delayed_cr")
+        (eq_attr "cpu" "ppce5500"))
+   "e5500_decode,e5500_bu")
++
++(define_bypass 15 "e5500_store" "e5500_load" "rs6000_bypass_load_on_store_collision_p")
+diff -Naur gcc-4.8.3/gcc/config/rs6000/e6500.md gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e6500.md
+--- gcc-4.8.3/gcc/config/rs6000/e6500.md	2013-01-10 14:38:27.000000000 -0600
++++ gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/e6500.md	2014-09-12 05:06:22.089156405 -0500
+@@ -211,3 +211,5 @@
+   (and (eq_attr "type" "vecperm")
+        (eq_attr "cpu" "ppce6500"))
+   "e6500_decode,e6500_vecperm")
++
++(define_bypass 15 "e6500_store" "e6500_load" "rs6000_bypass_load_on_store_collision_p")
+diff -Naur gcc-4.8.3/gcc/config/rs6000/rs6000.c gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/rs6000.c
+--- gcc-4.8.3/gcc/config/rs6000/rs6000.c	2014-05-04 21:18:35.000000000 -0500
++++ gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/rs6000.c	2014-09-12 05:06:22.092156403 -0500
+@@ -33045,3 +33045,20 @@
+ struct gcc_target targetm = TARGET_INITIALIZER;
+ 
+ #include "gt-rs6000.h"
++
++bool
++rs6000_bypass_load_on_store_collision_p (rtx out_insn, rtx in_insn)
++{
++  /* The out_insn is a store and the in_insn is a load */
++  if (flag_bypass_load_on_store &&
++      (GET_CODE (PATTERN (out_insn)) == SET &&
++       GET_CODE (SET_DEST (PATTERN (out_insn))) == MEM &&
++       GET_CODE (SET_SRC (PATTERN (out_insn))) == REG) &&
++      (GET_CODE (PATTERN (in_insn)) == SET &&
++       GET_CODE (SET_DEST (PATTERN (in_insn))) == REG &&
++       GET_CODE (SET_SRC (PATTERN (in_insn))) == MEM))
++    return rtx_equal_p (SET_DEST (PATTERN (out_insn)),
++                        SET_SRC  (PATTERN (in_insn)));
++  else
++    return false;
++}
+diff -Naur gcc-4.8.3/gcc/config/rs6000/rs6000-protos.h gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/rs6000-protos.h
+--- gcc-4.8.3/gcc/config/rs6000/rs6000-protos.h	2014-04-04 10:10:24.000000000 -0500
++++ gcc-4.8.3-load-on-store-bypass/gcc/config/rs6000/rs6000-protos.h	2014-09-12 05:06:22.092156403 -0500
+@@ -193,6 +193,8 @@
+ extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
+ extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void);
+ 
++extern bool rs6000_bypass_load_on_store_collision_p (rtx out_insn, rtx in_insn);
++
+ /* Declare functions in rs6000-c.c */
+ 
+ extern void rs6000_pragma_longcall (struct cpp_reader *);
+diff -Naur gcc-4.8.3/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c gcc-4.8.3-load-on-store-bypass/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c
+--- gcc-4.8.3/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.8.3-load-on-store-bypass/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c	2014-09-13 08:41:43.089145373 -0500
+@@ -0,0 +1,27 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
++/* { dg-options "-O3 -fbypass-load-on-store -fdump-rtl-sched1 -fdump-rtl-sched2 -fsched-verbose=2" } */
++
++void nescaf(void)
++{
++
++	extern long a, b, c, d, e, f;
++	volatile long z, w;
++
++	a = 41; b = 79; c = 20; d = 11; e = 12; f = 100;
++
++	/* Now, we have a store followed by a load. The assignments to a-t are
++	 * all independent of the store-load computation below. The question is:
++	 * Under -fschedule-insns -fbypass-load-on-store, are 14 of the above
++	 * instructions moved between the store-load?
++	 */
++	z = 121;
++	w = z;
++}
++
++/* Note: There is going to be exactly one insn that will be assigned cost 15.
++ *       Since its insn-number will likely change, we do not include the insn
++ *       number in the scan - just the part of the dump that'll be invariant.
++ */
++/* { dg-final { scan-rtl-dump "into queue with cost=15" "sched1" { target powerpc*-*-* } } } */
++/* { dg-final { cleanup-rtl-dump "sched*" } } */
diff --git a/recipes-devtools/gcc/gcc-4.9/0021-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch b/recipes-devtools/gcc/gcc-4.9/0021-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch
new file mode 100644
index 0000000..eb3c61f
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0021-gcc-disable-MASK_RELAX_PIC_CALLS-bit.patch
@@ -0,0 +1,59 @@
+From 004696e054ae9dc71d512cc755ccc4074fc62b2d Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:14:20 +0400
+Subject: [PATCH 21/35] gcc: disable MASK_RELAX_PIC_CALLS bit
+
+The new feature added after 4.3.3
+"http://www.pubbs.net/200909/gcc/94048-patch-add-support-for-rmipsjalr.html"
+will cause cc1plus eat up all the system memory when build webkit-gtk.
+The function mips_get_pic_call_symbol keeps on recursively calling itself.
+Disable this feature to walk aside the bug.
+
+Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [configuration]
+---
+ gcc/configure    |    7 -------
+ gcc/configure.ac |    7 -------
+ 2 files changed, 14 deletions(-)
+
+diff --git a/gcc/configure b/gcc/configure
+index b65d21d..bdab45a 100755
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -25829,13 +25829,6 @@ $as_echo_n "checking assembler and linker for explicit JALR relocation... " >&6;
+         rm -f conftest.*
+       fi
+     fi
+-    if test $gcc_cv_as_ld_jalr_reloc = yes; then
+-      if test x$target_cpu_default = x; then
+-        target_cpu_default=MASK_RELAX_PIC_CALLS
+-      else
+-        target_cpu_default="($target_cpu_default)|MASK_RELAX_PIC_CALLS"
+-      fi
+-    fi
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ld_jalr_reloc" >&5
+ $as_echo "$gcc_cv_as_ld_jalr_reloc" >&6; }
+ 
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index e226b85..5f5c909 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -4099,13 +4099,6 @@ x:
+         rm -f conftest.*
+       fi
+     fi
+-    if test $gcc_cv_as_ld_jalr_reloc = yes; then
+-      if test x$target_cpu_default = x; then
+-        target_cpu_default=MASK_RELAX_PIC_CALLS
+-      else
+-        target_cpu_default="($target_cpu_default)|MASK_RELAX_PIC_CALLS"
+-      fi
+-    fi
+     AC_MSG_RESULT($gcc_cv_as_ld_jalr_reloc)
+ 
+     AC_CACHE_CHECK([linker for .eh_frame personality relaxation],
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0021.gcc.fix_constvector.patch b/recipes-devtools/gcc/gcc-4.9/0021.gcc.fix_constvector.patch
new file mode 100644
index 0000000..297aee6
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0021.gcc.fix_constvector.patch
@@ -0,0 +1,43 @@
+For altivec targets, 32 bits, the spec2k-gap bmk does not build.  The
+reason is that at some point the vectorizer creates an CONST_VECTOR
+rtl, where the elements are SYMBOL_REFs.
+
+Gcc ICE on simplify_immed_subreg, where it checks that CONST_VECTORS
+can be only made of CONST_INT, CONST_DOUBLE, or CONST_FIXED.
+
+I really don't understand what that function does, but since the
+vectorizer will bailout later anyway, I think it is safe to treat
+SYMBOL_REFs as CONST_INT. (NOT for FSF submission, as I really don't
+have a clue)
+
+This problem does not exists on gcc-4.5
+
+This problem does not exists on 64 bits, since there is no altivec
+type that can support 64bit elements.
+
+Here is a simplified test case:
+
+typedef void f_t (void);
+extern f_t f;
+extern f_t *A[12];
+extern f_t *B[12];
+void bad_vector ()
+{                                                                                                                                                    
+  int i;                                                                                                                                             
+                                                                                                                                                     
+  for (i = 0; i < 12; i++ ) {                                                                                                                        
+    A[i] = f;                                                                                                                                        
+    B[i] = f;                                                                                                                                        
+  }                                                                                                                                                  
+}                                                                                                                                                    
+
+--- gcc-4.6.2/gcc/simplify-rtx.c~	2011-12-28 12:28:01.700039002 -0600
++++ gcc-4.6.2/gcc/simplify-rtx.c	2011-12-28 12:38:22.287039002 -0600
+@@ -5001,6 +5001,7 @@
+       switch (GET_CODE (el))
+ 	{
+ 	case CONST_INT:
++        case SYMBOL_REF:
+ 	  for (i = 0;
+ 	       i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
+ 	       i += value_bit)
diff --git a/recipes-devtools/gcc/gcc-4.9/0022-COLLECT_GCC_OPTIONS.patch b/recipes-devtools/gcc/gcc-4.9/0022-COLLECT_GCC_OPTIONS.patch
new file mode 100644
index 0000000..40c8abf
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0022-COLLECT_GCC_OPTIONS.patch
@@ -0,0 +1,38 @@
+From 7f5c9dcc71c8b83a0b5596266cc4bdf0936e8e00 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:16:28 +0400
+Subject: [PATCH 22/35] COLLECT_GCC_OPTIONS
+
+This patch adds --sysroot into COLLECT_GCC_OPTIONS which is used to
+invoke collect2.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/gcc.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/gcc/gcc.c b/gcc/gcc.c
+index 477752f..51062aa 100644
+--- a/gcc/gcc.c
++++ b/gcc/gcc.c
+@@ -4098,6 +4098,15 @@ set_collect_gcc_options (void)
+ 		sizeof ("COLLECT_GCC_OPTIONS=") - 1);
+ 
+   first_time = TRUE;
++#ifdef HAVE_LD_SYSROOT
++  if (target_system_root_changed && target_system_root)
++    {
++      obstack_grow (&collect_obstack, "'--sysroot=", sizeof("'--sysroot=")-1);
++      obstack_grow (&collect_obstack, target_system_root,strlen(target_system_root));
++      obstack_grow (&collect_obstack, "'", 1);
++      first_time = FALSE;
++    }
++#endif
+   for (i = 0; (int) i < n_switches; i++)
+     {
+       const char *const *args;
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0022.gcc.fix_pr63908_unwind_info.patch b/recipes-devtools/gcc/gcc-4.9/0022.gcc.fix_pr63908_unwind_info.patch
new file mode 100644
index 0000000..4fe4f2e
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0022.gcc.fix_pr63908_unwind_info.patch
@@ -0,0 +1,170 @@
+# Problem Statement:
+  [e500v2] "float_bessel"case failed on e500v2 platforms.
+  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63908
+  https://bugzilla.yoctoproject.org/show_bug.cgi?id=6824
+
+# Owned By:
+  Patch referred from Lei Maohui
+  https://bugzilla.yoctoproject.org/attachment.cgi?id=2314
+
+diff --git a/gcc/defaults.h b/gcc/defaults.h
+index f94ae17..80a798f 100644
+--- a/gcc/defaults.h
++++ b/gcc/defaults.h
+@@ -438,6 +438,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ #define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
+ #endif
+ 
++/* The mapping from dwarf CFA reg number to internal dwarf reg numbers.  */
++#ifndef DWARF_REG_TO_UNWIND_COLUMN
++#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
++#endif
++
+ /* Map register numbers held in the call frame info that gcc has
+    collected using DWARF_FRAME_REGNUM to those that should be output in
+    .debug_frame and .eh_frame.  */
+diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
+index abcdeb3..4e59dfe 100644
+--- a/gcc/dwarf2cfi.c
++++ b/gcc/dwarf2cfi.c
+@@ -252,7 +252,60 @@ init_return_column_size (enum machine_mode mode, rtx mem, unsigned int c)
+ 		  gen_int_mode (size, mode));
+ }
+ 
+-/* Generate code to initialize the register size table.  */
++/* Datastructure used by expand_builtin_init_dwarf_reg_sizes and
++   init_one_dwarf_reg_size to communicate on what has been done by the
++   latter.  */
++
++typedef struct
++{
++  /* Whether the dwarf return column was initialized.  */
++  bool wrote_return_column;
++
++  /* For each hard register REGNO, whether init_one_dwarf_reg_size
++     was given REGNO to process already.  */
++  bool processed_regno [FIRST_PSEUDO_REGISTER];
++
++} init_one_dwarf_reg_state;
++
++/* Helper for expand_builtin_init_dwarf_reg_sizes.  Generate code to
++   initialize the dwarf register size table entry corresponding to register
++   REGNO in REGMODE.  TABLE is the table base address, SLOTMODE is the mode to
++   use for the size entry to initialize, and INIT_STATE is the communication
++   datastructure conveying what we're doing to our caller.  */
++
++static
++void init_one_dwarf_reg_size (int regno, machine_mode regmode,
++                             rtx table, machine_mode slotmode,
++                             init_one_dwarf_reg_state *init_state)
++{
++  const unsigned int dnum = DWARF_FRAME_REGNUM (regno);
++  const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
++  const unsigned int dcol = DWARF_REG_TO_UNWIND_COLUMN (rnum);
++
++  const HOST_WIDE_INT slotoffset = dcol * GET_MODE_SIZE (slotmode);
++  const HOST_WIDE_INT regsize = GET_MODE_SIZE (regmode);
++
++  init_state->processed_regno[regno] = true;
++
++  if (rnum >= DWARF_FRAME_REGISTERS)
++    return;
++
++  if (dnum == DWARF_FRAME_RETURN_COLUMN)
++    {
++      if (regmode == VOIDmode)
++       return;
++      init_state->wrote_return_column = true;
++    }
++
++  if (slotoffset < 0)
++    return;
++
++  emit_move_insn (adjust_address (table, slotmode, slotoffset),
++                 gen_int_mode (regsize, slotmode));
++}
++
++/* Generate code to initialize the dwarf register size table located
++   at the provided ADDRESS.  */
+ 
+ void
+ expand_builtin_init_dwarf_reg_sizes (tree address)
+@@ -261,37 +314,41 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
+   enum machine_mode mode = TYPE_MODE (char_type_node);
+   rtx addr = expand_normal (address);
+   rtx mem = gen_rtx_MEM (BLKmode, addr);
+-  bool wrote_return_column = false;
++
++  init_one_dwarf_reg_state init_state;
++  memset ((char *)&init_state, 0, sizeof (init_state));
+ 
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+-      unsigned int dnum = DWARF_FRAME_REGNUM (i);
+-      unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
++      machine_mode save_mode;
++      rtx span;
+ 
+-      if (rnum < DWARF_FRAME_REGISTERS)
+-	{
+-	  HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (mode);
+-	  enum machine_mode save_mode = reg_raw_mode[i];
+-	  HOST_WIDE_INT size;
++      /* No point in processing a register multiple times.  This could happen
++         with register spans, e.g. when a reg is first processed as a piece of
++         a span, then as a register on its own later on.  */
+ 
+-	  if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
+-	    save_mode = choose_hard_reg_mode (i, 1, true);
+-	  if (dnum == DWARF_FRAME_RETURN_COLUMN)
+-	    {
+-	      if (save_mode == VOIDmode)
+-		continue;
+-	      wrote_return_column = true;
+-	    }
+-	  size = GET_MODE_SIZE (save_mode);
+-	  if (offset < 0)
+-	    continue;
++      if (init_state.processed_regno[i])
++        continue;
+ 
+-	  emit_move_insn (adjust_address (mem, mode, offset),
+-			  gen_int_mode (size, mode));
++      save_mode = reg_raw_mode[i];
++      if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
++        save_mode = choose_hard_reg_mode (i, 1, true);
++
++      span = targetm.dwarf_register_span (gen_rtx_REG (save_mode, i));
++      if (!span)
++        init_one_dwarf_reg_size (i, save_mode, mem, mode, &init_state);
++      else
++        {
++           for (int si = 0; si < XVECLEN (span, 0); si++)
++	    {
++               rtx reg = XVECEXP (span, 0, si);
++               init_one_dwarf_reg_size
++                 (REGNO (reg), GET_MODE (reg), mem, mode, &init_state);
++            }
+ 	}
+     }
+ 
+-  if (!wrote_return_column)
++  if (!init_state.wrote_return_column)
+     init_return_column_size (mode, mem, DWARF_FRAME_RETURN_COLUMN);
+ 
+ #ifdef DWARF_ALT_FRAME_RETURN_COLUMN
+diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
+index 55fc4bc..37f0ae2 100644
+--- a/libgcc/unwind-dw2.c
++++ b/libgcc/unwind-dw2.c
+@@ -55,10 +55,6 @@
+ #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
+ #endif
+ 
+-#ifndef DWARF_REG_TO_UNWIND_COLUMN
+-#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
+-#endif
+-
+ /* ??? For the public function interfaces, we tend to gcc_assert that the
+    column numbers are in range.  For the dwarf2 unwind info this does happen,
+    although so far in a case that doesn't actually matter.
diff --git a/recipes-devtools/gcc/gcc-4.9/0023-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch b/recipes-devtools/gcc/gcc-4.9/0023-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch
new file mode 100644
index 0000000..fddfe9e
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0023-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch
@@ -0,0 +1,96 @@
+From f7d49ca445e60faa1b5256c6b4f96c1ee5c0e353 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:17:25 +0400
+Subject: [PATCH 23/35] Use the defaults.h in ${B} instead of ${S}, and t-oe
+ in ${B}
+
+Use the defaults.h in ${B} instead of ${S}, and t-oe in ${B}, so that
+the source can be shared between gcc-cross-initial,
+gcc-cross-intermediate, gcc-cross, gcc-runtime, and also the sdk build.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+
+While compiling gcc-crosssdk-initial-x86_64 on some host, there is
+occasionally failure that test the existance of default.h doesn't
+work, the reason is tm_include_list='** defaults.h' rather than
+tm_include_list='** ./defaults.h'
+
+So we add the test condition for this situation.
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ gcc/Makefile.in  |    2 +-
+ gcc/configure    |    4 ++--
+ gcc/configure.ac |    4 ++--
+ gcc/mkconfig.sh  |    4 ++--
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/gcc/Makefile.in b/gcc/Makefile.in
+index d1ab22f..15fe4b6 100644
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -483,7 +483,7 @@ TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT@
+ TARGET_SYSTEM_ROOT_DEFINE = @TARGET_SYSTEM_ROOT_DEFINE@
+ 
+ xmake_file=@xmake_file@
+-tmake_file=@tmake_file@
++tmake_file=@tmake_file@ ./t-oe
+ TM_ENDIAN_CONFIG=@TM_ENDIAN_CONFIG@
+ TM_MULTILIB_CONFIG=@TM_MULTILIB_CONFIG@
+ TM_MULTILIB_EXCEPTIONS_CONFIG=@TM_MULTILIB_EXCEPTIONS_CONFIG@
+diff --git a/gcc/configure b/gcc/configure
+index 5399b2b..60a04bd 100755
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -11631,8 +11631,8 @@ for f in $tm_file; do
+        tm_include_list="${tm_include_list} $f"
+        ;;
+     defaults.h )
+-       tm_file_list="${tm_file_list} \$(srcdir)/$f"
+-       tm_include_list="${tm_include_list} $f"
++       tm_file_list="${tm_file_list} ./$f"
++       tm_include_list="${tm_include_list} ./$f"
+        ;;
+     * )
+        tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index f87c3b6..460e0d9 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -1740,8 +1740,8 @@ for f in $tm_file; do
+        tm_include_list="${tm_include_list} $f"
+        ;;
+     defaults.h )
+-       tm_file_list="${tm_file_list} \$(srcdir)/$f"
+-       tm_include_list="${tm_include_list} $f"
++       tm_file_list="${tm_file_list} ./$f"
++       tm_include_list="${tm_include_list} ./$f"
+        ;;
+     * )
+        tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+diff --git a/gcc/mkconfig.sh b/gcc/mkconfig.sh
+index c7146ed..b153f45 100644
+--- a/gcc/mkconfig.sh
++++ b/gcc/mkconfig.sh
+@@ -77,7 +77,7 @@ if [ -n "$HEADERS" ]; then
+     if [ $# -ge 1 ]; then
+ 	echo '#ifdef IN_GCC' >> ${output}T
+ 	for file in "$@"; do
+-	    if test x"$file" = x"defaults.h"; then
++	    if test x"$file" = x"./defaults.h" -o x"$file" = x"defaults.h"; then
+ 		postpone_defaults_h="yes"
+ 	    else
+ 		echo "# include \"$file\"" >> ${output}T
+@@ -106,7 +106,7 @@ esac
+ 
+ # If we postponed including defaults.h, add the #include now.
+ if test x"$postpone_defaults_h" = x"yes"; then
+-    echo "# include \"defaults.h\"" >> ${output}T
++    echo "# include \"./defaults.h\"" >> ${output}T
+ fi
+ 
+ # Add multiple inclusion protection guard, part two.
+-- 
+1.9.1
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0023.gcc.fix_pr60158_fixup_table.patch b/recipes-devtools/gcc/gcc-4.9/0023.gcc.fix_pr60158_fixup_table.patch
new file mode 100644
index 0000000..e882f94
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0023.gcc.fix_pr60158_fixup_table.patch
@@ -0,0 +1,121 @@
+[gcc]
+2014-04-22  Rohit  <rohitarulraj@freescale.com>
+
+    PR target/60158
+    * varasm.c (output_constant_pool_1): Pass actual alignment value to output_constant_pool_2
+    to emit ".fixup" section.
+
+[gcc/testsuite]
+2014-04-22  Rohit  <rohitarulraj@freescale.com>
+
+    PR target/60158
+    * gcc.target/powerpc/pr60158.c: New test.  Check if ".fixup" section gets emitted for
+    ".data.rel.ro.local" section.
+
+diff -Naur gcc-4.8.2/gcc/testsuite/gcc.target/powerpc/pr60158.c gcc-4.8.2-pr60158/gcc/testsuite/gcc.target/powerpc/pr60158.c
+--- gcc-4.8.2/gcc/testsuite/gcc.target/powerpc/pr60158.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.8.2-pr60158/gcc/testsuite/gcc.target/powerpc/pr60158.c	2014-04-28 13:24:53.659403486 -0500
+@@ -0,0 +1,91 @@
++/* { dg-do compile } */
++/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
++/* { dg-options "-mcpu=8548 -mno-spe -mfloat-gprs=double -Os -fdata-sections -fpic -mrelocatable" } */
++
++#define NULL 0
++int func (int val);
++void *func2 (void *ptr);
++
++static const char *ifs;
++static char map[256];
++
++typedef struct {
++/*
++ * None of these fields are used, but removing any
++ * of them makes the problem go away.
++ */
++  char *data;
++  int length;
++  int maxlen;
++  int quote;
++} o_string;
++
++#define NULL_O_STRING {NULL,0,0,0}
++
++static int parse_stream (void *dest, void *ctx)
++{
++  int ch = func (0), m;
++
++  while (ch != -1) {
++    m = map[ch];
++    if (ch != '\n')
++    func2(dest);
++
++    ctx = func2 (ctx);
++    if (!func (0))
++      return 0;
++    if (m != ch) {
++      func2 ("htns");
++      break;
++    }
++  }
++  return -1;
++}
++
++static void mapset (const char *set, int code)
++{
++  const char *s;
++  for (s=set; *s; s++)  map[(int)*s] = code;
++}
++
++static void update_ifs_map(void)
++{
++  /* char *ifs and char map[256] are both globals. */
++  ifs = func2 ("abc");
++  if (ifs == NULL) ifs="def";
++
++  func2 (map);
++  {
++    char subst[2] = {4, 0};
++    mapset (subst, 3);
++  }
++  mapset (";&|#", 1);
++}
++
++int parse_stream_outer (int flag)
++{
++  int blah;
++  o_string temp=NULL_O_STRING;
++  int rcode;
++
++  do {
++    update_ifs_map ();
++    func2 (&blah); /* a memory clobber works as well */
++    rcode = parse_stream (&temp, NULL);
++    func2 ("aoeu");
++    if (func (0) != 0) {
++      func2 (NULL);
++    }
++  } while (rcode != -1);
++  return 0;
++}
++
++/* { dg-final { if ![file exists pr60158.s] { fail "pr60158.c (compile)"; return; } } } */
++
++/* { dg-final { set c_rel [llength [grep pr60158.s \\.data\\.rel\\.ro\\.local]] } } */
++/* { dg-final { set c_fix [llength [grep pr60158.s \\.fixup]] } } */
++/* { dg-final { if [string match $c_rel $c_fix] \{                     } } */
++/* { dg-final {     pass "pr60158.c (passed)"  } } */
++/* { dg-final { \} else \{                                     } } */
++/* { dg-final {     fail "pr60158.c (.fixup table entries not generated for .data.rel.ro.local section)"       } } */
++/* { dg-final { \}                                              } } */
+diff -Naur gcc-4.8.2/gcc/varasm.c gcc-4.8.2-pr60158/gcc/varasm.c
+--- gcc-4.8.2/gcc/varasm.c	2013-05-09 20:54:06.000000000 -0500
++++ gcc-4.8.2-pr60158/gcc/varasm.c	2014-04-28 12:37:38.606372451 -0500
+@@ -3771,7 +3771,7 @@
+   targetm.asm_out.internal_label (asm_out_file, "LC", desc->labelno);
+ 
+   /* Output the data.  */
+-  output_constant_pool_2 (desc->mode, x, align);
++  output_constant_pool_2 (desc->mode, x, desc->align);
+ 
+   /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS
+      sections have proper size.  */
diff --git a/recipes-devtools/gcc/gcc-4.9/0024-PR-target-32219.patch b/recipes-devtools/gcc/gcc-4.9/0024-PR-target-32219.patch
new file mode 100644
index 0000000..45acf7f
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0024-PR-target-32219.patch
@@ -0,0 +1,62 @@
+From e0d15f4f8bf28c351b9215ca37f1caa24df0e1fd Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:18:54 +0400
+Subject: [PATCH 24/35] PR target/32219
+
+* varasm.c (default_binds_local_p_1): Weak data is not local.
+
+Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Backport
+---
+ gcc/testsuite/gcc.dg/visibility-21.c |   14 ++++++++++++++
+ gcc/varasm.c                         |    9 ++++-----
+ 2 files changed, 18 insertions(+), 5 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.dg/visibility-21.c
+
+Index: gcc-4.9-20140316/gcc/varasm.c
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/varasm.c
++++ gcc-4.9-20140316/gcc/varasm.c
+@@ -6771,6 +6771,10 @@ default_binds_local_p_1 (const_tree exp,
+   /* Static variables are always local.  */
+   else if (! TREE_PUBLIC (exp))
+     local_p = true;
++  /* hidden weak can't be overridden by something non-local, all
++     that is possible is that it is not defined at all. */
++  else if (DECL_WEAK (exp))
++    local_p = false;
+   /* A variable is local if the user has said explicitly that it will
+      be.  */
+   else if ((DECL_VISIBILITY_SPECIFIED (exp)
+@@ -6784,11 +6788,6 @@ default_binds_local_p_1 (const_tree exp,
+      local.  */
+   else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
+     local_p = true;
+-  /* Default visibility weak data can be overridden by a strong symbol
+-     in another module and so are not local.  */
+-  else if (DECL_WEAK (exp)
+-	   && !resolved_locally)
+-    local_p = false;
+   /* If PIC, then assume that any global name can be overridden by
+      symbols resolved from other modules.  */
+   else if (shlib)
+Index: gcc-4.9-20140316/gcc/testsuite/gcc.dg/visibility-22.c
+===================================================================
+--- /dev/null
++++ gcc-4.9-20140316/gcc/testsuite/gcc.dg/visibility-22.c
+@@ -0,0 +1,13 @@
++/* PR target/32219 */
++/* { dg-do run } */
++/* { dg-require-visibility "" } */
++/* { dg-options "-fPIC" { target fpic } } */
++
++extern void f() __attribute__((weak,visibility("hidden")));
++extern int puts( char const* );
++int main()
++{
++  if (f)
++    f();
++  return 0;
++}
diff --git a/recipes-devtools/gcc/gcc-4.9/0024.gcc.have-pre-modify-disp-support-49x.patch b/recipes-devtools/gcc/gcc-4.9/0024.gcc.have-pre-modify-disp-support-49x.patch
new file mode 100644
index 0000000..6362f62
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0024.gcc.have-pre-modify-disp-support-49x.patch
@@ -0,0 +1,1078 @@
+
+ This patch implements -fuse-load-updates
+
+ Prior to this patch, GCC will only combine a load/store and unit-increment into a
+ load/store with update instruction. This patch adds support for the generation of
+ {load, store}-with-update instructions past non-unit increments.
+
+ -fuse-load-updates is ON by default for 64-bit and OFF by default for 32-bit
+
+ Cores supported: e5500, e6500, e500mc
+
+diff -Naur gcc-4.9.1/gcc/common.opt gcc-4.9.1-pre-modify-disp-support/gcc/common.opt
+--- gcc-4.9.1/gcc/common.opt	2014-08-13 01:25:45.156015000 -0500
++++ gcc-4.9.1-pre-modify-disp-support/gcc/common.opt	2014-08-13 01:30:08.579014919 -0500
+@@ -2288,6 +2288,14 @@
+ fuse-linker-plugin
+ Common Undocumented Var(flag_use_linker_plugin)
+ 
++; Initialize flag_use_load_updates to -1
++; That way, it gets set to 1 on -fuse-load-updates and to 0 on -fno-use-load-updates
++; when these options are explicitly used by the user. This helps us default it to ON
++; on 64-bit and OFF in 32-bit
++fuse-load-updates
++Common Report Var(flag_use_load_updates) Init(-1) Optimization
++Support generation of {load, store}-with-update instructions past non-unit increments
++
+ ; Positive if we should track variables, negative if we should run
+ ; the var-tracking pass only to discard debug annotations, zero if
+ ; we're not to run it.  When flag_var_tracking == 2 (AUTODETECT_VALUE) it
+diff -Naur gcc-4.9.1/gcc/config/rs6000/rs6000.c gcc-4.9.1-pre-modify-disp-support/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.1/gcc/config/rs6000/rs6000.c	2014-08-13 01:25:45.210015000 -0500
++++ gcc-4.9.1-pre-modify-disp-support/gcc/config/rs6000/rs6000.c	2014-08-13 01:30:08.587015007 -0500
+@@ -4071,6 +4071,12 @@
+   if (TARGET_LINK_STACK == -1)
+     SET_TARGET_LINK_STACK (rs6000_cpu == PROCESSOR_PPC476 && flag_pic);
+ 
++  /* If the user has not specified -fuse-load-updates nor -fno-use-load-updates
++   * in 64-bit, default to -fuse-load-updates
++   */
++  if (flag_use_load_updates == -1 && TARGET_64BIT)
++    flag_use_load_updates = 1;
++
+   return ret;
+ }
+ 
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-10.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-10.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-10.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-10.c	2014-08-13 01:32:01.827015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m) {
++
++		s += 2;
++		m += 2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-11.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-11.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-11.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-11.c	2014-08-13 01:32:01.827015000 -0500
+@@ -0,0 +1,16 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-12.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-12.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-12.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-12.c	2014-08-13 01:32:01.827015000 -0500
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-13.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-13.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-13.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-13.c	2014-08-13 01:32:01.827015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++		m += 2;
++	}
++
++	baz(s, m, end);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-14.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-14.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-14.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-14.c	2014-08-13 01:32:01.827015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++		m += 2;
++	}
++
++	baz(s, m, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-15.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-15.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-15.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-15.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *p, char *s);
++
++void foo(char *p, char *q, char *r, char *s)
++{
++        while (*p == *q && *p == *r && p < s) {
++
++		p += 2;
++		q += 2;
++		r += 2;
++	}
++
++	baz(p, s);
++}
++
++/* { dg-final { scan-assembler-times "addi" 0 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 3 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-16.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-16.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-16.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-16.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *p, char *s);
++
++void foo(char *p, char *q, char *r, char *s)
++{
++        while (*p == *q && *p == *r && p < s) {
++
++		p += 2;
++		q += 2;
++		r += 2;
++	}
++
++	baz(p, s);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 3 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-17.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-17.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-17.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-17.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *p, char *s);
++
++void foo(char *p, char *q, char *r, char *s)
++{
++        while (*p == *q && *p == *r && p < s) {
++
++		p += 2;
++		q += 3;
++		r += 7;
++	}
++
++	baz(p, s);
++}
++
++/* { dg-final { scan-assembler-times "addi" 0 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 3 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-18.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-18.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-18.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-18.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *p, char *s);
++
++void foo(char *p, char *q, char *r, char *s)
++{
++        while (*p == *q && *p == *r && p < s) {
++
++		p += 2;
++		q += 3;
++		r += 7;
++	}
++
++	baz(p, s);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 3 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-19.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-19.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-19.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-19.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,21 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *p, char *s);
++
++void foo(char *p, char *q, char *r, char *s)
++{
++        while (*p && *q && *r && *s &&
++               *p == *q && *p == *r && *p == *s &&
++               *q == *r && *q == *s &&
++               *r == *s) {
++
++		p += 1;
++		q += 1;
++		r += 1;
++		s += 1;
++	}
++}
++
++/* { dg-final { scan-assembler-times "addi" 0 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 4 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-1.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-1.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-1.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-1.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++		m += 2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-20.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-20.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-20.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-20.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,21 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *p, char *s);
++
++void foo(char *p, char *q, char *r, char *s)
++{
++        while (*p && *q && *r && *s &&
++               *p == *q && *p == *r && *p == *s &&
++               *q == *r && *q == *s &&
++               *r == *s) {
++
++		p += 1;
++		q += 1;
++		r += 1;
++		s += 1;
++	}
++}
++
++/* { dg-final { scan-assembler-times "addi" 0 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 4 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-21.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-21.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-21.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-21.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(int *s, int *m, int *end);
++
++void foo(int *s, int *m, int *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 1;
++		m += 1;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lwzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-22.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-22.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-22.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-22.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(int *s, int *m, int *end);
++
++void foo(int *s, int *m, int *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 1;
++		m += 1;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lwzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-23.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-23.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-23.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-23.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(int *s, int *m, int *end);
++
++void foo(int *s, int *m, int *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 3;
++		m += 3;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lwzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-24.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-24.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-24.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-24.c	2014-08-13 01:32:01.828015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(int *s, int *m, int *end);
++
++void foo(int *s, int *m, int *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 3;
++		m += 3;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lwzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-25.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-25.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-25.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-25.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++		m += 2;
++
++		*s = 0;
++		*m = 0;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-26.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-26.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-26.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-26.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,22 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++		m += 2;
++
++		*s = 0;
++		*m = 0;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-27.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-27.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-27.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-27.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *scan, char *match, char *strend);
++
++void foo(char *scan, char *match, char *strend)
++{
++        while (*scan == *match && scan > strend) {
++
++		scan  += -2;
++		match += -2;
++
++		*scan = 0;
++		*match = 0;
++	}
++
++	baz(scan, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-28.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-28.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-28.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-28.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,22 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *scan, char *match, char *strend);
++
++void foo(char *scan, char *match, char *strend)
++{
++        while (*scan == *match && scan > strend) {
++
++		scan  += -2;
++		match += -2;
++
++		*scan = 0;
++		*match = 0;
++	}
++
++	baz(scan, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-29.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-29.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-29.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-29.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *strend);
++
++void foo(char *s, char *m, char *strend)
++{
++        while (*s == *m && s < strend) {
++
++		s += 2;
++		m -= 2;
++	}
++
++	baz(s, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-2.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-2.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-2.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-2.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 2;
++		m += 2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-30.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-30.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-30.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-30.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *strend);
++
++void foo(char *s, char *m, char *strend)
++{
++        while (*s == *m && s < strend) {
++
++		s += 2;
++		m -= 2;
++	}
++
++	baz(s, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-31.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-31.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-31.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-31.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *scan, char *match, char *strend);
++
++void foo(char *scan, char *match, char *strend)
++{
++        while (*scan == *match && scan < strend) {
++
++		scan  += 1;
++		match += 1;
++
++		*scan = 0;
++		*match = 0;
++	}
++
++	baz(scan, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-32.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-32.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-32.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-32.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,22 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *scan, char *match, char *strend);
++
++void foo(char *scan, char *match, char *strend)
++{
++        while (*scan == *match && scan < strend) {
++
++		scan  += 1;
++		match += 1;
++
++		*scan = 0;
++		*match = 0;
++	}
++
++	baz(scan, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-33.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-33.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-33.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-33.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,20 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *scan, char *match, char *strend);
++
++void foo(char *scan, char *match, char *strend)
++{
++        while (*scan == *match && scan > strend) {
++
++		scan  += -1;
++		match += -1;
++
++		*scan = 0;
++		*match = 0;
++	}
++
++	baz(scan, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-34.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-34.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-34.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-34.c	2014-08-13 01:32:01.829015000 -0500
+@@ -0,0 +1,22 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *scan, char *match, char *strend);
++
++void foo(char *scan, char *match, char *strend)
++{
++        while (*scan == *match && scan > strend) {
++
++		scan  += -1;
++		match += -1;
++
++		*scan = 0;
++		*match = 0;
++	}
++
++	baz(scan, 0, strend);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stbu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-35.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-35.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-35.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-35.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,22 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void foo (char *p, char *q, const char *bound);
++
++void incrBytes(char *p, char *q, const char *bound)
++{
++	while (*p == *q && p < bound) {
++
++		p += 1;
++		*p = *p + 1;
++
++		q += 1;
++		*q = *q+ 1;
++
++	}
++
++	foo (p, 0, bound);
++}
++
++/* { dg-final { scan-assembler-times "addi" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-36.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-36.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-36.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-36.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,23 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void foo (char *p, char *q, const char *bound);
++
++void incrBytes(char *p, char *q, const char *bound)
++{
++	while (*p == *q && p < bound) {
++
++		p += 1;
++		*p = *p + 1;
++
++		q += 1;
++		*q = *q+ 1;
++
++	}
++
++	foo (p, 0, bound);
++}
++
++/* { dg-final { scan-assembler-times "addi" 3 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-37.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-37.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-37.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-37.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,29 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++struct rx {
++ char **startp;
++};
++
++extern int *foo();
++
++int **bar(void)
++{
++ int **sp;
++ int iterations, i;
++ struct rx *rx;
++
++ for (i = i; i <= iterations; i++) {
++
++   ++sp;
++   *sp = foo();
++
++   if (rx->startp[i])
++     gorp();
++ }
++
++ return sp;
++}
++
++/* { dg-final { scan-assembler-times "addi" 3 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stwu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-38.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-38.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-38.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-38.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,29 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++struct rx {
++ char **startp;
++};
++
++extern int *foo();
++
++int **bar(void)
++{
++ int **sp;
++ int iterations, i;
++ struct rx *rx;
++
++ for (i = i; i <= iterations; i++) {
++
++   ++sp;
++   *sp = foo();
++
++   if (rx->startp[i])
++     gorp();
++ }
++
++ return sp;
++}
++
++/* { dg-final { scan-assembler-times "addi" 3 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-39.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-39.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-39.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-39.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates -fno-builtin -fno-tree-loop-optimize" } */
++
++void *memset(void *b, int c, unsigned long len)
++{
++        unsigned long i;
++
++        for (i = 0; i < len; i++)
++                ((unsigned char *)b)[i] = c;
++
++        return b;
++}
++
++/* NOTE: We ought to get at-least one stwu - there is some vector related stuff that
++ *       we need to take into consideration under -fuse-load-updates. With plain
++ *       vanilla GCC, we do get one stwu, so we are actually degrading performance
++ *       by not taking the "vector stuff" into account. */
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-3.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-3.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-3.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-3.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 1;
++		m += 1;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-40.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-40.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-40.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-40.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates -fno-builtin -fno-tree-loop-optimize" } */
++
++void *memset(void *b, int c, unsigned long len)
++{
++        unsigned long i;
++
++        for (i = 0; i < len; i++)
++                ((unsigned char *)b)[i] = c;
++
++        return b;
++}
++
++/* NOTE: We ought to get at-least one stwu - there is some vector related stuff that
++ *       we need to take into consideration under -fuse-load-updates. With plain
++ *       vanilla GCC, we do get one stwu, so we are actually degrading performance
++ *       by not taking the "vector stuff" into account. */
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-4.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-4.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-4.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-4.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += 1;
++		m += 1;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-5.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-5.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-5.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-5.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += -1;
++		m += -1;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-6.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-6.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-6.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-6.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += -1;
++		m += -1;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-7.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-7.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-7.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-7.c	2014-08-13 01:32:01.830015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += -2;
++		m += -2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-8.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-8.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-8.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-8.c	2014-08-13 01:32:01.831015000 -0500
+@@ -0,0 +1,19 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m && s < end) {
++
++		s += -2;
++		m += -2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "addi" 1 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
++/* { dg-final { scan-assembler-times "stdu" 1 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-9.c gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-9.c
+--- gcc-4.9.1/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-9.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.1-pre-modify-disp-support/gcc/testsuite/gcc.dg/tree-ssa/fsl-use-load-updates-9.c	2014-08-13 01:32:01.831015000 -0500
+@@ -0,0 +1,17 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fuse-load-updates" } */
++
++extern void baz(char *s, char *m, char *end);
++
++void foo(char *s, char *m, char *end)
++{
++        while (*s == *m) {
++
++		s += 2;
++		m += 2;
++	}
++
++	baz(s, 0, end);
++}
++
++/* { dg-final { scan-assembler-times "lbzu" 2 { target powerpc*-*-* } } } */
+diff -Naur gcc-4.9.1/gcc/tree-ssa-loop-ivopts.c gcc-4.9.1-pre-modify-disp-support/gcc/tree-ssa-loop-ivopts.c
+--- gcc-4.9.1/gcc/tree-ssa-loop-ivopts.c	2014-08-13 01:25:45.343015000 -0500
++++ gcc-4.9.1-pre-modify-disp-support/gcc/tree-ssa-loop-ivopts.c	2014-08-13 01:30:08.599015000 -0500
+@@ -2390,6 +2390,8 @@
+   return false;
+ }
+ 
++#define WANT_LOAD_UPDATES (flag_use_load_updates == 1)
++
+ /* If possible, adds autoincrement candidates BASE + STEP * i based on use USE.
+    Important field is set to IMPORTANT.  */
+ 
+@@ -2419,7 +2421,10 @@
+        && GET_MODE_SIZE (mem_mode) == cstepi)
+       || ((USE_LOAD_PRE_DECREMENT (mem_mode)
+ 	   || USE_STORE_PRE_DECREMENT (mem_mode))
+-	  && GET_MODE_SIZE (mem_mode) == -cstepi))
++	  && GET_MODE_SIZE (mem_mode) == -cstepi)
++      || (WANT_LOAD_UPDATES && HAVE_PRE_MODIFY_DISP
++	  && (GET_MODE_SIZE (mem_mode) != 0
++	      && cstepi % GET_MODE_SIZE (mem_mode) == 0)))
+     {
+       enum tree_code code = MINUS_EXPR;
+       tree new_base;
+@@ -3213,6 +3218,7 @@
+ {
+   AINC_PRE_INC,		/* Pre increment.  */
+   AINC_PRE_DEC,		/* Pre decrement.  */
++  AINC_PRE_MOD,		/* Pre Modify */
+   AINC_POST_INC,	/* Post increment.  */
+   AINC_POST_DEC,	/* Post decrement.  */
+   AINC_NONE		/* Also the number of auto increment types.  */
+@@ -3239,6 +3245,7 @@
+   address_cost_data data;
+   static bool has_preinc[MAX_MACHINE_MODE], has_postinc[MAX_MACHINE_MODE];
+   static bool has_predec[MAX_MACHINE_MODE], has_postdec[MAX_MACHINE_MODE];
++  static bool has_premod_d[MAX_MACHINE_MODE];
+   unsigned cost, acost, complexity;
+   enum ainc_type autoinc_type;
+   bool offset_p, ratio_p, autoinc;
+@@ -3356,6 +3363,14 @@
+ 	    data->ainc_costs[AINC_POST_INC]
+ 	      = address_cost (addr, mem_mode, as, speed);
+ 	}
++      if (WANT_LOAD_UPDATES && HAVE_PRE_MODIFY_DISP)
++	{
++	  addr = gen_rtx_PRE_MODIFY (address_mode, reg0,
++	                             gen_rtx_PLUS (address_mode, reg0,
++	                                           GEN_INT (cstep)));
++	  has_premod_d[mem_mode]
++	    = memory_address_addr_space_p (mem_mode, addr, as);
++	}
+       for (i = 0; i < 16; i++)
+ 	{
+ 	  sym_p = i & 1;
+@@ -3464,7 +3479,8 @@
+ 	      fprintf (dump_file, "index costs %d\n", acost);
+ 	    }
+ 	  if (has_predec[mem_mode] || has_postdec[mem_mode]
+-	      || has_preinc[mem_mode] || has_postinc[mem_mode])
++	      || has_preinc[mem_mode] || has_postinc[mem_mode]
++	      || (WANT_LOAD_UPDATES && has_premod_d[mem_mode]))
+ 	    fprintf (dump_file, "  May include autoinc/dec\n");
+ 	  fprintf (dump_file, "\n");
+ 	}
+@@ -3501,6 +3517,11 @@
+       else if (has_predec[mem_mode] && autoinc_offset == -msize
+ 	       && msize == -cstep)
+ 	autoinc_type = AINC_PRE_DEC;
++      else if (WANT_LOAD_UPDATES && has_premod_d[mem_mode]
++               && msize != 0
++               && autoinc_offset % msize == 0
++               && cstep % msize == 0)
++	autoinc_type = AINC_PRE_MOD;
+ 
+       if (autoinc_type != AINC_NONE)
+ 	autoinc = true;
+@@ -3521,7 +3542,7 @@
+ 
+   if (may_autoinc)
+     *may_autoinc = autoinc;
+-  if (autoinc)
++  if (autoinc && (autoinc_type != AINC_PRE_MOD))
+     acost = data->ainc_costs[autoinc_type];
+   else
+     acost = data->costs[symbol_present][var_present][offset_p][ratio_p];
diff --git a/recipes-devtools/gcc/gcc-4.9/0025-fortran-cross-compile-hack.patch b/recipes-devtools/gcc/gcc-4.9/0025-fortran-cross-compile-hack.patch
new file mode 100644
index 0000000..0e7914d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0025-fortran-cross-compile-hack.patch
@@ -0,0 +1,46 @@
+From af8a56ea4e17b2909eff2c57704ab43ef24f28d3 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:20:01 +0400
+Subject: [PATCH 25/35] fortran cross-compile hack.
+
+* Fortran would have searched for arm-angstrom-gnueabi-gfortran but would have used
+used gfortan. For gcc_4.2.2.bb we want to use the gfortran compiler from our cross
+directory.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [embedded specific]
+---
+ libgfortran/configure    |    2 +-
+ libgfortran/configure.ac |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libgfortran/configure b/libgfortran/configure
+index 8385e96..b8f7a92 100755
+--- a/libgfortran/configure
++++ b/libgfortran/configure
+@@ -12704,7 +12704,7 @@ esac
+ 
+ # We need gfortran to compile parts of the library
+ #AC_PROG_FC(gfortran)
+-FC="$GFORTRAN"
++#FC="$GFORTRAN"
+ ac_ext=${ac_fc_srcext-f}
+ ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
+index 7d97fed..3f9f484 100644
+--- a/libgfortran/configure.ac
++++ b/libgfortran/configure.ac
+@@ -227,7 +227,7 @@ AC_SUBST(enable_static)
+ 
+ # We need gfortran to compile parts of the library
+ #AC_PROG_FC(gfortran)
+-FC="$GFORTRAN"
++#FC="$GFORTRAN"
+ AC_PROG_FC(gfortran)
+ 
+ # extra LD Flags which are required for targets
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0025.gcc.fix_ENGR00298583_dwarf-vector-reg_49x.patch b/recipes-devtools/gcc/gcc-4.9/0025.gcc.fix_ENGR00298583_dwarf-vector-reg_49x.patch
new file mode 100644
index 0000000..88fb24c
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0025.gcc.fix_ENGR00298583_dwarf-vector-reg_49x.patch
@@ -0,0 +1,113 @@
+# Problem Statement:
+  In Altivec targets (e.g. e6500), DWARF vector register indices for DW_OP_regx
+  locations are not in range. According to "64-bit PowerPC ELF Application
+  Binary Interface Supplement 1.9", DWARF Register Number Mapping section, the
+  expected range for vector registers is:
+                 Vector Registers 0-31 1124-1155 vr0-vr31.
+
+  However, the compiler generates indices in the 77-108 range that overlap with
+  other defined mappings.
+
+# Reported by:
+  Doan Vu Van
+
+# Owned by:
+  Rohit
+
+# Action:
+  While mapping gcc register numbers to DWARF2 register numbers,
+  we digress a bit from the standard ABI.
+  http://gcc.gnu.org/ml/gcc-patches/2012-11/msg02136.html
+
+  The above change is handled by GDB, but CodeWarrior PowerPC debugger
+  stricity follows the ABI especially while mapping the vector registers.
+
+  We have provided an compiler option, '-mmap_dwarf_vecreg' so that the user can
+  generate the dwarf register indexes for vector registers as per standard.
+
+diff -Naur gcc-4.9.2/gcc/config/rs6000/rs6000.c gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.2/gcc/config/rs6000/rs6000.c	2014-10-12 21:33:20.000000000 -0500
++++ gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/rs6000.c	2014-11-06 09:32:31.609217000 -0600
+@@ -31304,6 +31304,22 @@
+   return regno;
+ }
+ 
++/* While mapping gcc register numbers to DWARF2 register numbers, 
++ * we digress a bit from the standard ABI.
++ * http://gcc.gnu.org/ml/gcc-patches/2012-11/msg02136.html
++ *
++ * The above change is handled by GDB, but CodeWarrior PowerPC debugger
++ * stricity follows the ABI especially while mapping the vector registers */
++
++unsigned int
++rs6000_fsl_dbx_register_number (unsigned int regno)
++{
++  if (global_options_set.x_rs6000_map_dwarf_vec_reg)
++    return rs6000_dbx_register_number (regno);
++
++  return regno;
++}
++
+ /* target hook eh_return_filter_mode */
+ static enum machine_mode
+ rs6000_eh_return_filter_mode (void)
+diff -Naur gcc-4.9.2/gcc/config/rs6000/rs6000.opt gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/rs6000.opt
+--- gcc-4.9.2/gcc/config/rs6000/rs6000.opt	2014-01-23 19:56:48.000000000 -0600
++++ gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/rs6000.opt	2014-11-06 09:32:31.610217000 -0600
+@@ -361,6 +361,10 @@
+ Target RejectNegative Joined
+ -mdebug=	Enable debug output
+ 
++mmap_dwarf_vecreg
++Target RejectNegative Var(rs6000_map_dwarf_vec_reg, 0) Save
++Generate expected DWARF Register Number Mapping for Vector Registers 
++
+ mabi=altivec
+ Target RejectNegative Var(rs6000_altivec_abi) Save
+ Use the AltiVec ABI extensions
+diff -Naur gcc-4.9.2/gcc/config/rs6000/rs6000-protos.h gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/rs6000-protos.h
+--- gcc-4.9.2/gcc/config/rs6000/rs6000-protos.h	2014-09-19 15:59:51.000000000 -0500
++++ gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/rs6000-protos.h	2014-11-06 09:32:31.610217000 -0600
+@@ -186,6 +186,7 @@
+ extern void rs6000_emit_prologue (void);
+ extern void rs6000_emit_load_toc_table (int);
+ extern unsigned int rs6000_dbx_register_number (unsigned int);
++extern unsigned int rs6000_fsl_dbx_register_number (unsigned int);
+ extern void rs6000_emit_epilogue (int);
+ extern void rs6000_emit_eh_reg_restore (rtx, rtx);
+ extern const char * output_isel (rtx *);
+diff -Naur gcc-4.9.2/gcc/config/rs6000/sysv4.h gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/sysv4.h
+--- gcc-4.9.2/gcc/config/rs6000/sysv4.h	2014-07-24 12:25:19.000000000 -0500
++++ gcc-4.9.2-dbx-vector-reg/gcc/config/rs6000/sysv4.h	2014-11-06 09:33:45.296217000 -0600
+@@ -948,7 +948,8 @@
+ /* This target uses the sysv4.opt file.  */
+ #define TARGET_USES_SYSV4_OPT 1
+ 
+-#undef DBX_REGISTER_NUMBER
++/* Use standard DWARF numbering for DWARF debugging information.  */
++#define DBX_REGISTER_NUMBER(REGNO) rs6000_fsl_dbx_register_number (REGNO)
+ 
+ /* Link -lasan early on the command line.  For -static-libasan, don't link
+    it for -shared link, the executable should be compiled with -static-libasan
+diff -Naur gcc-4.8.3/gcc/testsuite/gcc.target/powerpc/ppc-fsl-altivec-dwreg.c gcc-4.8.3-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-altivec-dwreg.c
+--- gcc-4.8.3/gcc/testsuite/gcc.target/powerpc/ppc-fsl-altivec-dwreg.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.8.3-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-altivec-dwreg.c	2014-12-05 04:11:26.299670000 -0600
+@@ -0,0 +1,18 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O0 -g -mmap_dwarf_vecreg" } */
++/* { dg-final { scan-assembler-times ".uleb128 0x481" 1 } } */
++/* { dg-final { scan-assembler-times ".uleb128 0x482" 1 } } */
++/* { dg-final { scan-assembler-times ".uleb128 0x483" 1 } } */
++
++#include <altivec.h>
++
++vector unsigned int fun()
++{
++  register vector unsigned int vi1 = {0,1,2,3}; 
++  register vector unsigned int vi2 = {1,2,3,4};
++  register vector unsigned int ri = {0,0,0,0};
++  ri = vec_add(vi1, vi2); /* ri = vi1 + vi2 */
++
++  return ri;
++}
diff --git a/recipes-devtools/gcc/gcc-4.9/0026-libgcc-sjlj-check.patch b/recipes-devtools/gcc/gcc-4.9/0026-libgcc-sjlj-check.patch
new file mode 100644
index 0000000..d4efab9
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0026-libgcc-sjlj-check.patch
@@ -0,0 +1,74 @@
+From 08c2398445e6cac282488f64ae6bf29cbcd8db23 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:20:50 +0400
+Subject: [PATCH 26/35] libgcc-sjlj-check
+
+ac_fn_c_try_compile doesnt seem to keep the intermediate files
+which are needed for sjlj test to pass since it greps into the
+generated file. So we run the compiler command using AC_TRY_COMMAND
+which then generates the needed .s file
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ libgcc/configure    |   10 ++++++----
+ libgcc/configure.ac |   10 ++++------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/libgcc/configure b/libgcc/configure
+index 1425df6..d18e3cb 100644
+--- a/libgcc/configure
++++ b/libgcc/configure
+@@ -4208,17 +4208,19 @@ void foo ()
+ }
+ 
+ _ACEOF
+-CFLAGS_hold=$CFLAGS
+-CFLAGS="--save-temps -fexceptions"
+ libgcc_cv_lib_sjlj_exceptions=unknown
+-if ac_fn_c_try_compile; then :
++if { ac_try='${CC-cc} -fexceptions -S conftest.c -o conftest.s 1>&5'
++  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
++  (eval $ac_try) 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then
+   if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1; then
+     libgcc_cv_lib_sjlj_exceptions=yes
+   elif grep _Unwind_Resume conftest.s >/dev/null 2>&1; then
+     libgcc_cv_lib_sjlj_exceptions=no
+   fi
+ fi
+-CFLAGS=$CFLAGS_hold
+ rm -f conftest*
+ 
+ fi
+diff --git a/libgcc/configure.ac b/libgcc/configure.ac
+index 8b7aba5..c7c9644 100644
+--- a/libgcc/configure.ac
++++ b/libgcc/configure.ac
+@@ -216,16 +216,14 @@ void foo ()
+   bar();
+ }
+ ])])
+-CFLAGS_hold=$CFLAGS
+-CFLAGS="--save-temps -fexceptions"
+ libgcc_cv_lib_sjlj_exceptions=unknown
+-AS_IF([ac_fn_c_try_compile],
+-  [if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1; then
++if AC_TRY_COMMAND(${CC-cc} -fexceptions -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
++  if grep _Unwind_SjLj_Resume conftest.s >/dev/null 2>&1; then
+     libgcc_cv_lib_sjlj_exceptions=yes
+   elif grep _Unwind_Resume conftest.s >/dev/null 2>&1; then
+     libgcc_cv_lib_sjlj_exceptions=no
+-  fi])
+-CFLAGS=$CFLAGS_hold
++  fi
++fi
+ rm -f conftest*
+ ])
+ 
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0026.gcc.fix_MTWX51605-memset-array-init_48.patch b/recipes-devtools/gcc/gcc-4.9/0026.gcc.fix_MTWX51605-memset-array-init_48.patch
new file mode 100644
index 0000000..5ff1bd2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0026.gcc.fix_MTWX51605-memset-array-init_48.patch
@@ -0,0 +1,129 @@
+# Problem Statement:
+  Identify memory block setting and insert call to memset() or a loop-unrolled
+  code sequence
+
+# Reported by:
+  James Yang
+
+# Owned by:
+  Rohit
+
+# Action:
+  1. From v4.8 onwards, gcc generates 'memset' call for initialization loop
+     by default.
+  2. If the loop count of the initialization loop is known at compile time, 
+     generate sequence of store instructions for 'memset' calls based on the
+     target specific data given below.
+  3. For e500mc generate call to 'memset' if no. of bytes to
+     be cleared is > 136 else generate sequence of store instructions.
+  4. For e500v1/e500v2 generate call to 'memset' if no. of bytes to
+     be cleared is > 172 else generate sequence of store instructions (vector).
+  5. For e5500/e6500 (32-bit) generate  call to 'memset' if no. of bytes to be
+     cleared is > 120 else generate sequence of store instructions.
+  6. For e5500/e6500 (64-bit) generate  call to 'memset' if no. of bytes to be
+     cleared is > 248 else generate sequence of store instructions.
+  7. Set upper bound limit (256/512) for generation of sequence of store
+     instructions to prevent stack overflow due to code bloat.
+  8. To override the default no. of bytes to be cleared values, use the
+     target flag '-mmax_block_clear='.
+  9. To disable this change and get default GCC behavior use the flag
+     '-mno-opt-memset'.
+
+diff -Naur gcc-4.8.1/gcc/config/rs6000/rs6000.c gcc-4.8.1-MTWX51605-memset-array-init/gcc/config/rs6000/rs6000.c
+--- gcc-4.8.1/gcc/config/rs6000/rs6000.c	2013-06-07 08:09:43.578001466 -0500
++++ gcc-4.8.1-MTWX51605-memset-array-init/gcc/config/rs6000/rs6000.c	2013-06-07 09:28:04.641003044 -0500
+@@ -2423,6 +2423,10 @@
+   if (optimize >= 3 && global_init_p && !global_options_set.x_flag_ira_loop_pressure)
+     flag_ira_loop_pressure = 1;
+ 
++  if (!global_options_set.x_TARGET_OPT_MEMSET_STORE &&
++      (flag_tree_loop_distribution || flag_tree_loop_distribute_patterns))
++    TARGET_OPT_MEMSET_STORE = 1;
++
+   /* Set the pointer size.  */
+   if (TARGET_64BIT)
+     {
+@@ -13414,7 +13418,64 @@
+ 
+   if (optimize_size && bytes > 3 * clear_step)
+     return 0;
+-  if (! optimize_size && bytes > 8 * clear_step)
++
++  if (TARGET_OPT_MEMSET_STORE && !optimize_size)
++    {
++      if (rs6000_cpu == PROCESSOR_PPCE500MC)
++        {
++          /* Based on comparison of performance data between generating sequence
++             of store instructions and 'memset' call,'memset' executes faster if
++             the no of bytes is > 136.
++             An Upper bound limit has been set for the generation of store
++             instructions to prevent stack overflow due to code bloat.  */
++          if (bytes > (rs6000_max_block_clear ?
++             ((rs6000_max_block_clear > 256) ? 256 : rs6000_max_block_clear)  : 136))
++            return 0;
++        }
++      else if ((rs6000_cpu == PROCESSOR_PPC8540) && align >= 64)
++        {
++          /* Based on comparison of performance data between generating sequence
++             of store instructions (vector) and 'memset' call,'memset' executes faster if
++             the no of bytes is > 172.
++             An Upper bound limit has been set for the generation of store
++             instructions to prevent stack overflow due to code bloat.  */
++          if (bytes > (rs6000_max_block_clear ?
++             ((rs6000_max_block_clear > 256) ? 256 : rs6000_max_block_clear)  : 172))
++            return 0;
++        }
++      else if ((rs6000_cpu == PROCESSOR_PPCE5500 ||
++                rs6000_cpu == PROCESSOR_PPCE6500 ||
++                rs6000_cpu == PROCESSOR_PPCE500MC64) &&  TARGET_32BIT)
++        {
++          /* Based on comparison of performance data between generating sequence
++             of store instructions and 'memset' call,'memset' executes faster if
++             the no of bytes is > 120.
++             An Upper bound limit has been set for the generation of store
++             instructions to prevent stack overflow due to code bloat.  */
++          if (bytes > (rs6000_max_block_clear ?
++             ((rs6000_max_block_clear > 256) ? 256 : rs6000_max_block_clear)  : 120))
++            return 0;
++        }
++      else if ((rs6000_cpu == PROCESSOR_PPCE5500 ||
++                rs6000_cpu == PROCESSOR_PPCE6500 ||
++                rs6000_cpu == PROCESSOR_PPCE500MC64) &&  TARGET_64BIT)
++        {
++          /* Based on comparison of performance data between generating sequence
++             of store instructions and 'memset' call,'memset' executes faster if
++             the no of bytes is > 248.
++             An Upper bound limit has been set for the generation of store
++             instructions to prevent stack overflow due to code bloat.  */
++          if (bytes > (rs6000_max_block_clear ?
++             ((rs6000_max_block_clear > 512) ? 512 : rs6000_max_block_clear)  : 248))
++            return 0;
++        }
++          /* An Upper bound limit has been set for the generation of store
++             instructions to prevent stack overflow due to code bloat.  */
++      else if (bytes > (rs6000_max_block_clear ?
++              ((rs6000_max_block_clear > 256) ? 256 : rs6000_max_block_clear) : 8 * clear_step))
++        return 0;
++    }
++  else if (! optimize_size && bytes > 8 * clear_step)
+     return 0;
+ 
+   for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
+diff -Naur gcc-4.8.1/gcc/config/rs6000/rs6000.opt gcc-4.8.1-MTWX51605-memset-array-init/gcc/config/rs6000/rs6000.opt
+--- gcc-4.8.1/gcc/config/rs6000/rs6000.opt	2013-06-07 08:09:43.660001466 -0500
++++ gcc-4.8.1-MTWX51605-memset-array-init/gcc/config/rs6000/rs6000.opt	2013-06-07 09:26:09.607001012 -0500
+@@ -157,6 +157,14 @@
+ Target Report Mask(MULTIPLE) Var(rs6000_isa_flags)
+ Generate load/store multiple instructions
+ 
++mmax_block_clear=
++Target RejectNegative Joined UInteger Var(rs6000_max_block_clear) Init(0)
++Maximum size in bytes above which generate string instructions for block clear
++
++mopt-memset
++Target Report Var(TARGET_OPT_MEMSET_STORE) Save
++If optimal emit sequence of stores for memset
++
+ mstring
+ Target Report Mask(STRING) Var(rs6000_isa_flags)
+ Generate string instructions for block moves
diff --git a/recipes-devtools/gcc/gcc-4.9/0027-cpp-honor-sysroot.patch b/recipes-devtools/gcc/gcc-4.9/0027-cpp-honor-sysroot.patch
new file mode 100644
index 0000000..05e9521
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0027-cpp-honor-sysroot.patch
@@ -0,0 +1,54 @@
+From a0f9bd09c816ad29ecf7c29d6c27f7df97710364 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:22:00 +0400
+Subject: [PATCH 27/35] cpp: honor sysroot.
+
+Currently, if the gcc toolchain is relocated and installed from sstate, then you try and compile
+preprocessed source (.i or .ii files), the compiler will try and access the builtin sysroot location
+rather than the --sysroot option specified on the commandline. If access to that directory is
+permission denied (unreadable), gcc will error.
+
+This happens when ccache is in use due to the fact it uses preprocessed source files.
+
+The fix below adds %I to the cpp-output spec macro so the default substitutions for -iprefix,
+-isystem, -isysroot happen and the correct sysroot is used.
+
+[YOCTO #2074]
+
+RP 2012/04/13
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/cp/lang-specs.h |    2 +-
+ gcc/gcc.c           |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h
+index a001c3e..1aae1e4 100644
+--- a/gcc/cp/lang-specs.h
++++ b/gcc/cp/lang-specs.h
+@@ -63,5 +63,5 @@ along with GCC; see the file COPYING3.  If not see
+   {".ii", "@c++-cpp-output", 0, 0, 0},
+   {"@c++-cpp-output",
+    "%{!M:%{!MM:%{!E:\
+-    cc1plus -fpreprocessed %i %(cc1_options) %2\
++    cc1plus -fpreprocessed %i %I %(cc1_options) %2\
+     %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+diff --git a/gcc/gcc.c b/gcc/gcc.c
+index 51062aa..cf6b99e 100644
+--- a/gcc/gcc.c
++++ b/gcc/gcc.c
+@@ -1042,7 +1042,7 @@ static const struct compiler default_compilers[] =
+                     %W{o*:--output-pch=%*}}%V}}}}}}", 0, 0, 0},
+   {".i", "@cpp-output", 0, 0, 0},
+   {"@cpp-output",
+-   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
++   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %I %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+   {".s", "@assembler", 0, 0, 0},
+   {"@assembler",
+    "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0027.gcc.fix_altivec_constant_alignment-v2.patch b/recipes-devtools/gcc/gcc-4.9/0027.gcc.fix_altivec_constant_alignment-v2.patch
new file mode 100644
index 0000000..36fb64d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0027.gcc.fix_altivec_constant_alignment-v2.patch
@@ -0,0 +1,33 @@
+# Problem Statement:
+  Altivec vector load instruction accepts non-aligned offsets, but it
+  will silently ignore the last 4 bits, resulting in accessing the
+  wrong memory.
+
+  Increase alignment for vector constants to take care of 
+  unaligned access.
+
+  This patch resolves the run-time segmentation fault on e6500 board.
+
+# Reported by:
+  Edmar [29.May.2013]
+
+# Owned by:
+  Edmar & Rohit
+
+# Action:
+  * Update GCC target macro to align vector constants on 16-byte
+    boundary. 
+  
+diff -Naur gcc-4.7.2/gcc/config/rs6000/rs6000.h gcc-4.7.2-altivec_const_align/gcc/config/rs6000/rs6000.h
+--- gcc-4.7.2/gcc/config/rs6000/rs6000.h        2013-05-30 06:20:45.631000574 -0500
++++ gcc-4.7.2-altivec_const_align/gcc/config/rs6000/rs6000.h    2013-05-30 06:24:30.663001475 -0500
+@@ -748,7 +748,8 @@
+    && (STRICT_ALIGNMENT || !optimize_size)                       \
+    && (ALIGN) < BITS_PER_WORD                                    \
+    ? BITS_PER_WORD                                               \
+-   : (ALIGN))
++   : ((TARGET_ALTIVEC && (TREE_CODE (EXP) == VECTOR_CST)       \
++     && ((ALIGN) < 128)) ? 128 : (ALIGN)))
+
+ /* Make arrays of chars word-aligned for the same reasons.
+    Align vectors to 128 bits.  Align SPE vectors and E500 v2 doubles to
diff --git a/recipes-devtools/gcc/gcc-4.9/0028-MIPS64-Default-to-N64-ABI.patch b/recipes-devtools/gcc/gcc-4.9/0028-MIPS64-Default-to-N64-ABI.patch
new file mode 100644
index 0000000..2638720
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0028-MIPS64-Default-to-N64-ABI.patch
@@ -0,0 +1,31 @@
+From 301e18d4711db5925e767fad08dffa9cfe0a2f1f Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:23:08 +0400
+Subject: [PATCH 28/35] MIPS64: Default to N64 ABI
+
+MIPS64 defaults to n32 ABI, this patch makes it
+so that it defaults to N64 ABI
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [OE config specific]
+---
+ gcc/config.gcc |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gcc/config.gcc b/gcc/config.gcc
+index 1a0be50..989c2fb 100644
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -1797,7 +1797,7 @@ mips*-mti-linux*)
+ mips64*-*-linux* | mipsisa64*-*-linux*)
+ 	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/gnu-user64.h mips/linux64.h mips/linux-common.h"
+ 	tmake_file="${tmake_file} mips/t-linux64"
+-	tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32"
++	tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_64"
+ 	case ${target} in
+ 		mips64el-st-linux-gnu)
+ 			tm_file="${tm_file} mips/st.h"
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0028.gcc.fix_altivec_reload_gs8.patch b/recipes-devtools/gcc/gcc-4.9/0028.gcc.fix_altivec_reload_gs8.patch
new file mode 100644
index 0000000..5fe0b25
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0028.gcc.fix_altivec_reload_gs8.patch
@@ -0,0 +1,29 @@
+# Problem Statement:
+  Office-2.gs8 ICE for alitvec targets e600/e6500.
+  Fix secondary reload addresses for Altivec targets.
+  
+# Reported by:
+  Rohit
+
+# Action:
+  This issue was first reported with one of the IBM's LE patch.
+  Reverted the change.
+
+diff -Naur gcc-4.8.3/gcc/config/rs6000/rs6000.c gcc-4.8.3-gs8-ice/gcc/config/rs6000/rs6000.c
+--- gcc-4.8.3/gcc/config/rs6000/rs6000.c	2014-08-31 01:54:57.844015000 -0500
++++ gcc-4.8.3-gs8-ice/gcc/config/rs6000/rs6000.c	2014-08-31 03:36:31.520015000 -0500
+@@ -17329,12 +17329,11 @@
+ 
+       if (legitimate_indirect_address_p (addr, false)	/* reg */
+ 	  || legitimate_indexed_address_p (addr, false)	/* reg+reg */
++	  || GET_CODE (addr) == PRE_MODIFY		/* VSX pre-modify */
+ 	  || (GET_CODE (addr) == AND			/* Altivec memory */
+-	      && rclass == ALTIVEC_REGS
+ 	      && GET_CODE (XEXP (addr, 1)) == CONST_INT
+ 	      && INTVAL (XEXP (addr, 1)) == -16
+-	      && (legitimate_indirect_address_p (XEXP (addr, 0), false)
+-		  || legitimate_indexed_address_p (XEXP (addr, 0), false))))
++	      && VECTOR_MEM_ALTIVEC_P (mode)))
+ 	;
+ 
+       else if (GET_CODE (addr) == PLUS)
diff --git a/recipes-devtools/gcc/gcc-4.9/0029-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch b/recipes-devtools/gcc/gcc-4.9/0029-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch
new file mode 100644
index 0000000..969d290
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0029-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch
@@ -0,0 +1,228 @@
+From 29d12344fb682a053de53eb08b95704cf3b67af2 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:24:50 +0400
+Subject: [PATCH 29/35] Define GLIBC_DYNAMIC_LINKER and UCLIBC_DYNAMIC_LINKER
+ relative to SYSTEMLIBS_DIR
+
+This patch defines GLIBC_DYNAMIC_LINKER and UCLIBC_DYNAMIC_LINKER
+relative to SYSTEMLIBS_DIR which can be set in generated headers
+This breaks the assumption of hardcoded multilib in gcc
+Change is only for the supported architectures in OE including
+SH, sparc, alpha for possible future support (if any)
+
+Removes the do_headerfix task in metadata
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Inappropriate [OE configuration]
+---
+ gcc/config/alpha/linux-elf.h |    4 ++--
+ gcc/config/arm/linux-eabi.h  |    4 ++--
+ gcc/config/arm/linux-elf.h   |    2 +-
+ gcc/config/i386/linux.h      |    2 +-
+ gcc/config/i386/linux64.h    |    6 +++---
+ gcc/config/mips/linux.h      |    2 +-
+ gcc/config/mips/linux64.h    |    8 ++++----
+ gcc/config/rs6000/linux64.h  |    8 ++++----
+ gcc/config/sh/linux.h        |    2 +-
+ gcc/config/sparc/linux.h     |    2 +-
+ gcc/config/sparc/linux64.h   |    4 ++--
+ 11 files changed, 22 insertions(+), 22 deletions(-)
+
+Index: gcc-4.9.0/gcc/config/alpha/linux-elf.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/alpha/linux-elf.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/alpha/linux-elf.h	2014-05-07 16:43:50.605106535 +0000
+@@ -23,8 +23,8 @@
+ #define EXTRA_SPECS \
+ { "elf_dynamic_linker", ELF_DYNAMIC_LINKER },
+ 
+-#define GLIBC_DYNAMIC_LINKER	"/lib/ld-linux.so.2"
+-#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
++#define GLIBC_DYNAMIC_LINKER	SYSTEMLIBS_DIR "ld-linux.so.2"
++#define UCLIBC_DYNAMIC_LINKER  SYSTEMLIBS_DIR "ld-uClibc.so.0"
+ #if DEFAULT_LIBC == LIBC_UCLIBC
+ #define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
+ #elif DEFAULT_LIBC == LIBC_GLIBC
+Index: gcc-4.9.0/gcc/config/arm/linux-eabi.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/arm/linux-eabi.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/arm/linux-eabi.h	2014-05-07 16:43:50.605106535 +0000
+@@ -68,8 +68,8 @@
+    GLIBC_DYNAMIC_LINKER_DEFAULT and TARGET_DEFAULT_FLOAT_ABI.  */
+ 
+ #undef  GLIBC_DYNAMIC_LINKER
+-#define GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "/lib/ld-linux.so.3"
+-#define GLIBC_DYNAMIC_LINKER_HARD_FLOAT "/lib/ld-linux-armhf.so.3"
++#define GLIBC_DYNAMIC_LINKER_SOFT_FLOAT SYSTEMLIBS_DIR "ld-linux.so.3"
++#define GLIBC_DYNAMIC_LINKER_HARD_FLOAT SYSTEMLIBS_DIR "ld-linux-armhf.so.3"
+ #define GLIBC_DYNAMIC_LINKER_DEFAULT GLIBC_DYNAMIC_LINKER_SOFT_FLOAT
+ 
+ #define GLIBC_DYNAMIC_LINKER \
+Index: gcc-4.9.0/gcc/config/arm/linux-elf.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/arm/linux-elf.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/arm/linux-elf.h	2014-05-07 16:43:50.605106535 +0000
+@@ -57,7 +57,7 @@
+ 
+ #define LIBGCC_SPEC "%{mfloat-abi=soft*:-lfloat} -lgcc"
+ 
+-#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
++#define GLIBC_DYNAMIC_LINKER SYSTEMLIBS_DIR "ld-linux.so.2"
+ 
+ #define LINUX_TARGET_LINK_SPEC  "%{h*} \
+    %{static:-Bstatic} \
+Index: gcc-4.9.0/gcc/config/i386/linux.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/i386/linux.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/i386/linux.h	2014-05-07 16:43:50.605106535 +0000
+@@ -20,4 +20,4 @@
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #define GNU_USER_LINK_EMULATION "elf_i386"
+-#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
++#define GLIBC_DYNAMIC_LINKER SYSTEMLIBS_DIR "ld-linux.so.2"
+Index: gcc-4.9.0/gcc/config/i386/linux64.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/i386/linux64.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/i386/linux64.h	2014-05-07 16:43:50.605106535 +0000
+@@ -27,6 +27,6 @@
+ #define GNU_USER_LINK_EMULATION64 "elf_x86_64"
+ #define GNU_USER_LINK_EMULATIONX32 "elf32_x86_64"
+ 
+-#define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
+-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
+-#define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
++#define GLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld-linux.so.2"
++#define GLIBC_DYNAMIC_LINKER64 SYSTEMLIBS_DIR "ld-linux-x86-64.so.2"
++#define GLIBC_DYNAMIC_LINKERX32 SYSTEMLIBS_DIR "ld-linux-x32.so.2"
+Index: gcc-4.9.0/gcc/config/mips/linux.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/mips/linux.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/mips/linux.h	2014-05-07 16:43:50.605106535 +0000
+@@ -18,8 +18,8 @@
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #define GLIBC_DYNAMIC_LINKER \
+-  "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld-linux-mipsn8.so.1;:" SYSTEMLIBS_DIR "ld.so.1}"
+ 
+ #undef UCLIBC_DYNAMIC_LINKER
+ #define UCLIBC_DYNAMIC_LINKER \
+-  "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld-uClibc-mipsn8.so.0;:" SYSTEMLIBS_DIR "ld-uClibc.so.0}"
+Index: gcc-4.9.0/gcc/config/mips/linux64.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/mips/linux64.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/mips/linux64.h	2014-05-07 16:43:50.605106535 +0000
+@@ -23,20 +23,20 @@
+ #define GNU_USER_LINK_EMULATIONN32 "elf32%{EB:b}%{EL:l}tsmipn32"
+ 
+ #define GLIBC_DYNAMIC_LINKER32 \
+-  "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld-linux-mipsn8.so.1;:" SYSTEMLIBS_DIR "ld.so.1}"
+ #define GLIBC_DYNAMIC_LINKER64 \
+-  "%{mnan=2008:/lib64/ld-linux-mipsn8.so.1;:/lib64/ld.so.1}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld-linux-mipsn8.so.1;:" SYSTEMLIBS_DIR "ld.so.1}"
+ #define GLIBC_DYNAMIC_LINKERN32 \
+-  "%{mnan=2008:/lib32/ld-linux-mipsn8.so.1;:/lib32/ld.so.1}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld-linux-mipsn8.so.1;:" SYSTEMLIBS_DIR "ld.so.1}"
+ 
+ #undef UCLIBC_DYNAMIC_LINKER32
+ #define UCLIBC_DYNAMIC_LINKER32 \
+-  "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld-uClibc-mipsn8.so.0;:" SYSTEMLIBS_DIR "ld-uClibc.so.0}"
+ #undef UCLIBC_DYNAMIC_LINKER64
+ #define UCLIBC_DYNAMIC_LINKER64 \
+-  "%{mnan=2008:/lib/ld64-uClibc-mipsn8.so.0;:/lib/ld64-uClibc.so.0}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld64-uClibc-mipsn8.so.0;:" SYSTEMLIBS_DIR "ld64-uClibc.so.0}"
+ #define UCLIBC_DYNAMIC_LINKERN32 \
+-  "%{mnan=2008:/lib32/ld-uClibc-mipsn8.so.0;:/lib32/ld-uClibc.so.0}"
++  "%{mnan=2008:" SYSTEMLIBS_DIR "ld-uClibc-mipsn8.so.0;:" SYSTEMLIBS_DIR "ld-uClibc.so.0}"
+ 
+ #define BIONIC_DYNAMIC_LINKERN32 "/system/bin/linker32"
+ #define GNU_USER_DYNAMIC_LINKERN32 \
+Index: gcc-4.9.0/gcc/config/rs6000/linux64.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/rs6000/linux64.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/rs6000/linux64.h	2014-05-07 16:43:50.605106535 +0000
+@@ -367,14 +367,14 @@
+ #undef	LINK_OS_DEFAULT_SPEC
+ #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
+ 
+-#define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
++#define GLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld.so.1"
+ #ifdef LINUX64_DEFAULT_ABI_ELFv2
+-#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:/lib64/ld64.so.1;:/lib64/ld64.so.2}"
++#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv1:" SYSTEMLIBS_DIR "ld64.so.1;:" SYSTEMLIBS_DIR "ld64.so.2}"
+ #else
+-#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:/lib64/ld64.so.2;:/lib64/ld64.so.1}"
++#define GLIBC_DYNAMIC_LINKER64 "%{mabi=elfv2:" SYSTEMLIBS_DIR "ld64.so.2;:" SYSTEMLIBS_DIR "ld64.so.1}"
+ #endif
+-#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
+-#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
++#define UCLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld-uClibc.so.0"
++#define UCLIBC_DYNAMIC_LINKER64 SYSTEMLIBS_DIR "ld64-uClibc.so.0"
+ #if DEFAULT_LIBC == LIBC_UCLIBC
+ #define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
+ #elif DEFAULT_LIBC == LIBC_GLIBC
+Index: gcc-4.9.0/gcc/config/sh/linux.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/sh/linux.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/sh/linux.h	2014-05-07 16:43:50.605106535 +0000
+@@ -43,7 +43,7 @@
+ 
+ #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+ 
+-#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
++#define GLIBC_DYNAMIC_LINKER SYSTEMLIBS_DIR "ld-linux.so.2"
+ 
+ #undef SUBTARGET_LINK_EMUL_SUFFIX
+ #define SUBTARGET_LINK_EMUL_SUFFIX "_linux"
+Index: gcc-4.9.0/gcc/config/sparc/linux.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/sparc/linux.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/sparc/linux.h	2014-05-07 16:43:50.605106535 +0000
+@@ -83,7 +83,7 @@
+    When the -shared link option is used a final link is not being
+    done.  */
+ 
+-#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
++#define GLIBC_DYNAMIC_LINKER SYSTEMLIBS_DIR "ld-linux.so.2"
+ 
+ #undef  LINK_SPEC
+ #define LINK_SPEC "-m elf32_sparc %{shared:-shared} \
+Index: gcc-4.9.0/gcc/config/sparc/linux64.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/sparc/linux64.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/sparc/linux64.h	2014-05-07 16:43:50.605106535 +0000
+@@ -92,8 +92,8 @@
+    When the -shared link option is used a final link is not being
+    done.  */
+ 
+-#define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
+-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux.so.2"
++#define GLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld-linux.so.2"
++#define GLIBC_DYNAMIC_LINKER64 SYSTEMLIBS_DIR "ld-linux.so.2"
+ 
+ #ifdef SPARC_BI_ARCH
+ 
+Index: gcc-4.9.0/gcc/config/linux.h
+===================================================================
+--- gcc-4.9.0.orig/gcc/config/linux.h	2014-05-07 16:43:50.609106535 +0000
++++ gcc-4.9.0/gcc/config/linux.h	2014-05-07 16:43:50.605106535 +0000
+@@ -73,10 +73,10 @@
+    GLIBC_DYNAMIC_LINKER must be defined for each target using them, or
+    GLIBC_DYNAMIC_LINKER32 and GLIBC_DYNAMIC_LINKER64 for targets
+    supporting both 32-bit and 64-bit compilation.  */
+-#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
+-#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
+-#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
+-#define UCLIBC_DYNAMIC_LINKERX32 "/lib/ldx32-uClibc.so.0"
++#define UCLIBC_DYNAMIC_LINKER SYSTEMLIBS_DIR "ld-uClibc.so.0"
++#define UCLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld-uClibc.so.0"
++#define UCLIBC_DYNAMIC_LINKER64 SYSTEMLIBS_DIR "ld64-uClibc.so.0"
++#define UCLIBC_DYNAMIC_LINKERX32 SYSTEMLIBS_DIR "ldx32-uClibc.so.0"
+ #define BIONIC_DYNAMIC_LINKER "/system/bin/linker"
+ #define BIONIC_DYNAMIC_LINKER32 "/system/bin/linker"
+ #define BIONIC_DYNAMIC_LINKER64 "/system/bin/linker64"
diff --git a/recipes-devtools/gcc/gcc-4.9/0029.gcc.fix_postfix_gimplifier.patch b/recipes-devtools/gcc/gcc-4.9/0029.gcc.fix_postfix_gimplifier.patch
new file mode 100644
index 0000000..d2526ed
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0029.gcc.fix_postfix_gimplifier.patch
@@ -0,0 +1,92 @@
+# Problem Statement:
+  With Flag mining options, EEMBC benchmarks [consumer-1.cjpeg,consumer-1.djpej]
+  showed performance degradation when built with GCC v4.8.1.
+
+# Reported by:
+  Edmar Wienskoski
+
+# Owned by:
+  Rohit
+
+# Action:
+  The issue was the way gimplifier was handing postfix operations
+  (self modifying expression) in GCC v4.8.1 compared to v4.7.3.
+ 
+  GCC v4.8.1 source was changed to confirm with C11 standard.
+  This is not a BUG.
+  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814
+
+  Added flag '-fdisable-c11-self-mod-expr' to recover performance loss. 
+
+
+diff -Naur gcc-4.8.2/gcc/common.opt gcc-4.8.2-gimplify-selfmod-expr/gcc/common.opt
+--- gcc-4.8.2/gcc/common.opt	2014-02-24 03:29:58.689893016 -0600
++++ gcc-4.8.2-gimplify-selfmod-expr/gcc/common.opt	2014-02-24 07:30:28.930815001 -0600
+@@ -1035,6 +1035,10 @@
+ Common Joined RejectNegative Var(common_deferred_options) Defer
+ -fdisable-[tree|rtl|ipa]-<pass>=range1+range2 disables an optimization pass
+ 
++fdisable-c11-self-mod-expr
++Common RejectNegative Report Var(flag_disable_c11_self_mod_expr) Init(0) Optimization
++Disable c11 restriction on self modifying expression of gimplifier
++
+ fenable-
+ Common Joined RejectNegative Var(common_deferred_options) Defer
+ -fenable-[tree|rtl|ipa]-<pass>=range1+range2 enables an optimization pass
+diff -Naur gcc-4.8.2/gcc/gimplify.c gcc-4.8.2-gimplify-selfmod-expr/gcc/gimplify.c
+--- gcc-4.8.2/gcc/gimplify.c	2014-02-24 03:29:08.229893001 -0600
++++ gcc-4.8.2-gimplify-selfmod-expr/gcc/gimplify.c	2014-02-24 07:36:24.403815001 -0600
+@@ -2393,11 +2393,20 @@
+      that as the result value and in the postqueue operation.  */
+   if (postfix)
+     {
++      if (flag_disable_c11_self_mod_expr && !is_gimple_min_lval (lvalue))
++        {
++	   mark_addressable (lvalue);
++	   lvalue = build_fold_addr_expr_loc (input_location, lvalue);
++	   gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue);
++	   lvalue = build_fold_indirect_ref_loc (input_location, lvalue);
++        }
++
+       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
+       if (ret == GS_ERROR)
+-	return ret;
+-
+-      lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
++        return ret;
++	  
++      if (!flag_disable_c11_self_mod_expr)
++        lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
+     }
+ 
+   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
+@@ -2405,18 +2414,25 @@
+     {
+       rhs = convert_to_ptrofftype_loc (loc, rhs);
+       if (arith_code == MINUS_EXPR)
+-	rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
+-      t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
++        rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
++		
++      if (flag_disable_c11_self_mod_expr)
++        arith_code = POINTER_PLUS_EXPR;
++      else
++        t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
+     }
+-  else
++  else if (!flag_disable_c11_self_mod_expr)
+     t1 = fold_convert (TREE_TYPE (*expr_p),
+ 		       fold_build2 (arith_code, arith_type,
+ 				    fold_convert (arith_type, lhs),
+ 				    fold_convert (arith_type, rhs)));
+ 
++  if (flag_disable_c11_self_mod_expr)
++    t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
++
+   if (postfix)
+     {
+-      gimplify_assign (lvalue, t1, pre_p);
++      gimplify_assign (lvalue, t1, ((flag_disable_c11_self_mod_expr) ? orig_post_p : pre_p));
+       gimplify_seq_add_seq (orig_post_p, post);
+       *expr_p = lhs;
+       return GS_ALL_DONE;
diff --git a/recipes-devtools/gcc/gcc-4.9/0030-gcc-Fix-argument-list-too-long-error.patch b/recipes-devtools/gcc/gcc-4.9/0030-gcc-Fix-argument-list-too-long-error.patch
new file mode 100644
index 0000000..2ceaff6
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0030-gcc-Fix-argument-list-too-long-error.patch
@@ -0,0 +1,40 @@
+From c1816c160156f99c34e6a0a0311bb0219326804e Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:26:37 +0400
+Subject: [PATCH 30/35] gcc: Fix argument list too long error.
+
+There would be an "Argument list too long" error when the
+build directory is longer than 200, this is caused by:
+
+headers=`echo $(PLUGIN_HEADERS) | tr ' ' '\012' | sort -u`
+
+The PLUGIN_HEADERS is too long before sort, so the "echo" can't handle
+it, use the $(sort list) of GNU make which can handle the too long list
+would fix the problem, the header would be short enough after sorted.
+The "tr ' ' '\012'" was used for translating the space to "\n", the
+$(sort list) doesn't need this.
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/Makefile.in |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gcc/Makefile.in b/gcc/Makefile.in
+index 2320497..8562a62 100644
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -4627,7 +4627,7 @@ install-plugin: installdirs lang.install-plugin s-header-vars install-gengtype
+ # We keep the directory structure for files in config or c-family and .def
+ # files. All other files are flattened to a single directory.
+ 	$(mkinstalldirs) $(DESTDIR)$(plugin_includedir)
+-	headers=`echo $(PLUGIN_HEADERS) | tr ' ' '\012' | sort -u`; \
++	headers="$(sort $(PLUGIN_HEADERS))"; \
+ 	srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`; \
+ 	for file in $$headers; do \
+ 	  if [ -f $$file ] ; then \
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0030.gcc.fix_adjust_address_cost.patch b/recipes-devtools/gcc/gcc-4.9/0030.gcc.fix_adjust_address_cost.patch
new file mode 100644
index 0000000..9607b15
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0030.gcc.fix_adjust_address_cost.patch
@@ -0,0 +1,346 @@
+# Problem Statement:
+  Fix Dhrystone degradation with GCC v492.
+  Target: e5500 64-bit.
+
+# Owned by:
+  Rohit
+
+# Action:
+  * Adjust the address cost while accessing constant addresses
+    so that it is profitable for loop invariant code.
+
+  * Referenced test case part of dhrystone benchmark code.
+
+diff -Naur gcc-4.9.2/gcc/config/rs6000/rs6000.c gcc-4.9.2-patch/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.2/gcc/config/rs6000/rs6000.c	2014-10-12 21:33:20.000000000 -0500
++++ gcc-4.9.2-patch/gcc/config/rs6000/rs6000.c	2014-11-22 13:38:52.939563569 -0600
+@@ -1460,7 +1460,7 @@
+ #undef TARGET_RTX_COSTS
+ #define TARGET_RTX_COSTS rs6000_rtx_costs
+ #undef TARGET_ADDRESS_COST
+-#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
++#define TARGET_ADDRESS_COST rs6000_address_costs
+ 
+ #undef TARGET_DWARF_REGISTER_SPAN
+ #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
+@@ -29899,6 +29899,24 @@
+   return ret;
+ }
+ 
++/* Address cost calculation.
++ * FIXME: Handle all addressing types */
++
++static int
++rs6000_address_costs (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
++		   addr_space_t as ATTRIBUTE_UNUSED,
++		   bool speed ATTRIBUTE_UNUSED)
++{
++  if (toc_relative_expr_p (x, false))
++    {
++      rtx temp = XVECEXP (tocrel_base, 0, 0);
++      if (GET_CODE (temp) != SYMBOL_REF)
++        return 0;
++      return 5;
++    }
++  return 0; 
++}
++
+ /* Debug form of ADDRESS_COST that is selected if -mdebug=cost.  */
+ 
+ static int
+diff -Naur gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv-2.c gcc-4.9.2-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv-2.c
+--- gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv-2.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.2-patch/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv-2.c	2015-01-22 16:07:13.614626997 -0600
+@@ -0,0 +1,292 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-O3 -m64 -fdump-rtl-loop2_invariant" } */
++/* { dg-final { scan-rtl-dump-times "Decided to move" 16 "loop2_invariant"} } */
++/* { dg-final { cleanup-rtl-dump "loop2_invariant" } } */
++
++#include <stdio.h>
++#include <string.h>
++
++typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
++                Enumeration;
++typedef int One_Thirty;
++typedef int One_Fifty;
++typedef char Capital_Letter;
++typedef int Boolean;
++typedef char Str_30 [31];
++typedef int Arr_1_Dim [50];
++typedef int Arr_2_Dim [50] [50];
++
++typedef struct record
++{
++  struct record *Ptr_Comp;
++  Enumeration Discr;
++  union {
++    struct {
++      Enumeration Enum_Comp;
++      int Int_Comp;
++      char Str_Comp [31];
++    } var_1;
++    struct {
++      Enumeration E_Comp_2;
++      char Str_2_Comp [31];
++    } var_2;
++    struct {
++      char Ch_1_Comp;
++      char Ch_2_Comp;
++    } var_3;
++  } variant;
++} Rec_Type, *Rec_Pointer;
++
++Rec_Pointer Ptr_Glob, Next_Ptr_Glob;
++int Int_Glob;
++Boolean Bool_Glob;
++char Ch_1_Glob, Ch_2_Glob;
++int Arr_1_Glob [50];
++int Arr_2_Glob [50] [50];
++char Reg_Define[] = "Register option selected.";
++double Begin_Time, End_Time, User_Time;
++double Microseconds, Dhrystones_Per_Second, Vax_Mips;
++
++Enumeration Func_1 ();
++void exit (int);
++
++void main ()
++{
++  double dtime();
++  One_Fifty Int_1_Loc;
++  One_Fifty Int_2_Loc;
++  One_Fifty Int_3_Loc;
++  char Ch_Index;
++  Enumeration Enum_Loc;
++  Str_30 Str_1_Loc;
++  Str_30 Str_2_Loc;
++  int Run_Index;
++  int Number_Of_Runs;
++
++  FILE *Ap;
++
++
++
++  if ((Ap = fopen("dhry.res","a+")) == ((void *)0))
++    {
++       printf("Can not open dhry.res\n\n");
++       exit(1);
++    }
++
++  Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
++  Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
++
++  Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
++  Ptr_Glob->Discr = Ident_1;
++  Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
++  Ptr_Glob->variant.var_1.Int_Comp = 40;
++  strcpy (Ptr_Glob->variant.var_1.Str_Comp,
++          "DHRYSTONE PROGRAM, SOME STRING");
++  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
++
++  Arr_2_Glob [8][7] = 10;
++
++  printf ("\n");
++  printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
++  printf ("\n");
++  printf ("Please give the number of runs through the benchmark: ");
++  {
++    int n;
++    scanf ("%d", &n);
++    Number_Of_Runs = n;
++  }
++  printf ("\n");
++  printf ("Execution starts, %d runs through Dhrystone\n",Number_Of_Runs);
++
++  Begin_Time = dtime();
++  for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
++  {
++
++    Proc_5();
++    Proc_4();
++
++    Int_1_Loc = 2;
++    Int_2_Loc = 3;
++    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
++    Enum_Loc = Ident_2;
++    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
++
++    while (Int_1_Loc < Int_2_Loc)
++    {
++      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
++      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
++      Int_1_Loc += 1;
++    }
++
++    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
++
++    Proc_1 (Ptr_Glob);
++    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
++    {
++      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
++
++        {
++          Proc_6 (Ident_1, &Enum_Loc);
++          strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
++          Int_2_Loc = Run_Index;
++          Int_Glob = Run_Index;
++        }
++    }
++    Int_2_Loc = Int_2_Loc * Int_1_Loc;
++    Int_1_Loc = Int_2_Loc / Int_3_Loc;
++    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
++    Proc_2 (&Int_1_Loc);
++  }
++  End_Time = dtime();
++
++  printf ("Execution ends\n");
++  printf ("\n");
++  printf ("Final values of the variables used in the benchmark:\n");
++  printf ("\n");
++  printf ("Int_Glob:            %d\n", Int_Glob);
++  printf ("        should be:   %d\n", 5);
++  printf ("Bool_Glob:           %d\n", Bool_Glob);
++  printf ("        should be:   %d\n", 1);
++  printf ("Ch_1_Glob:           %c\n", Ch_1_Glob);
++  printf ("        should be:   %c\n", 'A');
++  printf ("Ch_2_Glob:           %c\n", Ch_2_Glob);
++  printf ("        should be:   %c\n", 'B');
++  printf ("Arr_1_Glob[8]:       %d\n", Arr_1_Glob[8]);
++  printf ("        should be:   %d\n", 7);
++  printf ("Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]);
++  printf ("        should be:   Number_Of_Runs + 10\n");
++  printf ("Ptr_Glob->\n");
++  printf ("  Ptr_Comp:          %d\n", Ptr_Glob->Ptr_Comp);
++  printf ("        should be:   (implementation-dependent)\n");
++  printf ("  Discr:             %d\n", Ptr_Glob->Discr);
++  printf ("        should be:   %d\n", 0);
++  printf ("  Enum_Comp:         %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
++  printf ("        should be:   %d\n", 2);
++  printf ("  Int_Comp:          %d\n", Ptr_Glob->variant.var_1.Int_Comp);
++  printf ("        should be:   %d\n", 17);
++  printf ("  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp);
++  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
++  printf ("Next_Ptr_Glob->\n");
++  printf ("  Ptr_Comp:          %d\n", Next_Ptr_Glob->Ptr_Comp);
++  printf ("        should be:   (implementation-dependent), same as above\n");
++  printf ("  Discr:             %d\n", Next_Ptr_Glob->Discr);
++  printf ("        should be:   %d\n", 0);
++  printf ("  Enum_Comp:         %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
++  printf ("        should be:   %d\n", 1);
++  printf ("  Int_Comp:          %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
++  printf ("        should be:   %d\n", 18);
++  printf ("  Str_Comp:          %s\n", Next_Ptr_Glob->variant.var_1.Str_Comp);
++  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
++  printf ("Int_1_Loc:           %d\n", Int_1_Loc);
++  printf ("        should be:   %d\n", 5);
++  printf ("Int_2_Loc:           %d\n", Int_2_Loc);
++  printf ("        should be:   %d\n", 13);
++  printf ("Int_3_Loc:           %d\n", Int_3_Loc);
++  printf ("        should be:   %d\n", 7);
++  printf ("Enum_Loc:            %d\n", Enum_Loc);
++  printf ("        should be:   %d\n", 1);
++  printf ("Str_1_Loc:           %s\n", Str_1_Loc);
++  printf ("        should be:   DHRYSTONE PROGRAM, 1'ST STRING\n");
++  printf ("Str_2_Loc:           %s\n", Str_2_Loc);
++  printf ("        should be:   DHRYSTONE PROGRAM, 2'ND STRING\n");
++  printf ("\n");
++
++  User_Time = End_Time - Begin_Time;
++
++  if (User_Time < 2)
++  {
++    printf ("Measured time too small to obtain meaningful results\n");
++    printf ("Please increase number of runs\n");
++    printf ("\n");
++  }
++  else
++  {
++    Microseconds = User_Time * 1000000.0
++                        / (double) Number_Of_Runs;
++    Dhrystones_Per_Second = (double) Number_Of_Runs / User_Time;
++    Vax_Mips = Dhrystones_Per_Second / 1757.0;
++
++    printf ("Register option selected?  NO\n");
++    strcpy(Reg_Define, "Register option not selected.");
++
++    printf ("Microseconds for one run through Dhrystone: ");
++    printf ("%7.1lf \n", Microseconds);
++    printf ("Dhrystones per Second:                      ");
++    printf ("%10.1lf \n", Dhrystones_Per_Second);
++    printf ("VAX MIPS rating = %10.3lf \n",Vax_Mips);
++    printf ("\n");
++
++    fprintf(Ap,"\n");
++    fprintf(Ap,"Dhrystone Benchmark, Version 2.1 (Language: C)\n");
++    fprintf(Ap,"%s\n",Reg_Define);
++    fprintf(Ap,"Microseconds for one loop: %7.1lf\n",Microseconds);
++    fprintf(Ap,"Dhrystones per second: %10.1lf\n",Dhrystones_Per_Second);
++    fprintf(Ap,"VAX MIPS rating: %10.3lf\n",Vax_Mips);
++    fclose(Ap);
++  }
++}
++
++Proc_1 (Ptr_Val_Par)
++Rec_Pointer Ptr_Val_Par;
++{
++  Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
++  *Ptr_Val_Par->Ptr_Comp = *Ptr_Glob;
++  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
++  Next_Record->variant.var_1.Int_Comp
++        = Ptr_Val_Par->variant.var_1.Int_Comp;
++  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
++  Proc_3 (&Next_Record->Ptr_Comp);
++
++  if (Next_Record->Discr == Ident_1)
++  {
++    Next_Record->variant.var_1.Int_Comp = 6;
++    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
++           &Next_Record->variant.var_1.Enum_Comp);
++    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
++    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
++           &Next_Record->variant.var_1.Int_Comp);
++  }
++  else
++    *Ptr_Val_Par = *Ptr_Val_Par->Ptr_Comp;
++}
++
++
++Proc_2 (Int_Par_Ref)
++One_Fifty *Int_Par_Ref;
++{
++  One_Fifty Int_Loc;
++  Enumeration Enum_Loc;
++  Int_Loc = *Int_Par_Ref + 10;
++  do
++    if (Ch_1_Glob == 'A')
++    {
++      Int_Loc -= 1;
++      *Int_Par_Ref = Int_Loc - Int_Glob;
++      Enum_Loc = Ident_1;
++    }
++  while (Enum_Loc != Ident_1);
++}
++
++
++Proc_3 (Ptr_Ref_Par)
++Rec_Pointer *Ptr_Ref_Par;
++
++{
++  if (Ptr_Glob != 0)
++    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
++  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
++}
++
++Proc_4 ()
++{
++  Boolean Bool_Loc;
++  Bool_Loc = Ch_1_Glob == 'A';
++  Bool_Glob = Bool_Loc | Bool_Glob;
++  Ch_2_Glob = 'B';
++}
++
++Proc_5 ()
++{
++  Ch_1_Glob = 'A';
++  Bool_Glob = 0;
++}
diff --git a/recipes-devtools/gcc/gcc-4.9/0031-Disable-sdt.patch b/recipes-devtools/gcc/gcc-4.9/0031-Disable-sdt.patch
new file mode 100644
index 0000000..2c1d5e0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0031-Disable-sdt.patch
@@ -0,0 +1,113 @@
+From b85265bc94ec1beaf1d3b697c03db62991553467 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:28:10 +0400
+Subject: [PATCH 31/35] Disable sdt.
+
+We don't list dtrace in DEPENDS so we shouldn't be depending on this header.
+It may or may not exist from preivous builds though. To be determinstic, disable
+sdt.h usage always. This avoids build failures if the header is removed after configure
+but before libgcc is compiled for example.
+
+RP 2012/8/7
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Disable sdt for libstdc++-v3.
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+
+Upstream-Status: Inappropriate [hack]
+---
+ gcc/configure             | 12 ++++++------
+ gcc/configure.ac          | 18 +++++++++---------
+ libstdc++-v3/configure    |  6 +++---
+ libstdc++-v3/configure.ac |  2 +-
+ 4 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/gcc/configure b/gcc/configure
+index 3c550a6..01c7626 100755
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -26812,12 +26812,12 @@ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking sys/sdt.h in the target C library" >&5
+ $as_echo_n "checking sys/sdt.h in the target C library... " >&6; }
+ have_sys_sdt_h=no
+-if test -f $target_header_dir/sys/sdt.h; then
+-  have_sys_sdt_h=yes
+-
+-$as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
+-
+-fi
++#if test -f $target_header_dir/sys/sdt.h; then
++#  have_sys_sdt_h=yes
++#
++#$as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
++#
++#fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sys_sdt_h" >&5
+ $as_echo "$have_sys_sdt_h" >&6; }
+ 
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index 3601ab6..06e501f 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -4779,15 +4779,15 @@ if test x$gcc_cv_libc_provides_ssp = xyes; then
+ fi
+ 
+ # Test for <sys/sdt.h> on the target.
+-GCC_TARGET_TEMPLATE([HAVE_SYS_SDT_H])
+-AC_MSG_CHECKING(sys/sdt.h in the target C library)
+-have_sys_sdt_h=no
+-if test -f $target_header_dir/sys/sdt.h; then
+-  have_sys_sdt_h=yes
+-  AC_DEFINE(HAVE_SYS_SDT_H, 1,
+-            [Define if your target C library provides sys/sdt.h])
+-fi
+-AC_MSG_RESULT($have_sys_sdt_h)
++#GCC_TARGET_TEMPLATE([HAVE_SYS_SDT_H])
++#AC_MSG_CHECKING(sys/sdt.h in the target C library)
++#have_sys_sdt_h=no
++#if test -f $target_header_dir/sys/sdt.h; then
++#  have_sys_sdt_h=yes
++#  AC_DEFINE(HAVE_SYS_SDT_H, 1,
++#            [Define if your target C library provides sys/sdt.h])
++#fi
++#AC_MSG_RESULT($have_sys_sdt_h)
+ 
+ # Check if TFmode long double should be used by default or not.
+ # Some glibc targets used DFmode long double, but with glibc 2.4
+diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
+index 4953c9f..53a1145 100755
+--- a/libstdc++-v3/configure
++++ b/libstdc++-v3/configure
+@@ -20578,11 +20578,11 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ 
+-  if test $glibcxx_cv_sys_sdt_h = yes; then
++#  if test $glibcxx_cv_sys_sdt_h = yes; then
+ 
+-$as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
++#$as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
+ 
+-  fi
++#  fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_sys_sdt_h" >&5
+ $as_echo "$glibcxx_cv_sys_sdt_h" >&6; }
+ 
+diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
+index 73d430a..f2135e2 100644
+--- a/libstdc++-v3/configure.ac
++++ b/libstdc++-v3/configure.ac
+@@ -211,7 +211,7 @@ GLIBCXX_CHECK_SC_NPROCESSORS_ONLN
+ GLIBCXX_CHECK_SC_NPROC_ONLN
+ GLIBCXX_CHECK_PTHREADS_NUM_PROCESSORS_NP
+ GLIBCXX_CHECK_SYSCTL_HW_NCPU
+-GLIBCXX_CHECK_SDT_H
++#GLIBCXX_CHECK_SDT_H
+ 
+ # Check for available headers.
+ AC_CHECK_HEADERS([endian.h execinfo.h float.h fp.h ieeefp.h inttypes.h \
+-- 
+1.8.3.1
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0031.gcc.fix_adjust_sched_loopinv_cost.patch b/recipes-devtools/gcc/gcc-4.9/0031.gcc.fix_adjust_sched_loopinv_cost.patch
new file mode 100644
index 0000000..4ca0cc7
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0031.gcc.fix_adjust_sched_loopinv_cost.patch
@@ -0,0 +1,154 @@
+# Problem Statement:
+  Fix office-1.dither01 degradation with GCC v492.
+
+  Targets: e500mc & e5500 (32-bit).
+
+  There were 2 issues:
+  
+  a) lwzx and dependent cmp instruction were scheduled too close.
+  b) Loop invariant code being not moved out.
+
+# Owned by:
+  Rohit
+
+# Action:
+  a) Adjust the scheduler cost between lwzx and dependent cmp instruction
+     so that the lwzx instruction gets scheduled earlier.
+
+  b) Adjust the address cost so that the loop invariant code gets moved out.
+     Since the same cost calculation affects forward propagation, it causes
+     degradation in other benchmarks. So make this change specific to loop 
+     invariant code optimization.
+
+  c) Referenced test case is part of 'dither' benchmark code.
+
+diff -Naur gcc-4.9.2/gcc/config/rs6000/rs6000.c gcc-4.9.2-patch/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.2/gcc/config/rs6000/rs6000.c	2014-12-05 08:22:21.436670465 -0600
++++ gcc-4.9.2-patch/gcc/config/rs6000/rs6000.c	2014-12-05 08:24:04.223669496 -0600
+@@ -27009,6 +27009,19 @@
+             break;
+           }
+ 
++      if ((rs6000_cpu == CPU_PPCE500MC
++          || rs6000_cpu_attr == CPU_PPCE500MC64
++          || rs6000_cpu_attr == CPU_PPCE5500
++          || rs6000_cpu_attr == CPU_PPCE6500)
++          && recog_memoized (dep_insn)
++          && (INSN_CODE (dep_insn) >= 0)
++          && (GET_CODE (PATTERN (insn)) == SET)
++          && (GET_CODE (PATTERN (dep_insn)) == SET) 
++          && (get_attr_type (insn) == TYPE_CMP)
++          && (get_attr_type (dep_insn) == TYPE_LOAD)
++          && (GET_CODE (XEXP (PATTERN (dep_insn), 1)) == MEM)
++          && legitimate_indexed_address_p (XEXP((XEXP (PATTERN (dep_insn), 1)),0), false))
++        return cost + 3;
+ 	/* Fall out to return default cost.  */
+       }
+       break;
+diff -Naur gcc-4.9.2/gcc/config/rs6000/rs6000.c gcc-4.9.2-loop-invariant/gcc/config/rs6000/rs6000.c
+--- gcc-4.9.2/gcc/config/rs6000/rs6000.c	2014-12-29 08:34:13.858952006 -0600
++++ gcc-4.9.2-loop-invariant/gcc/config/rs6000/rs6000.c	2014-12-30 08:19:22.263951826 -0600
+@@ -85,6 +85,7 @@
+ #if TARGET_MACHO
+ #include "gstab.h"  /* for N_SLINE */
+ #endif
++#include "tree-pass.h"	/* for current_pass */
+ 
+ #ifndef TARGET_NO_PROTOTYPE
+ #define TARGET_NO_PROTOTYPE 0
+@@ -30547,6 +30548,11 @@
+         return 0;
+       return 5;
+     }
++  if (!strcmp (current_pass->name, "loop2_invariant")
++      && (GET_CODE (x) == LO_SUM)
++      && GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
++    return 5;
++
+   return 0; 
+ }
+ 
+diff -Naur gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv.c gcc-4.9.2-deja/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv.c
+--- gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.2-deja/gcc/testsuite/gcc.target/powerpc/ppc-fsl-loop-inv.c	2014-12-31 02:25:10.562952006 -0600
+@@ -0,0 +1,80 @@
++/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */
++/* { dg-options "-O3 -fdump-rtl-loop2_invariant" } */
++/* { dg-final { scan-rtl-dump-times "Decided to move" 10 "loop2_invariant"} } */
++/* { dg-final { cleanup-rtl-dump "loop2_invariant" } } */
++
++#include <string.h>
++unsigned char setmask[] =
++{
++    0x01, 0x02, 0x04, 0x08,
++    0x10, 0x20, 0x40, 0x80,
++};
++
++
++int threashold[] = { 139,138,122,120,131,135,109,130 };
++void ditherImage (unsigned char *input_buffer, int input_height,
++                         int input_width, unsigned char *output_buffer)
++{
++  int * c0;
++  int * c1;
++  int column;
++  int pixel;
++  unsigned char byte = 0;
++  int error;
++  int row;
++  int bit = 0;
++  int * temp;
++  int * err0;
++  int storage_err0[(2) * (256 +2*(1))];
++
++  memset((void*)output_buffer, 0,
++              (input_height * ((input_width-1)/(8)+1)));
++
++  err0 = storage_err0;
++  memset((void*)err0, 0,
++              (2) * (input_width+2*(1)) * sizeof(int));
++
++  c0 = err0 + (1);
++  c1 = c0 + input_width + 2*(1);
++
++  for (row = 0; row < input_height; ++row)
++  {
++    error = 0;
++    for (column = 0; column < input_width; ++column)
++    {
++      if ((pixel = *(input_buffer++)) == (255))
++        c0[column] = error = 0;
++      else
++      {
++        pixel += ((error * 8 + c1[column+1] * 3 + c1[column] * 5
++                  + c1[column-1] * 1)/16);
++        if (pixel < threashold[bit])
++        {
++          byte |= setmask[bit];
++          c0[column] = error = pixel;
++        }
++        else
++        {
++          c0[column] = error = pixel - (255);
++        }
++      }
++
++      if (++bit >= (8))
++      {
++        *(output_buffer++) = byte;
++        byte = bit = 0;
++      }
++    }
++
++    if (bit != 0)
++    {
++      *(output_buffer++) = byte;
++      byte = bit = 0;
++    }
++
++    temp = c0;
++    c0 = c1;
++    c1 = temp;
++  }
++  return;
++}
diff --git a/recipes-devtools/gcc/gcc-4.9/0032-libtool.patch b/recipes-devtools/gcc/gcc-4.9/0032-libtool.patch
new file mode 100644
index 0000000..3b3d1b6
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0032-libtool.patch
@@ -0,0 +1,42 @@
+From 6c715fcfa262adadca81c68a1f3f69aa3187a501 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:29:11 +0400
+Subject: [PATCH 32/35] libtool
+
+libstdc++ from gcc-runtime gets created with -rpath=/usr/lib/../lib for qemux86-64
+when running on am x86_64 build host.
+
+This patch stops this speading to libdir in the libstdc++.la file within libtool.
+Arguably, it shouldn't be passing this into libtool in the first place but
+for now this resolves the nastiest problems this causes.
+
+func_normal_abspath would resolve an empty path to `pwd` so we need
+to filter the zero case.
+
+RP 2012/8/24
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ ltmain.sh |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ltmain.sh b/ltmain.sh
+index a03433f..46f47c2 100644
+--- a/ltmain.sh
++++ b/ltmain.sh
+@@ -6359,6 +6359,10 @@ func_mode_link ()
+ 	func_warning "ignoring multiple \`-rpath's for a libtool library"
+ 
+       install_libdir="$1"
++      if test -n "$install_libdir"; then
++	func_normal_abspath "$install_libdir"
++	install_libdir=$func_normal_abspath_result
++      fi
+ 
+       oldlibs=
+       if test -z "$rpath"; then
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0032.gcc.fix_e5500_mulli_pipeline.patch b/recipes-devtools/gcc/gcc-4.9/0032.gcc.fix_e5500_mulli_pipeline.patch
new file mode 100644
index 0000000..05e3bab
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0032.gcc.fix_e5500_mulli_pipeline.patch
@@ -0,0 +1,36 @@
+# Problem Statement:
+  Fix consumer-1.rgbyiq01 degradation with GCC v492.
+  Target: e5500 64-bit.
+
+# Owned by:
+  Rohit
+
+# Action:
+  Add mulli pipeline to make sure that new multiply instruction cannot start
+  execution if another multiply is executing and is 3 cycles or less from
+  finishing execution.
+
+diff -Naur gcc-4.9.2/gcc/config/rs6000/e5500.md gcc-4.9.2-patch/gcc/config/rs6000/e5500.md
+--- gcc-4.9.2/gcc/config/rs6000/e5500.md	2014-01-02 16:23:26.000000000 -0600
++++ gcc-4.9.2-patch/gcc/config/rs6000/e5500.md	2014-12-06 10:19:45.328762009 -0600
+@@ -33,6 +33,9 @@
+ ;; Non-pipelined division.
+ (define_cpu_unit "e5500_cfx_div" "e5500_long")
+ 
++;; Mulli pipeline
++(define_cpu_unit "e5500_cfx_mulli" "e5500_long")
++
+ ;; LSU.
+ (define_cpu_unit "e5500_lsu" "e5500_most")
+ 
+@@ -108,8 +111,8 @@
+ (define_insn_reservation "e5500_multiply_i" 5
+   (and (eq_attr "type" "imul2,imul3,imul_compare")
+        (eq_attr "cpu" "ppce5500"))
+-  "e5500_decode,e5500_cfx_stage0,\
+-   e5500_cfx_stage0+e5500_cfx_stage1,e5500_cfx_stage1")
++  "e5500_decode,e5500_cfx_stage0+e5500_cfx_mulli,\
++   e5500_cfx_mulli*2")
+ 
+ ;; CFX - Divide.
+ (define_insn_reservation "e5500_divide" 16
diff --git a/recipes-devtools/gcc/gcc-4.9/0033-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch b/recipes-devtools/gcc/gcc-4.9/0033-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch
new file mode 100644
index 0000000..b236c37
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0033-gcc-armv4-pass-fix-v4bx-to-linker-to-support-EABI.patch
@@ -0,0 +1,40 @@
+From 97e4591c20310425e7aca0e6712a8d9480e7744c Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:30:32 +0400
+Subject: [PATCH 33/35] gcc: armv4: pass fix-v4bx to linker to support EABI.
+
+The LINK_SPEC for linux gets overwritten by linux-eabi.h which
+means the value of TARGET_FIX_V4BX_SPEC gets lost and as a result
+the option is not passed to linker when chosing march=armv4
+This patch redefines this in linux-eabi.h and reinserts it
+for eabi defaulting toolchains.
+
+We might want to send it upstream.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/config/arm/linux-eabi.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+Index: gcc-4.9-20140316/gcc/config/arm/linux-eabi.h
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/config/arm/linux-eabi.h
++++ gcc-4.9-20140316/gcc/config/arm/linux-eabi.h
+@@ -77,10 +77,14 @@
+     %{mfloat-abi=soft*:" GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "} \
+     %{!mfloat-abi=*:" GLIBC_DYNAMIC_LINKER_DEFAULT "}"
+ 
++/* For armv4 we pass --fix-v4bx to linker to support EABI */
++#undef TARGET_FIX_V4BX_SPEC
++#define TARGET_FIX_V4BX_SPEC "%{mcpu=arm8|mcpu=arm810|mcpu=strongarm*|march=armv4: --fix-v4bx}"
++
+ /* At this point, bpabi.h will have clobbered LINK_SPEC.  We want to
+    use the GNU/Linux version, not the generic BPABI version.  */
+ #undef  LINK_SPEC
+-#define LINK_SPEC EABI_LINK_SPEC					\
++#define LINK_SPEC TARGET_FIX_V4BX_SPEC EABI_LINK_SPEC			\
+   LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC,				\
+ 		       LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC)
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0033.gcc.fix_e500mc_addi_pipeline.patch b/recipes-devtools/gcc/gcc-4.9/0033.gcc.fix_e500mc_addi_pipeline.patch
new file mode 100644
index 0000000..f987f35
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0033.gcc.fix_e500mc_addi_pipeline.patch
@@ -0,0 +1,44 @@
+# Problem Statement:
+  Fix consumer-1.rgbyiq01 benchmark degradation with GCC v492.
+
+  Target: e500mc.
+
+  There were 2 issues:
+  * add/addi/addis instrutions were scheduled too close.
+  * Fixing the above issue lead to degradation in rgbcmy01 benchmark.
+    Reason being 'nor' instructions were scheduled too close.
+
+# Owned by:
+  Rohit
+
+# Action:
+  * Allocate SU resource such that "add/addi/addis" and "nor" instructions are
+    not scheduled closer.
+
+diff -Naur gcc-4.9.2/gcc/config/rs6000/rs6000.md gcc-4.9.2-rgbyiq/gcc/config/rs6000/rs6000.md
+--- gcc-4.9.2/gcc/config/rs6000/rs6000.md	2014-12-22 06:46:25.860952006 -0600
++++ gcc-4.9.2-rgbyiq/gcc/config/rs6000/rs6000.md	2014-12-31 06:25:34.421951939 -0600
+@@ -1863,7 +1863,10 @@
+    addi %0,%1,%2
+    addic %0,%1,%2
+    addis %0,%1,%v2"
+-  [(set_attr "length" "4,4,4,4")])
++  [(set_attr "length" "4,4,4,4")
++   (set (attr "type")
++        (if_then_else (match_test "rs6000_cpu_attr == CPU_PPCE500MC")
++                      (const_string "two") (const_string "*")))])
+ 
+ (define_insn "addsi3_high"
+   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
+@@ -1982,7 +1985,10 @@
+   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ 	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
+   ""
+-  "nor %0,%1,%1")
++  "nor %0,%1,%1"
++  [(set (attr "type")
++        (if_then_else (match_test "rs6000_cpu_attr == CPU_PPCE500MC")
++                      (const_string "two") (const_string "*")))])
+ 
+ (define_insn ""
+   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
diff --git a/recipes-devtools/gcc/gcc-4.9/0034-Use-the-multilib-config-files-from-B-instead-of-usin.patch b/recipes-devtools/gcc/gcc-4.9/0034-Use-the-multilib-config-files-from-B-instead-of-usin.patch
new file mode 100644
index 0000000..66b9f89
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0034-Use-the-multilib-config-files-from-B-instead-of-usin.patch
@@ -0,0 +1,102 @@
+From fc5e4beaea856a2b486c770ad3addc0f5bb3100e Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:33:04 +0400
+Subject: [PATCH 34/35] Use the multilib config files from ${B} instead of
+ using the ones from ${S}
+
+Use the multilib config files from ${B} instead of using the ones from ${S}
+so that the source can be shared between gcc-cross-initial,
+gcc-cross-intermediate, gcc-cross, gcc-runtime, and also the sdk build.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Signed-off-by: Constantin Musca <constantinx.musca@intel.com>
+
+Upstream-Status: Inappropriate [configuration]
+---
+ gcc/configure    |   22 ++++++++++++++++++----
+ gcc/configure.ac |   22 ++++++++++++++++++----
+ 2 files changed, 36 insertions(+), 8 deletions(-)
+
+diff --git a/gcc/configure b/gcc/configure
+index 8bc0c98..3cd0817 100755
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -11519,10 +11519,20 @@ done
+ tmake_file_=
+ for f in ${tmake_file}
+ do
+-	if test -f ${srcdir}/config/$f
+-	then
+-		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+-	fi
++  case $f in
++    */t-linux64 )
++       if test -f ./config/$f
++       then
++         tmake_file_="${tmake_file_} ./config/$f"
++       fi
++       ;;
++    * )
++       if test -f ${srcdir}/config/$f
++       then
++         tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
++       fi
++       ;;
++  esac
+ done
+ tmake_file="${tmake_file_}"
+ 
+@@ -11533,6 +11543,10 @@ tm_file_list="options.h"
+ tm_include_list="options.h insn-constants.h"
+ for f in $tm_file; do
+   case $f in
++    */linux64.h )
++       tm_file_list="${tm_file_list} ./config/$f"
++       tm_include_list="${tm_include_list} ./config/$f"
++       ;;
+     ./* )
+        f=`echo $f | sed 's/^..//'`
+        tm_file_list="${tm_file_list} $f"
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index 5e5e84f..415a6df 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -1700,10 +1700,20 @@ done
+ tmake_file_=
+ for f in ${tmake_file}
+ do
+-	if test -f ${srcdir}/config/$f
+-	then
+-		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+-	fi
++  case $f in
++    */t-linux64 )
++       if test -f ./config/$f
++       then
++         tmake_file_="${tmake_file_} ./config/$f"
++       fi
++       ;;
++    * )
++       if test -f ${srcdir}/config/$f
++       then
++         tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
++       fi
++       ;;
++  esac
+ done
+ tmake_file="${tmake_file_}"
+ 
+@@ -1714,6 +1724,10 @@ tm_file_list="options.h"
+ tm_include_list="options.h insn-constants.h"
+ for f in $tm_file; do
+   case $f in
++    */linux64.h )
++       tm_file_list="${tm_file_list} ./config/$f"
++       tm_include_list="${tm_include_list} ./config/$f"
++       ;;
+     ./* )
+        f=`echo $f | sed 's/^..//'`
+        tm_file_list="${tm_file_list} $f"
+-- 
+1.7.10.4
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0034.gcc.fix_ENGR00292364_debug_frame.patch b/recipes-devtools/gcc/gcc-4.9/0034.gcc.fix_ENGR00292364_debug_frame.patch
new file mode 100644
index 0000000..0355bba
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0034.gcc.fix_ENGR00292364_debug_frame.patch
@@ -0,0 +1,63 @@
+# Problem Statement:
+  For C++ applications, built with GCC v4.8.1, the CodeWarrior debugger
+  is not able to properly display the local variables because the frame
+  information is not generated in .debug_frame section as required by
+  the DWARF standard.
+
+  However, the compiler does emit the frame information but to avoid
+  duplication of information, by default, the GCC v4.8.1 generates the
+  frame information only in .eh_frame section, which is the more compact
+  form compared to .debug_frame section, with few additional details.
+
+# Reported by:
+  Hoang Tu
+
+# Owned by:
+  Ram
+
+# Action:
+  * Along with the .eh_frame section, changes are made in compiler DWARF
+    emission to generate the frame information in .debug_frame section also
+  * Added a new compiler flag '-fdebug-unwind-tables', which is disabled
+    by default in the compiler, to enable/disable the above changes
+
+
+diff -ruN gcc-4.8.1/gcc/common.opt gcc-4.8.1_ENGR00292364_Fix/gcc/common.opt
+--- gcc-4.8.1/gcc/common.opt	2014-02-17 09:24:10.067382984 -0600
++++ gcc-4.8.1_ENGR00292364_Fix/gcc/common.opt	2014-02-19 01:15:49.656381305 -0600
+@@ -984,6 +984,10 @@
+ Common Report Var(flag_debug_types_section) Init(0)
+ Output .debug_types section when using DWARF v4 debuginfo.
+ 
++fdebug-unwind-tables
++Common Report Var(flag_debug_unwind_tables) Init(0)
++Generate unwind tables in .debug_frame also, when exception unwind tables enabled
++
+ ; Nonzero for -fdefer-pop: don't pop args after each function call
+ ; instead save them up to pop many calls' args with one insns.
+ fdefer-pop
+diff -ruN gcc-4.8.1/gcc/dwarf2out.c gcc-4.8.1_ENGR00292364_Fix/gcc/dwarf2out.c
+--- gcc-4.8.1/gcc/dwarf2out.c	2014-02-17 09:24:31.621383000 -0600
++++ gcc-4.8.1_ENGR00292364_Fix/gcc/dwarf2out.c	2014-02-19 01:27:19.453383000 -0600
+@@ -21750,10 +21750,17 @@
+ dwarf2out_assembly_start (void)
+ {
+   if (HAVE_GAS_CFI_SECTIONS_DIRECTIVE
+-      && dwarf2out_do_cfi_asm ()
+-      && (!(flag_unwind_tables || flag_exceptions)
+-	  || targetm_common.except_unwind_info (&global_options) != UI_DWARF2))
+-    fprintf (asm_out_file, "\t.cfi_sections\t.debug_frame\n");
++      && dwarf2out_do_cfi_asm ())
++    {
++      if (!(flag_unwind_tables || flag_exceptions)
++	  || targetm_common.except_unwind_info (&global_options) != UI_DWARF2)
++        fprintf (asm_out_file, "\t.cfi_sections\t.debug_frame\n");
++
++      if (flag_debug_unwind_tables
++          && (flag_unwind_tables || flag_exceptions)
++          && targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
++        fprintf (asm_out_file, "\t.cfi_sections\t.eh_frame, .debug_frame\n");
++    }
+ }
+ 
+ /* A helper function for dwarf2out_finish called through
diff --git a/recipes-devtools/gcc/gcc-4.9/0035.gcc.fix_ENGR00215936_49x.patch b/recipes-devtools/gcc/gcc-4.9/0035.gcc.fix_ENGR00215936_49x.patch
new file mode 100644
index 0000000..f472a67
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0035.gcc.fix_ENGR00215936_49x.patch
@@ -0,0 +1,159 @@
+Remove redundant mov instructions.
+Issue: remove redundant move instructions.
+
+ addi 5,5,-1        addi 3,5,-1
+ mr 3,5          => blr
+ blr
+
+Here  these patters will not get gnerated by the time we call
+peephole2. Moreover we need cover lot of combination of instrctions
+like add/sub/div/mult/neg etc..and their varients and after changing the
+pattern register 3 should satisfy the constraints of previous add isntruction.
+otherwise compiler will crash at later stages.
+
+so preferred writting and generic check for these paterns in target specific
+reorg pass instead of adding using define_peephole.
+
+
+--- gcc-4.8.0-orig/gcc/config/rs6000/rs6000.c	2013-02-08 13:36:04.000000000 -0600
++++ gcc-4.8.0/gcc/config/rs6000/rs6000.c	2013-04-22 05:47:56.303264636 -0500
+@@ -940,6 +940,7 @@
+ static bool is_load_insn (rtx, rtx *);
+ static bool is_store_insn (rtx, rtx *);
+ static bool set_to_load_agen (rtx,rtx);
++static void rs6000_reorg (void);
+ static bool insn_terminates_group_p (rtx , enum group_termination);
+ static bool insn_must_be_first_in_group (rtx);
+ static bool insn_must_be_last_in_group (rtx);
+@@ -1221,6 +1222,8 @@
+ #define TARGET_SCHED_REORDER rs6000_sched_reorder
+ #undef TARGET_SCHED_REORDER2
+ #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
++#undef TARGET_MACHINE_DEPENDENT_REORG
++#define TARGET_MACHINE_DEPENDENT_REORG rs6000_reorg
+ 
+ #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+ #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
+@@ -23888,6 +23891,122 @@
+   return cached_can_issue_more;
+ }
+ 
++/* Implement TARGET_MACHINE_DEPENDENT_REORG.  */
++
++void
++remove_redundant_mov (void)
++{
++ basic_block bb;
++ rtx insn0,insn1,insn2,insn3;
++ rtx x,pat,pat0;
++ rtx operands[15];
++ 
++ FOR_EACH_BB_FN (bb, cfun)
++ {
++   FOR_BB_INSNS (bb,insn0)
++   {
++    insn1 = insn0;
++    if(insn1 == 0 )continue;
++    if (LABEL_P (insn1)
++       || BARRIER_P (insn1))insn1 = NEXT_INSN(insn1);
++    if(insn1 == 0)continue;
++
++    if (NEXT_INSN (insn1)
++       && BARRIER_P (NEXT_INSN (insn1)))continue;
++
++    while (NOTE_P (insn1)
++          || (NONJUMP_INSN_P (insn1)
++              && (GET_CODE (PATTERN (insn1)) == USE
++                 || GET_CODE (PATTERN (insn1)) == CLOBBER)))
++    {
++    	insn1 = NEXT_INSN (insn1);
++        if(insn1 == 0)break;
++    }
++    if(insn1 == 0)continue;
++
++    if (LABEL_P (insn1)
++      || BARRIER_P (insn1))continue;
++
++    pat = PATTERN (insn1);
++    x = pat0 = pat;
++    if (GET_CODE (x) != SET)continue;
++    x = XEXP (pat,0);
++    operands[0] = x;
++    if (! TARGET_POWERPC64)
++    {
++     if (! gpc_reg_operand (x, SImode))continue;
++    }
++    else
++    {
++     if (! gpc_reg_operand (x, DImode))continue;
++    } 
++    x = XEXP (XEXP (pat, 1), 0);
++    operands[1] = x;
++    insn2 = insn1;
++    do { insn2 = NEXT_INSN (insn2);
++       if (insn2 == 0) break; }
++    while (NOTE_P (insn2)
++         || (NONJUMP_INSN_P (insn2)
++             && (GET_CODE (PATTERN (insn2)) == USE
++                 || GET_CODE (PATTERN (insn2)) == CLOBBER)));
++    if(insn2 == 0)continue;
++    if (LABEL_P (insn2)
++        || BARRIER_P (insn2))continue;
++    pat = PATTERN (insn2);
++    x = pat;
++    if (GET_CODE (x) != SET)continue;
++    x = XEXP (pat, 0);
++    operands[3] = x;
++    if (! TARGET_POWERPC64)
++    {
++       if (! gpc_reg_operand (x, SImode))continue;
++    }
++    else
++    {
++       if (! gpc_reg_operand (x, DImode))continue;
++    }
++    x = XEXP (pat, 1);
++    if (!rtx_equal_p (operands[0], x))continue;
++    insn3 = insn2;
++    do { insn3 = NEXT_INSN (insn3);
++       if (insn3 == 0) break; }
++    while (NOTE_P (insn3)
++         || (NONJUMP_INSN_P (insn3)
++             && (GET_CODE (PATTERN (insn3)) == USE
++                 || GET_CODE (PATTERN (insn3)) == CLOBBER)));
++    if(insn3 == 0)continue;
++    if (LABEL_P (insn3)
++        || BARRIER_P (insn3))continue;
++    pat = PATTERN (insn3);
++    x = pat;
++    if (GET_CODE (x) != RETURN)continue;
++    if ((REGNO(operands[3]) == 3))
++    {
++      rtx ret_reg;
++      int insn_code_number;
++      
++      ret_reg = copy_rtx (operands[3]);
++      XEXP(pat0,0) = ret_reg;
++      insn_code_number = recog_memoized (insn1);
++      cleanup_subreg_operands (insn1);
++      if (! constrain_operands_cached (1))
++      {
++       /*operands does ot match to their constraints.so revert changes to insn*/
++        XEXP(pat0,0) = operands[0];
++      }
++      else
++        delete_insn (insn2);
++    }
++   }
++  }
++}
++
++static void
++rs6000_reorg (void)
++{
++  remove_redundant_mov ();
++}
++
+ /* Return whether the presence of INSN causes a dispatch group termination
+    of group WHICH_GROUP.
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0036.gcc.enable_soft_multilib-49x.patch b/recipes-devtools/gcc/gcc-4.9/0036.gcc.enable_soft_multilib-49x.patch
new file mode 100644
index 0000000..69872cf
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0036.gcc.enable_soft_multilib-49x.patch
@@ -0,0 +1,23 @@
+diff -Naur gcc-4.9.0/gcc/config/rs6000/t-linux64 gcc-4.9.0-soft-multilib/gcc/config/rs6000/t-linux64
+--- gcc-4.9.0/gcc/config/rs6000/t-linux64	2014-06-20 04:41:27.682372001 -0500
++++ gcc-4.9.0-soft-multilib/gcc/config/rs6000/t-linux64	2014-06-20 06:53:02.935374190 -0500
+@@ -25,11 +25,14 @@
+ # it doesn't tell anything about the 32bit libraries on those systems.  Set
+ # MULTILIB_OSDIRNAMES according to what is found on the target.
+ 
+-MULTILIB_OPTIONS    := m64/m32
+-MULTILIB_DIRNAMES   := 64 32
+-MULTILIB_EXTRA_OPTS := 
+-MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu)
+-MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
++MULTILIB_OPTIONS        = m64/m32 msoft-float
++MULTILIB_DIRNAMES       = 64 32 nof
++MULTILIB_EXTRA_OPTS     = fPIC mstrict-align
++MULTILIB_EXCEPTIONS     = m64/msoft-float
++MULTILIB_EXCLUSIONS     = m64/!m32/msoft-float
++MULTILIB_OSDIRNAMES     = ../lib64$(call if_multiarch,:powerpc64-linux-gnu)
++MULTILIB_OSDIRNAMES    += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) nof$(call if_multiarch,:powerpc-linux-gnu)
++MULTILIB_MATCHES        = $(MULTILIB_MATCHES_FLOAT)
+ 
+ rs6000-linux.o: $(srcdir)/config/rs6000/rs6000-linux.c
+ 	$(COMPILE) $<
diff --git a/recipes-devtools/gcc/gcc-4.9/0037.gcc.fix_49x-doc.patch b/recipes-devtools/gcc/gcc-4.9/0037.gcc.fix_49x-doc.patch
new file mode 100644
index 0000000..276d8d9
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0037.gcc.fix_49x-doc.patch
@@ -0,0 +1,30 @@
+diff -Naur gcc-4.9.0/libffi/doc/libffi.texi gcc-4.9.0-fix-doc/libffi/doc/libffi.texi
+--- gcc-4.9.0/libffi/doc/libffi.texi	2014-06-20 04:41:36.089371999 -0500
++++ gcc-4.9.0-fix-doc/libffi/doc/libffi.texi	2014-06-20 08:57:23.159371124 -0500
+@@ -378,26 +378,6 @@
+ You must first describe the structure to @samp{libffi} by creating a
+ new @code{ffi_type} object for it.
+ 
+-@tindex ffi_type
+-@deftp {Data type} ffi_type
+-The @code{ffi_type} has the following members:
+-@table @code
+-@item size_t size
+-This is set by @code{libffi}; you should initialize it to zero.
+-
+-@item unsigned short alignment
+-This is set by @code{libffi}; you should initialize it to zero.
+-
+-@item unsigned short type
+-For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
+-
+-@item ffi_type **elements
+-This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
+-objects.  There is one element per field of the struct.
+-@end table
+-@end deftp
+-
+-
+ @node Type Example
+ @subsection Type Example
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0038.gcc.fix_emulation_spec_48.patch b/recipes-devtools/gcc/gcc-4.9/0038.gcc.fix_emulation_spec_48.patch
new file mode 100644
index 0000000..deb5a64
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0038.gcc.fix_emulation_spec_48.patch
@@ -0,0 +1,56 @@
+# Problem Statement:
+  For e5500/e6500 bare-board tool chain, when '-m64' option is used,
+  the corresponding emulation option '-melf64ppc' is not being passed
+  to the linker by default.
+
+# Reported by:
+  Rohit [23.April.2013]
+
+# Owned by:
+  Rohit
+
+# Action:
+  * Update the header file e500mc.h to set appropriate target macros.
+  * AEABI is a proxy for Linux ABI, so these changes should not affect
+    e500mc (EABI) tool chain.
+  * Fix typo in config.gcc file
+
+diff -Naur gcc-4.7.2/gcc/config/rs6000/e500mc.h gcc-4.7.2-emulation-spec/gcc/config/rs6000/e500mc.h
+--- gcc-4.7.2/gcc/config/rs6000/e500mc.h	2013-05-31 07:40:08.638001570 -0500
++++ gcc-4.7.2-emulation-spec/gcc/config/rs6000/e500mc.h	2013-05-31 07:39:34.794001566 -0500
+@@ -83,6 +83,8 @@
+   { "asm_spec_common",		ASM_SPEC_COMMON },			\
+   { "asm_spec32",		ASM_SPEC32 },				\
+   { "asm_spec64",		ASM_SPEC64 },				\
++  { "link_os_linux_spec32",	LINK_OS_LINUX_SPEC32 },			\
++  { "link_os_linux_spec64",	LINK_OS_LINUX_SPEC64 },
+ 
+ #undef	MULTILIB_DEFAULTS
+ #if DEFAULT_ARCH64_P
+@@ -170,6 +172,14 @@
+     }							\
+   while (0)
+ 
++#ifdef RS6000BI_ARCH_P
++#undef	LINK_OS_DEFAULT_SPEC
++#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
++#endif
++
++#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux"
++#define LINK_OS_LINUX_SPEC64 "-m elf64ppc"
++
+ /* Must be at least as big as our pointer type.  */
+ #undef	SIZE_TYPE
+ #define	SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
+diff -Naur gcc-4.7.2/gcc/config.gcc gcc-4.7.2-emulation-spec/gcc/config.gcc
+--- gcc-4.7.2/gcc/config.gcc	2013-05-31 07:40:01.544000724 -0500
++++ gcc-4.7.2-emulation-spec/gcc/config.gcc	2013-05-31 07:39:32.758001571 -0500
+@@ -421,7 +421,7 @@
+ 	extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h"
+ 	need_64bit_hwint=yes
+ 	case x$with_cpu in
+-	    xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[345678]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|Xe6500)
++	    xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[345678]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|xe6500)
+ 		cpu_is_64bit=yes
+ 		;;
+ 	esac
diff --git a/recipes-devtools/gcc/gcc-4.9/0039.gcc.create_maeabi.patch b/recipes-devtools/gcc/gcc-4.9/0039.gcc.create_maeabi.patch
new file mode 100644
index 0000000..f247d42
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0039.gcc.create_maeabi.patch
@@ -0,0 +1,746 @@
+--- gcc-4.7.2/gcc/config/rs6000/sysv4.opt-orig  2013-03-29 13:13:27.001603071 -0500
++++ gcc-4.7.2/gcc/config/rs6000/sysv4.opt       2013-03-29 13:15:05.637602550 -0500
+@@ -117,6 +117,10 @@
+ Target RejectNegative
+ Link with libsim.a, libc.a and sim-crt0.o
+ 
++maeabi
++Target RejectNegative
++Link with libaeabi.a, crtaeabi0.o and crtaeabi9.o
++
+ mads
+ Target RejectNegative
+ Link with libads.a, libc.a and crt0.o
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/e500mc.h gcc-4.7.3-new/gcc/config/rs6000/e500mc.h
+--- gcc-4.7.3-orig/gcc/config/rs6000/e500mc.h	2013-04-29 16:40:59.759000075 -0500
++++ gcc-4.7.3-new/gcc/config/rs6000/e500mc.h	2013-04-29 18:32:49.436000171 -0500
+@@ -84,7 +84,22 @@
+   { "asm_spec32",		ASM_SPEC32 },				\
+   { "asm_spec64",		ASM_SPEC64 },				\
+   { "link_os_linux_spec32",	LINK_OS_LINUX_SPEC32 },			\
+-  { "link_os_linux_spec64",	LINK_OS_LINUX_SPEC64 },
++  { "link_os_linux_spec64",	LINK_OS_LINUX_SPEC64 },                 \
++  { "startfile_aeabi",          STARTFILE_AEABI_SPEC },                 \
++  { "lib_aeabi",                LIB_AEABI_SPEC },                       \
++  { "endfile_aeabi",            ENDFILE_AEABI_SPEC },
++
++#define STARTFILE_AEABI_SPEC ""
++#define LIB_AEABI_SPEC ""
++#define ENDFILE_AEABI_SPEC ""
++
++/* This is the case of e5500 and e6500 targets */
++#undef STARTFILE_AEABI_SPEC
++#undef LIB_AEABI_SPEC
++#undef ENDFILE_AEABI_SPEC
++#define STARTFILE_AEABI_SPEC "%{m32:-m elf32ppc} %{m64:-m elf64ppc} %{!m32:%{!m64:-m elf32ppc}} ecrti.o%s crtaeabi0.o%s crtbegin.o%s"
++#define LIB_AEABI_SPEC "--start-group -laeabi -lc --end-group"
++#define ENDFILE_AEABI_SPEC "crtend.o%s crtaeabi9.o%s ecrtn.o%s"
+ 
+ #undef	MULTILIB_DEFAULTS
+ #if DEFAULT_ARCH64_P
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/crtaeabi0.S gcc-4.7.3-new/gcc/config/rs6000/libaeabi/crtaeabi0.S
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/crtaeabi0.S	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/crtaeabi0.S	2013-04-29 18:34:39.483000083 -0500
+@@ -0,0 +1,57 @@
++/*
++ * crt0.S -- startup file for PowerPC systems.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++#include "ppc-asm.h"
++
++	.file	"sim-crt0.S"
++	.text
++FUNC_START(_start)
++	lis	r0,0
++	stw	r0,0(sp)	/* clear back chain */
++	stwu	sp,-64(sp)	/* push another stack frame */
++
++	/* Let her rip */
++#if defined (__powerpc64__)
++	.section ".init"
++._init:
++	.text
++	bl	FUNC_NAME(_init)
++	nop
++	/* return value from main is argument to exit */
++	bl	FUNC_NAME(exit)
++	nop
++#else
++	bl	FUNC_NAME(__init)
++	bl	FUNC_NAME(main)#
++	/* return value from main is argument to exit */
++	bl	FUNC_NAME(exit)
++#endif
++FUNC_END(_start)
++
++	.extern	FUNC_NAME(atexit)
++	.globl	FUNC_NAME(__atexit)
++	.section ".sdata","aw"
++	.align	2
++FUNC_NAME(__atexit):			/* tell C's eabi-ctor's we have an atexit function */
++#if defined (__powerpc64__)
++	.long	FUNC_NAME(atexit)	/* and that it is to register __do_global_dtors */
++#else
++	.long	FUNC_NAME(atexit)@fixup	/* and that it is to register __do_global_dtors */
++
++	.section ".fixup","aw"
++	.align	2
++	.long	FUNC_NAME(__atexit)
++#endif
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/crtaeabi9.S gcc-4.7.3-new/gcc/config/rs6000/libaeabi/crtaeabi9.S
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/crtaeabi9.S	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/crtaeabi9.S	2013-04-29 18:34:39.498000079 -0500
+@@ -0,0 +1,12 @@
++#include "ppc-asm.h"
++
++	.file	"sim-crt9.S"
++
++#if defined (__powerpc64__)
++	.section ".init","ax"
++	bl	FUNC_NAME(main)
++	nop
++	/* return value from main is argument to exit */
++	bl	FUNC_NAME(exit)
++	nop
++#endif
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/fstat.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/fstat.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/fstat.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/fstat.c	2013-04-29 18:34:39.518000116 -0500
+@@ -0,0 +1,30 @@
++/* fstat.c -- get status of a file.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include <sys/stat.h>
++#include "glue.h"
++
++/*
++ * fstat -- Since we have no file system, we just return an error.
++ */
++int
++_DEFUN (fstat, (fd, buf),
++       int fd _AND
++       struct stat *buf)
++{
++  buf->st_mode = S_IFCHR;	/* Always pretend to be a tty */
++  buf->st_blksize = 0;
++
++  return (0);
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/getpid.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/getpid.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/getpid.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/getpid.c	2013-04-29 18:34:39.562000126 -0500
+@@ -0,0 +1,25 @@
++/* getpid.c -- get the current process id.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include "glue.h"
++
++/*
++ * getpid -- only one process, so just return 1.
++ */
++int
++_DEFUN (getpid, (),
++        )
++{
++  return __MYPID;
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/glue.h gcc-4.7.3-new/gcc/config/rs6000/libaeabi/glue.h
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/glue.h	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/glue.h	2013-04-29 18:34:39.581999971 -0500
+@@ -0,0 +1,31 @@
++/* glue.h -- common definitions for "glue" fucntions.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include <_ansi.h>
++
++#ifndef NULL
++#  define NULL 0
++#endif
++
++#ifdef __NO_UNDERSCORE__
++#  define _end    end
++#  define _exit	  exit
++#endif
++
++extern char _end[];                /* _end is set in the linker command file */
++
++/* only one prcess support, as this is OS dependant */
++#define __MYPID 1
++
++
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/isatty.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/isatty.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/isatty.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/isatty.c	2013-04-29 18:34:39.603000235 -0500
+@@ -0,0 +1,27 @@
++/* isatty.c -- chek the terminal device.
++ * 
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include "glue.h"
++
++/*
++ * isatty -- returns 1 if connected to a terminal device,
++ *           returns 0 if not. Since we're hooked up to a
++ *           serial port, we'll say yes _AND return a 1.
++ */
++int
++_DEFUN (isatty, (fd),
++       int fd)
++{
++  return (1);
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/kill.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/kill.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/kill.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/kill.c	2013-04-29 18:34:39.627000022 -0500
+@@ -0,0 +1,29 @@
++/* kill.c -- remove a process.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include <unistd.h>
++#include "glue.h"
++
++/*
++ * kill -- go out via exit...
++ */
++int
++_DEFUN (kill, (pid, sig),
++        int pid _AND 
++        int sig)
++{
++  if(pid == __MYPID)
++    _exit(sig);
++  return 0;
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/mcount.S gcc-4.7.3-new/gcc/config/rs6000/libaeabi/mcount.S
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/mcount.S	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/mcount.S	2013-04-29 18:34:39.669000101 -0500
+@@ -0,0 +1,27 @@
++/*
++ * mcount.S -- dummy module for profiling.
++ *
++ * Copyright (c) 1997 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++#include "ppc-asm.h"
++
++	.file	"mcount-dummy.S"
++	.text
++FUNC_START(_mcount)
++	mflr	r11
++	lwz	r0,4(sp)
++	mtctr	r11
++	mtlr	r0
++	bctr
++FUNC_END(_mcount)
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/putnum.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/putnum.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/putnum.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/putnum.c	2013-04-29 18:34:39.678000079 -0500
+@@ -0,0 +1,41 @@
++/* putnum.c -- put a hex number on the output device.
++ * 
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include "glue.h"
++
++/*
++ * putnum -- print a 32 bit number in hex
++ */
++void
++_DEFUN (putnum, (num),
++	unsigned int num)
++{
++  char  buf[9];
++  int   cnt;
++  char  *ptr;
++  int   digit;
++  
++  ptr = buf;
++  for (cnt = 7 ; cnt >= 0 ; cnt--) {
++    digit = (num >> (cnt * 4)) & 0xf;
++    
++    if (digit <= 9)
++      *ptr++ = (char) ('0' + digit);
++    else
++      *ptr++ = (char) ('a' - 10 + digit);
++  }
++
++  *ptr = (char) 0;
++  print (buf);
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-abort.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-abort.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-abort.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-abort.c	2013-04-29 18:34:39.700000034 -0500
+@@ -0,0 +1,22 @@
++/*
++ * sim-abort.c -- PowerPC abort support when running under the simulator.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++#include <stdlib.h>
++void abort(void)
++{
++  write (2, "Abort called.\n", sizeof("Abort called.\n")-1);
++  exit (1);
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-errno.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-errno.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-errno.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-errno.c	2013-04-29 18:34:39.707000107 -0500
+@@ -0,0 +1,28 @@
++/*
++ * sim-errno.c -- return address of errno for current thread.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++#include <errno.h>
++#include <reent.h>
++
++/* syscall handler branches here in case of error. */
++
++int
++_cerror (e)
++     int e;
++{
++  _REENT->_errno = e;
++  return -1;
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-getrusage.S gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-getrusage.S
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-getrusage.S	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-getrusage.S	2013-04-29 18:34:39.727999978 -0500
+@@ -0,0 +1,25 @@
++/*
++ * sim-getrusage.S -- PowerPC simulator getrusage call.
++ *
++ * Copyright (c) 1995, 2000, 2001 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++#include "ppc-asm.h"
++
++FUNC_START(getrusage)
++	li	r0,117
++	sc
++	bns+	0f
++	b	FUNC_NAME(_cerror)
++0:	blr
++FUNC_END(getrusage)
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-inbyte.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-inbyte.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-inbyte.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-inbyte.c	2013-04-29 18:34:39.751000179 -0500
+@@ -0,0 +1,26 @@
++/*
++ * sim-inbyte.c -- read a character from standard input.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++int
++inbyte ()
++{
++  char c;
++
++  if (read (0, &c, 1) <= 0)
++    return -1;
++
++  return c;
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-print.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-print.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-print.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-print.c	2013-04-29 18:34:39.768999944 -0500
+@@ -0,0 +1,43 @@
++/* sim-print.c -- print a string on the output device.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++/*
++ * print -- do a raw print of a string
++ */ 
++void
++print (ptr)
++     char *ptr;
++{
++  int len = 0;
++  char *p = ptr;
++
++  while (*p != '\0')
++    p++;
++
++  write (1, ptr, p-ptr);
++}
++
++/*
++ * outbyte -- write a single character.
++ */
++
++void
++outbyte (c_int)
++     int c_int;
++{
++  char c = c_int;
++
++  write (1, &c, 1);
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-sbrk.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-sbrk.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/sim-sbrk.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/sim-sbrk.c	2013-04-29 18:34:39.789000253 -0500
+@@ -0,0 +1,31 @@
++/*
++ * sim-sbrk.c -- PowerPC sbrk support when running under the simulator.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++extern char _end[];
++static char *curbrk = _end;
++extern char *brk(char *);
++
++char *
++sbrk (incr)
++     int incr;
++{
++  char *oldbrk = curbrk;
++  curbrk = brk (oldbrk + incr);
++  if (curbrk == oldbrk)
++    return (char *) -1;
++
++  return oldbrk;
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/simulator.S gcc-4.7.3-new/gcc/config/rs6000/libaeabi/simulator.S
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/simulator.S	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/simulator.S	2013-04-29 18:34:39.810999897 -0500
+@@ -0,0 +1,95 @@
++/*
++ * simulator.S -- PowerPC simulator system calls.
++ *
++ * Copyright (c) 1995, 2000, 2001 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++
++#include "ppc-asm.h"
++
++FUNC_START(_exit)
++	li	r0, 1
++	sc
++
++/*
++ * Insure that the debugger tells the client that the PC is in _exit,
++ * not whatever function happens to follow this function.
++ */
++
++0:	trap
++	b	0b			/* we never should return, but... */
++
++FUNC_END(_exit)
++
++FUNC_START(read)
++	li	r0,3
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(read)
++
++FUNC_START(write)
++	li	r0,4
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(write)
++
++FUNC_START(open)
++	li	r0,5
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(open)
++
++FUNC_START(close)
++	li	r0,6
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(close)
++
++FUNC_START(brk)
++	li	r0,45
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(brk)
++
++FUNC_START(access)
++	li	r0,33
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(access)
++
++FUNC_START(dup)
++	li	r0,41
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(dup)
++
++FUNC_START(gettimeofday)
++	li	r0,116
++	sc
++	bns+	0f
++	b	FUNC_NAME(_cerror)
++0:	blr
++FUNC_END(gettimeofday)
++
++FUNC_START(lseek)
++	li	r0,199
++	sc
++	bnslr+
++	b	FUNC_NAME(_cerror)
++FUNC_END(lseek)
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/stat.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/stat.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/stat.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/stat.c	2013-04-29 18:34:39.826000177 -0500
+@@ -0,0 +1,30 @@
++/* stat.c -- Get the status of a file.
++ *
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include <sys/stat.h>
++#include <errno.h>
++#include "glue.h"
++
++/*
++ * stat -- Since we have no file system, we just return an error.
++ */
++int
++_DEFUN (stat, (path, buf),
++       const char *path _AND
++       struct stat *buf)
++{
++  errno = EIO;
++  return (-1);
++}
++
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/unlink.c gcc-4.7.3-new/gcc/config/rs6000/libaeabi/unlink.c
+--- gcc-4.7.3-orig/gcc/config/rs6000/libaeabi/unlink.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.7.3-new/gcc/config/rs6000/libaeabi/unlink.c	2013-04-29 18:34:39.846999914 -0500
+@@ -0,0 +1,28 @@
++/* unlink.c -- remove a file.
++ * 
++ * Copyright (c) 1995 Cygnus Support
++ *
++ * The authors hereby grant permission to use, copy, modify, distribute,
++ * and license this software and its documentation for any purpose, provided
++ * that existing copyright notices are retained in all copies and that this
++ * notice is included verbatim in any distributions. No written agreement,
++ * license, or royalty fee is required for any of the authorized uses.
++ * Modifications to this software may be copyrighted by their authors
++ * and need not follow the licensing terms described here, provided that
++ * the new terms are clearly indicated on the first page of each file where
++ * they apply.
++ */
++#include <errno.h>
++#include "glue.h"
++
++/*
++ * unlink -- since we have no file system, 
++ *           we just return an error.
++ */
++int
++_DEFUN (unlink, (path),
++        char * path)
++{
++  errno = EIO;
++  return (-1);
++}
+diff -ruN gcc-4.7.3-orig/gcc/config/rs6000/sysv4.h gcc-4.7.3-new/gcc/config/rs6000/sysv4.h
+--- gcc-4.7.3-orig/gcc/config/rs6000/sysv4.h	2013-04-29 16:40:59.757000074 -0500
++++ gcc-4.7.3-new/gcc/config/rs6000/sysv4.h	2013-04-29 18:10:58.189000389 -0500
+@@ -673,6 +673,7 @@
+   mcall-linux  : %(startfile_linux)       ; \
+   mcall-netbsd : %(startfile_netbsd)      ; \
+   mcall-openbsd: %(startfile_openbsd)     ; \
++  maeabi       : %(startfile_aeabi)       ; \
+                : %(startfile_default)     }"
+ 
+ #define	STARTFILE_DEFAULT_SPEC "ecrti.o%s crtbegin.o%s"
+@@ -687,6 +688,7 @@
+   mcall-linux  : %(lib_linux)       ; \
+   mcall-netbsd : %(lib_netbsd)      ; \
+   mcall-openbsd: %(lib_openbsd)     ; \
++  maeabi       : %(lib_aeabi)       ; \
+                : %(lib_default)     }"
+ 
+ #define LIB_DEFAULT_SPEC "-lc"
+@@ -701,6 +703,7 @@
+   mcall-linux  : %(endfile_linux)       ; \
+   mcall-netbsd : %(endfile_netbsd)      ; \
+   mcall-openbsd: %(endfile_openbsd)     ; \
++  maeabi       : %(endfile_aeabi)       ; \
+                : %(crtsavres_default) %(endfile_default)     }"
+ 
+ #define CRTSAVRES_DEFAULT_SPEC ""
diff --git a/recipes-devtools/gcc/gcc-4.9/0040-fix-g++-sysroot.patch b/recipes-devtools/gcc/gcc-4.9/0040-fix-g++-sysroot.patch
new file mode 100644
index 0000000..d50aa5c
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0040-fix-g++-sysroot.patch
@@ -0,0 +1,40 @@
+Portions of
+
+http://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg26013.html
+
+are not upstreamed yet. So lets keep missing pieces.
+
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Index: gcc-4.8.1/gcc/configure.ac
+===================================================================
+--- gcc-4.8.1.orig/gcc/configure.ac	2013-07-15 15:55:49.488399132 -0700
++++ gcc-4.8.1/gcc/configure.ac	2013-07-15 16:02:31.772406679 -0700
+@@ -148,7 +148,9 @@
+ if test "${with_sysroot+set}" = set; then
+   gcc_gxx_without_sysroot=`expr "${gcc_gxx_include_dir}" : "${with_sysroot}"'\(.*\)'`
+   if test "${gcc_gxx_without_sysroot}"; then
+-    gcc_gxx_include_dir="${gcc_gxx_without_sysroot}"
++    if test x${with_sysroot} != x/; then
++      gcc_gxx_include_dir="${gcc_gxx_without_sysroot}"
++    fi
+     gcc_gxx_include_dir_add_sysroot=1
+   fi
+ fi
+Index: gcc-4.8.1/gcc/configure
+===================================================================
+--- gcc-4.8.1.orig/gcc/configure	2013-07-15 15:55:49.472399132 -0700
++++ gcc-4.8.1/gcc/configure	2013-07-15 16:02:31.780406680 -0700
+@@ -3325,7 +3325,9 @@
+ if test "${with_sysroot+set}" = set; then
+   gcc_gxx_without_sysroot=`expr "${gcc_gxx_include_dir}" : "${with_sysroot}"'\(.*\)'`
+   if test "${gcc_gxx_without_sysroot}"; then
+-    gcc_gxx_include_dir="${gcc_gxx_without_sysroot}"
++    if test x${with_sysroot} != x/; then
++      gcc_gxx_include_dir="${gcc_gxx_without_sysroot}"
++    fi
+     gcc_gxx_include_dir_add_sysroot=1
+   fi
+ fi
diff --git a/recipes-devtools/gcc/gcc-4.9/0040.gcc.rm_e500v2_loops_48.patch b/recipes-devtools/gcc/gcc-4.9/0040.gcc.rm_e500v2_loops_48.patch
new file mode 100644
index 0000000..821ff3e
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0040.gcc.rm_e500v2_loops_48.patch
@@ -0,0 +1,795 @@
+diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_default_init_1.f90 b/gcc/testsuite/gfortran.dg/alloc_comp_default_init_1.f90
+deleted file mode 100644
+index 48947cd..0000000
+--- a/gcc/testsuite/gfortran.dg/alloc_comp_default_init_1.f90
++++ /dev/null
+@@ -1,84 +0,0 @@
+-! { dg-do run }
+-! Checks the fixes for PR34681 and PR34704, in which various mixtures
+-! of default initializer and allocatable array were not being handled
+-! correctly for derived types with allocatable components.
+-!
+-! Contributed by Paolo Giannozzi <p.giannozzi@fisica.uniud.it>
+-!
+-program boh
+-  integer :: c1, c2, c3, c4, c5
+-  !
+-  call mah (0, c1) ! These calls deal with PR34681
+-  call mah (1, c2)
+-  call mah (2, c3)
+-  !
+-  if (c1 /= c2) call abort
+-  if (c1 /= c3) call abort
+-  !
+-  call mah0 (c4) ! These calls deal with PR34704
+-  call mah1 (c5)
+-  !
+-  if (c4 /= c5) call abort
+-  !
+-end program boh
+-!
+-subroutine mah (i, c)
+-  !
+-  integer, intent(in) :: i
+-  integer, intent(OUT) :: c
+-  !
+-  type mix_type
+-     real(8), allocatable :: a(:)
+-     complex(8), allocatable :: b(:)
+-  end type mix_type
+-  type(mix_type), allocatable, save :: t(:)
+-  integer :: j, n=1024
+-  !
+-  if (i==0) then
+-     allocate (t(1))
+-     allocate (t(1)%a(n))
+-     allocate (t(1)%b(n))
+-     do j=1,n
+-        t(1)%a(j) = j
+-        t(1)%b(j) = n-j
+-     end do
+-  end if
+-  c = sum( t(1)%a(:) ) + sum( t(1)%b(:) )
+-  if ( i==2) then
+-     deallocate (t(1)%b)
+-     deallocate (t(1)%a)
+-     deallocate (t)
+-  end if
+-end subroutine mah
+-
+-subroutine mah0 (c)
+-  !
+-  integer, intent(OUT) :: c
+-  type mix_type
+-     real(8), allocatable :: a(:)
+-     integer :: n=1023
+-  end type mix_type
+-  type(mix_type) :: t
+-  !
+-  allocate(t%a(1))
+-  t%a=3.1415926
+-  c = t%n
+-  deallocate(t%a)
+-  !
+-end subroutine mah0
+-!
+-subroutine mah1 (c)
+-  !
+-  integer, intent(OUT) :: c
+-  type mix_type
+-     real(8), allocatable :: a(:)
+-     integer :: n=1023
+-  end type mix_type
+-  type(mix_type), save :: t
+-  !
+-  allocate(t%a(1))
+-  t%a=3.1415926
+-  c = t%n
+-  deallocate(t%a)
+-  !
+-end subroutine mah1
+diff -ruN gcc-4.8.0-orig/gcc/testsuite/gfortran.dg/specifics_1.f90 gcc-4.8.0/gcc/testsuite/gfortran.dg/specifics_1.f90
+--- gcc-4.8.0-orig/gcc/testsuite/gfortran.dg/specifics_1.f90	2013-05-06 13:02:17.560000510 -0500
++++ gcc-4.8.0/gcc/testsuite/gfortran.dg/specifics_1.f90	1969-12-31 18:00:00.000000000 -0600
+@@ -1,318 +0,0 @@
+-! Program to test intrinsic functions as actual arguments
+-!
+-! Copied from gfortran.fortran-torture/execute/specifics.f90
+-! Please keep them in sync
+-!
+-! It is run here with -ff2c option
+-!
+-! { dg-do run }
+-! { dg-options "-ff2c" }
+-! Program to test intrinsic functions as actual arguments
+-subroutine test_c(fn, val, res)
+-  complex fn
+-  complex val, res
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  complex a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_z(fn, val, res)
+-  double complex fn
+-  double complex val, res
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  double complex a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_cabs(fn, val, res)
+-  real fn, res
+-  complex val
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  real a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_cdabs(fn, val, res)
+-  double precision fn, res
+-  double complex val
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  double precision a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_r(fn, val, res)
+-  real fn
+-  real val, res
+-
+-  if (diff(fn(val), res)) call abort
+-contains
+-function diff(a, b)
+-  real a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine
+-
+-subroutine test_d(fn, val, res)
+-  double precision fn
+-  double precision val, res
+-
+-  if (diff(fn(val), res)) call abort
+-contains
+-function diff(a, b)
+-  double precision a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001d0)
+-end function
+-end subroutine
+-
+-subroutine test_r2(fn, val1, val2, res)
+-  real fn
+-  real val1, val2, res
+-
+-  if (diff(fn(val1, val2), res)) call abort
+-contains
+-function diff(a, b)
+-  real a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine
+-
+-subroutine test_d2(fn, val1, val2, res)
+-  double precision fn
+-  double precision val1, val2, res
+-
+-  if (diff(fn(val1, val2), res)) call abort
+-contains
+-function diff(a, b)
+-  double precision a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001d0)
+-end function
+-end subroutine
+-
+-subroutine test_dprod(fn)
+-  double precision fn
+-  if (abs (fn (2.0, 3.0) - 6d0) .gt. 0.00001) call abort
+-end subroutine
+-
+-subroutine test_nint(fn,val,res)
+-  integer fn, res
+-  real val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_idnint(fn,val,res)
+-  integer fn, res
+-  double precision val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_idim(fn,val1,val2,res)
+-  integer fn, res, val1, val2
+-  if (res .ne. fn(val1,val2)) call abort
+-end subroutine
+-
+-subroutine test_iabs(fn,val,res)
+-  integer fn, res, val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_len(fn,val,res)
+-  integer fn, res
+-  character(len=*) val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_index(fn,val1,val2,res)
+-  integer fn, res
+-  character(len=*) val1, val2
+-  if (fn(val1,val2) .ne. res) call abort
+-end subroutine
+-
+-program specifics
+-  intrinsic abs
+-  intrinsic aint
+-  intrinsic anint
+-  intrinsic acos
+-  intrinsic acosh
+-  intrinsic asin
+-  intrinsic asinh
+-  intrinsic atan
+-  intrinsic atanh
+-  intrinsic cos
+-  intrinsic sin
+-  intrinsic tan
+-  intrinsic cosh
+-  intrinsic sinh
+-  intrinsic tanh
+-  intrinsic alog
+-  intrinsic alog10
+-  intrinsic exp
+-  intrinsic sign
+-  intrinsic isign
+-  intrinsic amod
+-
+-  intrinsic dabs
+-  intrinsic dint
+-  intrinsic dnint
+-  intrinsic dacos
+-  intrinsic dacosh
+-  intrinsic dasin
+-  intrinsic dasinh
+-  intrinsic datan
+-  intrinsic datanh
+-  intrinsic dcos
+-  intrinsic dsin
+-  intrinsic dtan
+-  intrinsic dcosh
+-  intrinsic dsinh
+-  intrinsic dtanh
+-  intrinsic dlog
+-  intrinsic dlog10
+-  intrinsic dexp
+-  intrinsic dsign
+-  intrinsic dmod
+-
+-  intrinsic conjg
+-  intrinsic ccos
+-  intrinsic cexp
+-  intrinsic clog
+-  intrinsic csin
+-  intrinsic csqrt
+-
+-  intrinsic dconjg
+-  intrinsic cdcos
+-  intrinsic cdexp
+-  intrinsic cdlog
+-  intrinsic cdsin
+-  intrinsic cdsqrt
+-  intrinsic zcos
+-  intrinsic zexp
+-  intrinsic zlog
+-  intrinsic zsin
+-  intrinsic zsqrt
+-
+-  intrinsic cabs
+-  intrinsic cdabs
+-  intrinsic zabs
+-
+-  intrinsic dprod
+-
+-  intrinsic nint
+-  intrinsic idnint
+-  intrinsic dim
+-  intrinsic ddim
+-  intrinsic idim
+-  intrinsic iabs
+-  intrinsic mod
+-  intrinsic len
+-  intrinsic index
+-
+-  intrinsic aimag
+-  intrinsic dimag
+-
+-  call test_r (abs, -1.0, abs(-1.0))
+-  call test_r (aint, 1.7, aint(1.7))
+-  call test_r (anint, 1.7, anint(1.7))
+-  call test_r (acos, 0.5, acos(0.5))
+-  call test_r (acosh, 1.5, acosh(1.5))
+-  call test_r (asin, 0.5, asin(0.5))
+-  call test_r (asinh, 0.5, asinh(0.5))
+-  call test_r (atan, 0.5, atan(0.5))
+-  call test_r (atanh, 0.5, atanh(0.5))
+-  call test_r (cos, 1.0, cos(1.0))
+-  call test_r (sin, 1.0, sin(1.0))
+-  call test_r (tan, 1.0, tan(1.0))
+-  call test_r (cosh, 1.0, cosh(1.0))
+-  call test_r (sinh, 1.0, sinh(1.0))
+-  call test_r (tanh, 1.0, tanh(1.0))
+-  call test_r (alog, 2.0, alog(2.0))
+-  call test_r (alog10, 2.0, alog10(2.0))
+-  call test_r (exp, 1.0, exp(1.0))
+-  call test_r2 (sign, 1.0, -2.0, sign(1.0, -2.0))
+-  call test_r2 (amod, 3.5, 2.0, amod(3.5, 2.0))
+-  
+-  call test_d (dabs, -1d0, abs(-1d0))
+-  call test_d (dint, 1.7d0, 1d0)
+-  call test_d (dnint, 1.7d0, 2d0)
+-  call test_d (dacos, 0.5d0, dacos(0.5d0))
+-  call test_d (dacosh, 1.5d0, dacosh(1.5d0))
+-  call test_d (dasin, 0.5d0, dasin(0.5d0))
+-  call test_d (dasinh, 0.5d0, dasinh(0.5d0))
+-  call test_d (datan, 0.5d0, datan(0.5d0))
+-  call test_d (datanh, 0.5d0, datanh(0.5d0))
+-  call test_d (dcos, 1d0, dcos(1d0))
+-  call test_d (dsin, 1d0, dsin(1d0))
+-  call test_d (dtan, 1d0, dtan(1d0))
+-  call test_d (dcosh, 1d0, dcosh(1d0))
+-  call test_d (dsinh, 1d0, dsinh(1d0))
+-  call test_d (dtanh, 1d0, dtanh(1d0))
+-  call test_d (dlog, 2d0, dlog(2d0))
+-  call test_d (dlog10, 2d0, dlog10(2d0))
+-  call test_d (dexp, 1d0, dexp(1d0))
+-  call test_d2 (dsign, 1d0, -2d0, sign(1d0, -2d0))
+-  call test_d2 (dmod, 3.5d0, 2d0, dmod(3.5d0, 2d0))
+-
+-  call test_dprod (dprod)
+-
+-  call test_c (conjg, (1.2,-4.), conjg((1.2,-4.)))
+-  call test_c (ccos, (1.2,-4.), ccos((1.2,-4.)))
+-  call test_c (cexp, (1.2,-4.), cexp((1.2,-4.)))
+-  call test_c (clog, (1.2,-4.), clog((1.2,-4.)))
+-  call test_c (csin, (1.2,-4.), csin((1.2,-4.)))
+-  call test_c (csqrt, (1.2,-4.), csqrt((1.2,-4.)))
+-
+-  call test_z (dconjg, (1.2d0,-4.d0), dconjg((1.2d0,-4.d0)))
+-  call test_z (cdcos, (1.2d0,-4.d0), cdcos((1.2d0,-4.d0)))
+-  call test_z (zcos, (1.2d0,-4.d0), zcos((1.2d0,-4.d0)))
+-  call test_z (cdexp, (1.2d0,-4.d0), cdexp((1.2d0,-4.d0)))
+-  call test_z (zexp, (1.2d0,-4.d0), zexp((1.2d0,-4.d0)))
+-  call test_z (cdlog, (1.2d0,-4.d0), cdlog((1.2d0,-4.d0)))
+-  call test_z (zlog, (1.2d0,-4.d0), zlog((1.2d0,-4.d0)))
+-  call test_z (cdsin, (1.2d0,-4.d0), cdsin((1.2d0,-4.d0)))
+-  call test_z (zsin, (1.2d0,-4.d0), zsin((1.2d0,-4.d0)))
+-  call test_z (cdsqrt, (1.2d0,-4.d0), cdsqrt((1.2d0,-4.d0)))
+-  call test_z (zsqrt, (1.2d0,-4.d0), zsqrt((1.2d0,-4.d0)))
+-
+-  call test_cabs (cabs, (1.2,-4.), cabs((1.2,-4.)))
+-  call test_cdabs (cdabs, (1.2d0,-4.d0), cdabs((1.2d0,-4.d0)))
+-  call test_cdabs (zabs, (1.2d0,-4.d0), zabs((1.2d0,-4.d0)))
+-  call test_cabs (aimag, (1.2,-4.), aimag((1.2,-4.)))
+-  call test_cdabs (dimag, (1.2d0,-4.d0), dimag((1.2d0,-4.d0)))
+-
+-  call test_nint (nint, -1.2, nint(-1.2))
+-  call test_idnint (idnint, -1.2d0, idnint(-1.2d0))
+-  call test_idim (isign, -42, 17, isign(-42, 17))
+-  call test_idim (idim, -42, 17, idim(-42,17))
+-  call test_idim (idim, 42, 17, idim(42,17))
+-  call test_r2 (dim, 1.2, -4., dim(1.2, -4.))
+-  call test_d2 (ddim, 1.2d0, -4.d0, ddim(1.2d0, -4.d0))
+-  call test_iabs (iabs, -7, iabs(-7))
+-  call test_idim (mod, 5, 2, mod(5,2))
+-  call test_len (len, "foobar", len("foobar"))
+-  call test_index (index, "foobarfoobar", "bar", index("foobarfoobar","bar"))
+-
+-end program
+-
+diff -ruN gcc-4.8.0-orig/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x gcc-4.8.0/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x
+--- gcc-4.8.0-orig/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x	2013-05-06 13:02:11.078000510 -0500
++++ gcc-4.8.0/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x	2013-05-06 13:06:55.129000422 -0500
+@@ -2,5 +2,9 @@
+     # No Inf/NaN support on SPU.
+     return 1
+ }
++if [istarget "powerpc-*-*gnuspe"] {
++    # No Inf/NaN support on SPE.
++    return 1
++}
+ add-ieee-options
+ return 0
+diff -ruN gcc-4.8.0-orig/gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90 gcc-4.8.0/gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90
+--- gcc-4.8.0-orig/gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90	2013-05-06 13:02:11.093000510 -0500
++++ gcc-4.8.0/gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90	1969-12-31 18:00:00.000000000 -0600
+@@ -1,311 +0,0 @@
+-! Program to test intrinsic functions as actual arguments
+-!
+-! Please keep the content of this file in sync with gfortran.dg/specifics_1.f90
+-subroutine test_c(fn, val, res)
+-  complex fn
+-  complex val, res
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  complex a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_z(fn, val, res)
+-  double complex fn
+-  double complex val, res
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  double complex a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_cabs(fn, val, res)
+-  real fn, res
+-  complex val
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  real a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_cdabs(fn, val, res)
+-  double precision fn, res
+-  double complex val
+-
+-  if (diff(fn(val),res)) call abort
+-contains
+-function diff(a,b)
+-  double precision a,b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine 
+-
+-subroutine test_r(fn, val, res)
+-  real fn
+-  real val, res
+-
+-  if (diff(fn(val), res)) call abort
+-contains
+-function diff(a, b)
+-  real a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine
+-
+-subroutine test_d(fn, val, res)
+-  double precision fn
+-  double precision val, res
+-
+-  if (diff(fn(val), res)) call abort
+-contains
+-function diff(a, b)
+-  double precision a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001d0)
+-end function
+-end subroutine
+-
+-subroutine test_r2(fn, val1, val2, res)
+-  real fn
+-  real val1, val2, res
+-
+-  if (diff(fn(val1, val2), res)) call abort
+-contains
+-function diff(a, b)
+-  real a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001)
+-end function
+-end subroutine
+-
+-subroutine test_d2(fn, val1, val2, res)
+-  double precision fn
+-  double precision val1, val2, res
+-
+-  if (diff(fn(val1, val2), res)) call abort
+-contains
+-function diff(a, b)
+-  double precision a, b
+-  logical diff
+-  diff = (abs(a - b) .gt. 0.00001d0)
+-end function
+-end subroutine
+-
+-subroutine test_dprod(fn)
+-  double precision fn
+-  if (abs (fn (2.0, 3.0) - 6d0) .gt. 0.00001) call abort
+-end subroutine
+-
+-subroutine test_nint(fn,val,res)
+-  integer fn, res
+-  real val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_idnint(fn,val,res)
+-  integer fn, res
+-  double precision val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_idim(fn,val1,val2,res)
+-  integer fn, res, val1, val2
+-  if (res .ne. fn(val1,val2)) call abort
+-end subroutine
+-
+-subroutine test_iabs(fn,val,res)
+-  integer fn, res, val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_len(fn,val,res)
+-  integer fn, res
+-  character(len=*) val
+-  if (res .ne. fn(val)) call abort
+-end subroutine
+-
+-subroutine test_index(fn,val1,val2,res)
+-  integer fn, res
+-  character(len=*) val1, val2
+-  if (fn(val1,val2) .ne. res) call abort
+-end subroutine
+-
+-program specifics
+-  intrinsic abs
+-  intrinsic aint
+-  intrinsic anint
+-  intrinsic acos
+-  intrinsic acosh
+-  intrinsic asin
+-  intrinsic asinh
+-  intrinsic atan
+-  intrinsic atanh
+-  intrinsic cos
+-  intrinsic sin
+-  intrinsic tan
+-  intrinsic cosh
+-  intrinsic sinh
+-  intrinsic tanh
+-  intrinsic alog
+-  intrinsic alog10
+-  intrinsic exp
+-  intrinsic sign
+-  intrinsic isign
+-  intrinsic amod
+-
+-  intrinsic dabs
+-  intrinsic dint
+-  intrinsic dnint
+-  intrinsic dacos
+-  intrinsic dacosh
+-  intrinsic dasin
+-  intrinsic dasinh
+-  intrinsic datan
+-  intrinsic datanh
+-  intrinsic dcos
+-  intrinsic dsin
+-  intrinsic dtan
+-  intrinsic dcosh
+-  intrinsic dsinh
+-  intrinsic dtanh
+-  intrinsic dlog
+-  intrinsic dlog10
+-  intrinsic dexp
+-  intrinsic dsign
+-  intrinsic dmod
+-
+-  intrinsic conjg
+-  intrinsic ccos
+-  intrinsic cexp
+-  intrinsic clog
+-  intrinsic csin
+-  intrinsic csqrt
+-
+-  intrinsic dconjg
+-  intrinsic cdcos
+-  intrinsic cdexp
+-  intrinsic cdlog
+-  intrinsic cdsin
+-  intrinsic cdsqrt
+-  intrinsic zcos
+-  intrinsic zexp
+-  intrinsic zlog
+-  intrinsic zsin
+-  intrinsic zsqrt
+-
+-  intrinsic cabs
+-  intrinsic cdabs
+-  intrinsic zabs
+-
+-  intrinsic dprod
+-
+-  intrinsic nint
+-  intrinsic idnint
+-  intrinsic dim
+-  intrinsic ddim
+-  intrinsic idim
+-  intrinsic iabs
+-  intrinsic mod
+-  intrinsic len
+-  intrinsic index
+-
+-  intrinsic aimag
+-  intrinsic dimag
+-
+-  call test_r (abs, -1.0, abs(-1.0))
+-  call test_r (aint, 1.7, aint(1.7))
+-  call test_r (anint, 1.7, anint(1.7))
+-  call test_r (acos, 0.5, acos(0.5))
+-  call test_r (acosh, 1.5, acosh(1.5))
+-  call test_r (asin, 0.5, asin(0.5))
+-  call test_r (asinh, 0.5, asinh(0.5))
+-  call test_r (atan, 0.5, atan(0.5))
+-  call test_r (atanh, 0.5, atanh(0.5))
+-  call test_r (cos, 1.0, cos(1.0))
+-  call test_r (sin, 1.0, sin(1.0))
+-  call test_r (tan, 1.0, tan(1.0))
+-  call test_r (cosh, 1.0, cosh(1.0))
+-  call test_r (sinh, 1.0, sinh(1.0))
+-  call test_r (tanh, 1.0, tanh(1.0))
+-  call test_r (alog, 2.0, alog(2.0))
+-  call test_r (alog10, 2.0, alog10(2.0))
+-  call test_r (exp, 1.0, exp(1.0))
+-  call test_r2 (sign, 1.0, -2.0, sign(1.0, -2.0))
+-  call test_r2 (amod, 3.5, 2.0, amod(3.5, 2.0))
+-  
+-  call test_d (dabs, -1d0, abs(-1d0))
+-  call test_d (dint, 1.7d0, 1d0)
+-  call test_d (dnint, 1.7d0, 2d0)
+-  call test_d (dacos, 0.5d0, dacos(0.5d0))
+-  call test_d (dacosh, 1.5d0, dacosh(1.5d0))
+-  call test_d (dasin, 0.5d0, dasin(0.5d0))
+-  call test_d (dasinh, 0.5d0, dasinh(0.5d0))
+-  call test_d (datan, 0.5d0, datan(0.5d0))
+-  call test_d (datanh, 0.5d0, datanh(0.5d0))
+-  call test_d (dcos, 1d0, dcos(1d0))
+-  call test_d (dsin, 1d0, dsin(1d0))
+-  call test_d (dtan, 1d0, dtan(1d0))
+-  call test_d (dcosh, 1d0, dcosh(1d0))
+-  call test_d (dsinh, 1d0, dsinh(1d0))
+-  call test_d (dtanh, 1d0, dtanh(1d0))
+-  call test_d (dlog, 2d0, dlog(2d0))
+-  call test_d (dlog10, 2d0, dlog10(2d0))
+-  call test_d (dexp, 1d0, dexp(1d0))
+-  call test_d2 (dsign, 1d0, -2d0, sign(1d0, -2d0))
+-  call test_d2 (dmod, 3.5d0, 2d0, dmod(3.5d0, 2d0))
+-
+-  call test_dprod (dprod)
+-
+-  call test_c (conjg, (1.2,-4.), conjg((1.2,-4.)))
+-  call test_c (ccos, (1.2,-4.), ccos((1.2,-4.)))
+-  call test_c (cexp, (1.2,-4.), cexp((1.2,-4.)))
+-  call test_c (clog, (1.2,-4.), clog((1.2,-4.)))
+-  call test_c (csin, (1.2,-4.), csin((1.2,-4.)))
+-  call test_c (csqrt, (1.2,-4.), csqrt((1.2,-4.)))
+-
+-  call test_z (dconjg, (1.2d0,-4.d0), dconjg((1.2d0,-4.d0)))
+-  call test_z (cdcos, (1.2d0,-4.d0), cdcos((1.2d0,-4.d0)))
+-  call test_z (zcos, (1.2d0,-4.d0), zcos((1.2d0,-4.d0)))
+-  call test_z (cdexp, (1.2d0,-4.d0), cdexp((1.2d0,-4.d0)))
+-  call test_z (zexp, (1.2d0,-4.d0), zexp((1.2d0,-4.d0)))
+-  call test_z (cdlog, (1.2d0,-4.d0), cdlog((1.2d0,-4.d0)))
+-  call test_z (zlog, (1.2d0,-4.d0), zlog((1.2d0,-4.d0)))
+-  call test_z (cdsin, (1.2d0,-4.d0), cdsin((1.2d0,-4.d0)))
+-  call test_z (zsin, (1.2d0,-4.d0), zsin((1.2d0,-4.d0)))
+-  call test_z (cdsqrt, (1.2d0,-4.d0), cdsqrt((1.2d0,-4.d0)))
+-  call test_z (zsqrt, (1.2d0,-4.d0), zsqrt((1.2d0,-4.d0)))
+-
+-  call test_cabs (cabs, (1.2,-4.), cabs((1.2,-4.)))
+-  call test_cdabs (cdabs, (1.2d0,-4.d0), cdabs((1.2d0,-4.d0)))
+-  call test_cdabs (zabs, (1.2d0,-4.d0), zabs((1.2d0,-4.d0)))
+-  call test_cabs (aimag, (1.2,-4.), aimag((1.2,-4.)))
+-  call test_cdabs (dimag, (1.2d0,-4.d0), dimag((1.2d0,-4.d0)))
+-
+-  call test_nint (nint, -1.2, nint(-1.2))
+-  call test_idnint (idnint, -1.2d0, idnint(-1.2d0))
+-  call test_idim (isign, -42, 17, isign(-42, 17))
+-  call test_idim (idim, -42, 17, idim(-42,17))
+-  call test_idim (idim, 42, 17, idim(42,17))
+-  call test_r2 (dim, 1.2, -4., dim(1.2, -4.))
+-  call test_d2 (ddim, 1.2d0, -4.d0, ddim(1.2d0, -4.d0))
+-  call test_iabs (iabs, -7, iabs(-7))
+-  call test_idim (mod, 5, 2, mod(5,2))
+-  call test_len (len, "foobar", len("foobar"))
+-  call test_index (index, "foobarfoobar", "bar", index("foobarfoobar","bar"))
+-
+-end program
+-
+diff -ruN gcc-4.8.0-orig/gcc/testsuite/gfortran.dg/PR49268.f90 gcc-4.8.0/gcc/testsuite/gfortran.dg/PR49268.f90
+--- gcc-4.8.0-orig/gcc/testsuite/gfortran.dg/PR49268.f90	2013-05-06 15:04:59.318000510 -0500
++++ gcc-4.8.0/gcc/testsuite/gfortran.dg/PR49268.f90	1969-12-31 18:00:00.000000000 -0600
+@@ -1,51 +0,0 @@
+-! { dg-do run }
+-! { dg-options "-fcray-pointer" }
+-
+-! Test the fix for a runtime error 
+-! Contributed by Mike Kumbera <kumbera1@llnl.gov>
+-
+-        program bob
+-        implicit none
+-        integer*8 ipfoo
+-        integer n,m,i,j
+-        real*8 foo
+-        
+-        common /ipdata/ ipfoo
+-        common /ipsize/ n,m
+-        POINTER ( ipfoo, foo(3,7) )
+-
+-        n=3
+-        m=7
+-
+-        ipfoo=malloc(8*n*m)
+-        do i=1,n
+-            do j=1,m
+-                foo(i,j)=1.d0
+-            end do
+-        end do
+-        call use_foo()
+-        end  program bob
+-
+-
+-        subroutine use_foo()
+-        implicit none
+-        integer n,m,i,j
+-        integer*8 ipfoo
+-        common /ipdata/ ipfoo
+-        common /ipsize/ n,m
+-        real*8 foo,boo
+-
+-        !fails if * is the last dimension
+-        POINTER ( ipfoo, foo(n,*) )
+-
+-        !works if the last dimension is specified
+-        !POINTER ( ipfoo, foo(n,m) )
+-        boo=0.d0
+-        do i=1,n
+-            do j=1,m
+-               boo=foo(i,j)+1.0
+-               if (abs (boo - 2.0) .gt. 1e-6) call abort
+-            end do
+-        end do
+-
+-        end subroutine use_foo
diff --git a/recipes-devtools/gcc/gcc-4.9/0041-libtool-avoid-libdir.patch b/recipes-devtools/gcc/gcc-4.9/0041-libtool-avoid-libdir.patch
new file mode 100644
index 0000000..2dd9610
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0041-libtool-avoid-libdir.patch
@@ -0,0 +1,19 @@
+Avoid using libdir from .la which usually points to a host path
+
+Upstream-Status: Inappropriate [embedded specific]
+Signed-off-by: Jonathan Liu <net147@gmail.com>
+
+diff --git a/ltmain.sh b/ltmain.sh
+index a03433f..1902a90 100644
+--- a/ltmain.sh
++++ b/ltmain.sh
+@@ -5628,6 +5628,9 @@ func_mode_link ()
+ 	    absdir="$abs_ladir"
+ 	    libdir="$abs_ladir"
+ 	  else
++	    # Instead of using libdir from .la which usually points to a host path,
++	    # use the path the .la is contained in.
++	    libdir="$abs_ladir"
+ 	    dir="$libdir"
+ 	    absdir="$libdir"
+ 	  fi
diff --git a/recipes-devtools/gcc/gcc-4.9/0041.gcc.fix_e5500-e6500-aeabi-multi-lib.patch b/recipes-devtools/gcc/gcc-4.9/0041.gcc.fix_e5500-e6500-aeabi-multi-lib.patch
new file mode 100644
index 0000000..807a063
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0041.gcc.fix_e5500-e6500-aeabi-multi-lib.patch
@@ -0,0 +1,46 @@
+# Problem Statement:
+  For e5500/e6500 bare-board tool chain, 
+  we do not build the 32-bit soft-float library.
+
+# Reported by:
+  Rohit [28.May.2013]
+
+# Owned by:
+  Rohit
+
+# Action:
+  * Generate the following multi-libs [same as e500mc eabi target].
+	.;@mno-eabi@mstrict-align
+	nof;@msoft-float@mno-eabi@mstrict-align
+	le;@mlittle@mno-eabi@mstrict-align
+	und;@fleading-underscore@mno-eabi@mstrict-align
+	64;@m64@mno-eabi@mstrict-align
+	le/und;@mlittle@fleading-underscore@mno-eabi@mstrict-align
+	nof/le;@msoft-float@mlittle@mno-eabi@mstrict-align
+	nof/und;@msoft-float@fleading-underscore@mno-eabi@mstrict-align
+	nof/le/und;@msoft-float@mlittle@fleading-underscore@mno-eabi@mstrict-align
+
+diff -Naur gcc-4.8.1/gcc/config/rs6000/t-ppc-e500mc gcc-4.8.1-e5500-e6500-multi-lib-patch/gcc/config/rs6000/t-ppc-e500mc
+--- gcc-4.8.1/gcc/config/rs6000/t-ppc-e500mc	2013-06-17 07:35:05.349002658 -0500
++++ gcc-4.8.1-e5500-e6500-multi-lib-patch/gcc/config/rs6000/t-ppc-e500mc	2013-06-18 02:43:10.331002656 -0500
+@@ -1,10 +1,15 @@
+ # Multilibs for powerpc embedded ELF targets.
++MULTILIB_OPTIONS	= msoft-float \
++			  mlittle \
++			  fleading-underscore \
++			  m64
++
++MULTILIB_DIRNAMES	= nof \
++			  le \
++			  und \
++			  64
+ 
+-MULTILIB_OPTIONS	= m32/m64
+-
+-MULTILIB_DIRNAMES	= 32 64
+-
+-MULTILIB_EXCEPTIONS	= 
++MULTILIB_EXCLUSIONS     = m64/msoft-float m64/mlittle m64/fleading-underscore
+ 
+ MULTILIB_EXTRA_OPTS	= mno-eabi mstrict-align
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0042.gcc.fix_ivopts.patch b/recipes-devtools/gcc/gcc-4.9/0042.gcc.fix_ivopts.patch
new file mode 100644
index 0000000..5326aa4
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0042.gcc.fix_ivopts.patch
@@ -0,0 +1,157 @@
+# Problem Statement:
+  Fix telecom degradation around 30% to 40% without any degradations
+  in other benchmarks or keep them as minimum as possible.
+  below pattern causing pipeline stall resulting in huge degradations.
+  lhau 4,2(10)
+  lhax 9,10,12
+  the above pattern needs to converted to something like this
+  lhax 4,3,10
+  lhax 9,12,10
+  addi 10,10,2
+
+# Owned by:
+  Srinivas
+
+# Action:
+  Root cause of the problem lies in selecting optimal iv set selected
+  for loop.making cost adjustments resulting in huge degradations in
+  other benchmarks and this approach makes every load updates to be
+  replacedload indexed at least in telecom case.
+  Approach: skip replacing original iv candidate which will result in
+  load index with the address candidate which results in load update.
+  use pattern is identified with some hueristics as given in fix.
+  this bebehaviour is guarded with -fuse-seq-load-indexes switch.
+  this switch is on by default at -O1 and above.
+  use -fno-use-seq-load-indexes to supress this behaviour.
+
+diff -Naur gcc-4.9.2/gcc/common.opt gcc-4.9.2-ivopts-fix/gcc/common.opt
+--- gcc-4.9.2/gcc/common.opt	2014-04-07 08:27:39.000000000 -0500
++++ gcc-4.9.2-ivopts-fix/gcc/common.opt	2015-01-15 13:37:12.895409095 -0600
+@@ -1467,6 +1467,10 @@
+ Common Report Var(flag_ivopts) Init(1) Optimization
+ Optimize induction variables on trees
+ 
++fuse-seq-load-indexes
++Common Report Var(flag_use_seq_load_indexes) Init(1) Optimization
++Supress sequential load update and indexed loads with two indexed loads which exploits pipeline
++
+ fjump-tables
+ Common Var(flag_jump_tables) Init(1) Optimization
+ Use jump tables for sufficiently large switch statements
+diff -Naur gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-fuse-seq-load-indexes.c gcc-4.9.2-ivopts-fix/gcc/testsuite/gcc.target/powerpc/ppc-fsl-fuse-seq-load-indexes.c
+--- gcc-4.9.2/gcc/testsuite/gcc.target/powerpc/ppc-fsl-fuse-seq-load-indexes.c	1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.9.2-ivopts-fix/gcc/testsuite/gcc.target/powerpc/ppc-fsl-fuse-seq-load-indexes.c	2015-01-16 20:08:49.786531453 -0600
+@@ -0,0 +1,29 @@
++/* { dg-do compile { target powerpc*-*-* } } */
++/* { dg-options "-O2 -fuse-seq-load-indexes" } */
++
++void
++testloadindex (
++    short   *Data,     
++    short   *AccData,  
++    short   DataSize,       
++    short   NumberOfLags,   
++    short   Scale           
++)
++{
++    int   i;
++    int   lag;
++    int   LastIndex;
++    int   Accumulator;
++
++    for (lag = 0; lag < NumberOfLags; lag++) {
++        Accumulator = 0;
++        LastIndex = DataSize - lag;
++        for (i = 0; i < LastIndex; i++) {
++            Accumulator += ((int) Data[i] * (int) Data[i+lag]) >> Scale;
++        }
++        AccData[lag] = (short) (Accumulator >> 16) ;
++    }
++}
++/* { dg-final { scan-assembler-not "lhau" } }*/
++/* { dg-final { scan-assembler-times "lhax" 2 } }*/
++
+diff -Naur gcc-4.9.2/gcc/tree-ssa-loop-ivopts.c gcc-4.9.2-ivopts-fix/gcc/tree-ssa-loop-ivopts.c
+--- gcc-4.9.2/gcc/tree-ssa-loop-ivopts.c	2014-08-06 06:42:22.000000000 -0500
++++ gcc-4.9.2-ivopts-fix/gcc/tree-ssa-loop-ivopts.c	2015-01-16 00:32:23.754306622 -0600
+@@ -5671,6 +5671,69 @@
+       }
+   fprintf (file, "\n\n");
+ }
++/* Find out if the given iv use pattern for a given candidate which would
++ * generate two sequential load indexes so that they can be pipelined and
++ * result in performance improvement over one load update and load index.
++ * Below are the heuristics.
++ * 1)IV candidate base object should be same as that of IV uses for which
++ *   two loads would be generated.
++ * 2)base values of two uses should be different and the first base should
++ *   be just an object name.
++ * 3)both the uses should be consecutive.
++ *   returns true if above hueristics are matched otherwise return false.
++ */
++static bool
++iv_use_pipeline_possibility (struct ivopts_data *data,struct iv_ca *ivs,
++                             struct iv_cand *cand)
++{
++  unsigned i,count = 0;
++  struct iv_use *use;
++  int base_check = true;
++  tree cand_base_obj,base_obj;
++  tree cur_base = NULL,prev_base = NULL;
++  cand_base_obj = cand->iv->base_object;
++
++  if (cand_base_obj)
++   STRIP_NOPS (cand_base_obj);
++  for (i = 0; i < ivs->upto; i++)
++    {
++      use = iv_use (data, i);
++      base_obj = use->iv->base_object;
++      cur_base = use->iv->base;
++      if (cur_base)
++        {
++          STRIP_NOPS (cur_base);
++        }
++      if (base_obj)
++        {
++          STRIP_NOPS (base_obj);
++        }
++      if (count == 2)
++       break;
++      if (prev_base && count == 1)
++	{
++         if (TREE_CODE (prev_base) == SSA_NAME &&
++             TREE_CODE (cur_base) != SSA_NAME)
++          base_check=true;
++         else
++          base_check = false;
++        }
++      else
++       base_check = true;
++	
++      if ((cand_base_obj == base_obj) &&
++           (use->type == USE_ADDRESS) && base_check)
++       count++;
++      else
++       count = 0;
++ 
++       prev_base = cur_base;
++    }
++     if (count == 2)
++      return true;
++     else
++      return false;
++}
+ 
+ /* Try changing candidate in IVS to CAND for each use.  Return cost of the
+    new set, and store differences in DELTA.  Number of induction variables
+@@ -5707,6 +5770,10 @@
+       if (!min_ncand && !cheaper_cost_pair (new_cp, old_cp))
+         continue;
+ 
++      if (flag_use_seq_load_indexes &&
++          iv_use_pipeline_possibility (data,ivs,cand))
++        continue;
++
+       *delta = iv_ca_delta_add (use, old_cp, new_cp, *delta);
+     }
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0043-cpp.patch b/recipes-devtools/gcc/gcc-4.9/0043-cpp.patch
new file mode 100644
index 0000000..eaf8646
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0043-cpp.patch
@@ -0,0 +1,40 @@
+The OE environment sets and exports CPP as being the target gcc. When building 
+gcc-cross-canadian for a mingw targetted sdk, the following can be found in
+build.x86_64-pokysdk-mingw32.i586-poky-linux/build-x86_64-linux/libiberty/config.log:
+
+configure:3641: checking for _FILE_OFFSET_BITS value needed for large files
+configure:3666: gcc  -c -isystem/media/build1/poky/build/tmp/sysroots/x86_64-linux/usr/include -O2 -pipe  conftest.c >&5
+configure:3666: $? = 0
+configure:3698: result: no
+configure:3786: checking how to run the C preprocessor
+configure:3856: result: x86_64-pokysdk-mingw32-gcc -E --sysroot=/media/build1/poky/build/tmp/sysroots/x86_64-nativesdk-mingw32-pokysdk-mingw32
+configure:3876: x86_64-pokysdk-mingw32-gcc -E --sysroot=/media/build1/poky/build/tmp/sysroots/x86_64-nativesdk-mingw32-pokysdk-mingw32  conftest.c
+configure:3876: $? = 0
+
+Note this is a *build* target (in build-x86_64-linux) so it should be using 
+the host "gcc", not x86_64-pokysdk-mingw32-gcc. Since the mingw32 headers are 
+very different, using the wrong cpp is a real problem. It is leaking into 
+configure through the CPP variable. Ultimately this leads to build failures 
+related to not being able to include a process.h file for pem-unix.c.
+
+The fix is to ensure we export a sane CPP value into the build environment when
+using build targets. We could define a CPP_FOR_BUILD value which may be the version
+which needs to be upstreamed but for now, this fix is good enough to avoid the 
+problem.
+
+RP 22/08/2013
+
+Upstream-Status: Pending
+
+Index: gcc-4.8.1/Makefile.in
+===================================================================
+--- gcc-4.8.1.orig/Makefile.in	2013-03-30 11:25:03.000000000 +0000
++++ gcc-4.8.1/Makefile.in	2013-08-13 12:03:17.151988882 +0000
+@@ -149,6 +149,7 @@
+ 	AR="$(AR_FOR_BUILD)"; export AR; \
+ 	AS="$(AS_FOR_BUILD)"; export AS; \
+ 	CC="$(CC_FOR_BUILD)"; export CC; \
++	CPP="$(CC_FOR_BUILD) -E"; export CPP; \
+ 	CFLAGS="$(CFLAGS_FOR_BUILD)"; export CFLAGS; \
+ 	CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+ 	CXX="$(CXX_FOR_BUILD)"; export CXX; \
diff --git a/recipes-devtools/gcc/gcc-4.9/0043.gcc.sysroot_spec_only_linux.patch b/recipes-devtools/gcc/gcc-4.9/0043.gcc.sysroot_spec_only_linux.patch
new file mode 100644
index 0000000..01eaa8b
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0043.gcc.sysroot_spec_only_linux.patch
@@ -0,0 +1,30 @@
+# Problem Statement:
+  The compiler driver doesn't pick the right libraries and other initialization
+  routines when '-msoft-float' option is passed.
+
+# Owned by:
+  Andrei (b14391)
+
+# Action
+  Add sysroot suffix 'nof' if '-msoft-float' options is passed for linux targets.
+
+diff -ruN gcc-4.9.2.old/gcc/config/rs6000/fsl-linux.h gcc-4.9.2.new/gcc/config/rs6000/fsl-linux.h
+--- gcc-4.9.2.old/gcc/config/rs6000/fsl-linux.h	1970-01-01 02:00:00.000000000 +0200
++++ gcc-4.9.2.new/gcc/config/rs6000/fsl-linux.h	2015-06-18 12:46:06.264520800 +0300
+@@ -0,0 +1,4 @@
++
++/* The C soft-float libraries have their own subdirectory.  */
++#undef SYSROOT_SUFFIX_SPEC
++#define SYSROOT_SUFFIX_SPEC  "%{msoft-float:/nof}"
+diff -ruN gcc-4.9.2.old/gcc/config.gcc gcc-4.9.2.new/gcc/config.gcc
+--- gcc-4.9.2.old/gcc/config.gcc	2015-06-15 19:05:43.000000000 +0300
++++ gcc-4.9.2.new/gcc/config.gcc	2015-06-18 12:42:10.951991900 +0300
+@@ -2290,7 +2290,7 @@
+ 	tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-rtems rs6000/t-ppccomm"
+ 	;;
+ powerpc*-*-linux*)
+-	tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h"
++	tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h rs6000/fsl-linux.h"
+ 	extra_options="${extra_options} rs6000/sysv4.opt"
+ 	tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+ 	extra_objs="$extra_objs rs6000-linux.o"
diff --git a/recipes-devtools/gcc/gcc-4.9/0044-gengtypes.patch b/recipes-devtools/gcc/gcc-4.9/0044-gengtypes.patch
new file mode 100644
index 0000000..e38761d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0044-gengtypes.patch
@@ -0,0 +1,97 @@
+gengtype is generated for both the build system and the target. -DGENERATOR_FILE
+was added in the patch http://gcc.gnu.org/ml/gcc-patches/2012-07/msg00273.html
+and was applied to both versions of gengtype.
+
+Unfortunately the presence of this flag triggers the build configuration (bconfig.h) 
+to be included for the target build of gengtype. Compiling gengtype with the target 
+compiler and bconfig.h can result in errors if the build and target systems are 
+dissimilar. An example case this fails is cross compiling gcc on linux for a darwin 
+target system:
+
+In file included from /media/build1/poky/build/tmp/work-shared/gcc-4.8.1-r0/gcc-4.8.1/gcc/gengtype-parse.c:25:0:
+| /media/build1/poky/build/tmp/work-shared/gcc-4.8.1-r0/gcc-4.8.1/gcc/gengtype-parse.c: In function 'void parse_error(const char*, ...)':
+| /media/build1/poky/build/tmp/work-shared/gcc-4.8.1-r0/gcc-4.8.1/gcc/system.h:93:53: error: 'fputc_unlocked' was not declared in this scope
+|  #  define fputc(C, Stream) fputc_unlocked (C, Stream)
+
+which occurs since auto-build.h and auto-host.h have differnet values of
+HAVE_FPUTC_UNLOCKED:
+
+#define HAVE_FPUTC_UNLOCKED 1
+/* #undef HAVE_FPUTS_UNLOCKED */
+
+The obvious fix is to only include the flag on build/ targets which this patch does, however 
+this also leads to compile errors due to const_tree being undefined but used in double_int.h
+
+I added a GENERATOR_FILE2 flag to workaround those in the 
+target case and allow the build to succeed.
+
+Only the build/gengtypes should have the -DGENERATOR_FILE 
+
+RP 22/8/2013
+
+Upstream-Status: Pending
+
+Index: gcc-4.8.1/gcc/Makefile.in
+===================================================================
+--- gcc-4.8.1.orig/gcc/Makefile.in	2013-08-19 11:40:36.844014424 +0000
++++ gcc-4.8.1/gcc/Makefile.in	2013-08-19 11:40:37.784014402 +0000
+@@ -3903,27 +3903,29 @@
+ 
+ gengtype-lex.o build/gengtype-lex.o : gengtype-lex.c gengtype.h $(SYSTEM_H)
+ gengtype-lex.o: $(CONFIG_H) $(BCONFIG_H)
+-CFLAGS-gengtype-lex.o += -DGENERATOR_FILE
++CFLAGS-build/gengtype-lex.o += -DGENERATOR_FILE
+ build/gengtype-lex.o: $(BCONFIG_H)
+ 
+ gengtype-parse.o build/gengtype-parse.o : gengtype-parse.c gengtype.h \
+   $(SYSTEM_H)
+ gengtype-parse.o: $(CONFIG_H)
+-CFLAGS-gengtype-parse.o += -DGENERATOR_FILE
++CFLAGS-build/gengtype-parse.o += -DGENERATOR_FILE
+ build/gengtype-parse.o: $(BCONFIG_H)
+ 
+ gengtype-state.o build/gengtype-state.o: gengtype-state.c $(SYSTEM_H) \
+   gengtype.h errors.h double-int.h version.h $(HASHTAB_H) $(OBSTACK_H) \
+   $(XREGEX_H)
+ gengtype-state.o: $(CONFIG_H)
+-CFLAGS-gengtype-state.o += -DGENERATOR_FILE
++CFLAGS-gengtype-state.o += -DGENERATOR_FILE2
++CFLAGS-build/gengtype-state.o += -DGENERATOR_FILE
+ build/gengtype-state.o: $(BCONFIG_H)
+ 
+ gengtype.o build/gengtype.o : gengtype.c $(SYSTEM_H) gengtype.h 	\
+   rtl.def insn-notes.def errors.h double-int.h version.h $(HASHTAB_H) \
+   $(OBSTACK_H) $(XREGEX_H)
+ gengtype.o: $(CONFIG_H)
+-CFLAGS-gengtype.o += -DGENERATOR_FILE
++CFLAGS-gengtype.o += -DGENERATOR_FILE2
++CFLAGS-build/gengtype.o += -DGENERATOR_FILE
+ build/gengtype.o: $(BCONFIG_H)
+ 
+ build/genmddeps.o: genmddeps.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h	\
+@@ -3988,7 +3990,7 @@
+ # any system header is included.
+ gengtype-lex.c : gengtype-lex.l
+ 	-$(FLEX) $(FLEXFLAGS) -o$@ $< && { \
+-	  echo '#include "bconfig.h"' > $@.tmp; \
++	  echo '' > $@.tmp; \
+ 	  cat $@ >> $@.tmp; \
+ 	  mv $@.tmp $@; \
+ 	}
+Index: gcc-4.8.1/gcc/double-int.h
+===================================================================
+--- gcc-4.8.1.orig/gcc/double-int.h	2013-01-30 11:04:30.000000000 +0000
++++ gcc-4.8.1/gcc/double-int.h	2013-08-19 11:41:51.564012719 +0000
+@@ -448,10 +448,12 @@
+ 
+ 
+ #ifndef GENERATOR_FILE
++#ifndef GENERATOR_FILE2
+ /* Conversion to and from GMP integer representations.  */
+ 
+ void mpz_set_double_int (mpz_t, double_int, bool);
+ double_int mpz_get_double_int (const_tree, mpz_t, bool);
+ #endif
++#endif
+ 
+ #endif /* DOUBLE_INT_H */
diff --git a/recipes-devtools/gcc/gcc-4.9/0046-libatomic-deptracking.patch b/recipes-devtools/gcc/gcc-4.9/0046-libatomic-deptracking.patch
new file mode 100644
index 0000000..6ea4f42
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0046-libatomic-deptracking.patch
@@ -0,0 +1,41 @@
+gcc 4.8 won't build with --disable-dependency-tracking since the *.Ppo files
+don't get created unless --enable-dependency-tracking is true.
+
+This patch ensures we only use those compiler options when its enabled.
+
+Upstream-Status: Submitted
+
+(Problem was already reported upstream, attached this patch there
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55930)
+
+RP 
+2012/09/22
+
+Index: gcc-4.8.1/libatomic/Makefile.am
+===================================================================
+--- gcc-4.8.1.orig/libatomic/Makefile.am	2013-01-14 18:16:23.000000000 +0000
++++ gcc-4.8.1/libatomic/Makefile.am	2013-09-22 10:38:18.904064750 +0000
+@@ -100,7 +100,8 @@
+ IFUNC_DEF	= -DIFUNC_ALT=$(PAT_S)
+ IFUNC_OPT	= $(word $(PAT_S),$(IFUNC_OPTIONS))
+ 
+-M_DEPS		= -MT $@ -MD -MP -MF $(DEPDIR)/$(@F).Ppo
++@AMDEP_TRUE@M_DEPS		= -MT $@ -MD -MP -MF $(DEPDIR)/$(@F).Ppo
++@AMDEP_FALSE@M_DEPS		= 
+ M_SIZE		= -DN=$(PAT_N)
+ M_IFUNC		= $(if $(PAT_S),$(IFUNC_DEF) $(IFUNC_OPT))
+ M_FILE		= $(PAT_BASE)_n.c
+Index: gcc-4.8.1/libatomic/Makefile.in
+===================================================================
+--- gcc-4.8.1.orig/libatomic/Makefile.in	2013-05-31 09:09:26.000000000 +0000
++++ gcc-4.8.1/libatomic/Makefile.in	2013-09-22 10:40:42.520059917 +0000
+@@ -298,7 +298,8 @@
+ PAT_S = $(word 3,$(PAT_SPLIT))
+ IFUNC_DEF = -DIFUNC_ALT=$(PAT_S)
+ IFUNC_OPT = $(word $(PAT_S),$(IFUNC_OPTIONS))
+-M_DEPS = -MT $@ -MD -MP -MF $(DEPDIR)/$(@F).Ppo
++@AMDEP_TRUE@M_DEPS = -MT $@ -MD -MP -MF $(DEPDIR)/$(@F).Ppo
++@AMDEP_FALSE@M_DEPS = 
+ M_SIZE = -DN=$(PAT_N)
+ M_IFUNC = $(if $(PAT_S),$(IFUNC_DEF) $(IFUNC_OPT))
+ M_FILE = $(PAT_BASE)_n.c
diff --git a/recipes-devtools/gcc/gcc-4.9/0047-repomembug.patch b/recipes-devtools/gcc/gcc-4.9/0047-repomembug.patch
new file mode 100644
index 0000000..9afd55c
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0047-repomembug.patch
@@ -0,0 +1,53 @@
+When compiling a project using -frepo, .rpo files are written alongside
+the .o file, the symbols either have O or C against them. During final linking,
+the objects can be recompiled with some of the entries tweaked/chosen by the 
+tlink.c code (visible with TLINK_VERBOSE=3), it does this by changing O -> C
+in the .rpo files.
+
+My tests showed that init_repo (cp/repo.c) was correctly calling 
+IDENTIFIER_REPO_CHOSEN against the right identifers and setting the
+chosen bit.
+
+By the time finish_repo() or emit_repo_p() were called, the pointer returned
+by get_identifier() for the symbol marked during init_repo had changed and
+the chosen bit was no longer set. This lead to linking bugs like:
+
+collect: relinking
+collect2: error: '_ZNK6sudoku5ClearINS_8SequenceEEclERS1_' was assigned to 'board.rpo', but was not defined during recompilation, or vice versa
+
+The problem is that the garbage collection is getting called before
+finish_repo() is called and ggc_protect_identifiers is set to false 
+so the identifiers are not preserved. They are recreated but the 
+chosen bits get wiped out which is why the pointer changes and the 
+chosen bit is not set.
+
+The fix is to change ggc_protect_identifiers *after* the finish_repo 
+calls are made.
+
+Reproduction is tricky since you need to trigger the garbage collector at
+just the right moment.
+
+RP 2013/10/9
+
+[YOCTO #5133]
+
+Upstream-Status: Pending
+
+Index: gcc-4.8.1/gcc/toplev.c
+===================================================================
+--- gcc-4.8.1.orig/gcc/toplev.c	2013-03-28 08:29:51.000000000 +0000
++++ gcc-4.8.1/gcc/toplev.c	2013-10-09 20:27:17.089228023 +0000
+@@ -551,11 +551,11 @@
+   if (flag_syntax_only || flag_wpa)
+     return;
+ 
+-  ggc_protect_identifiers = false;
+-
+   /* This must also call finalize_compilation_unit.  */
+   lang_hooks.decls.final_write_globals ();
+ 
++  ggc_protect_identifiers = false;
++
+   if (seen_error ())
+     return;
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch b/recipes-devtools/gcc/gcc-4.9/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch
new file mode 100644
index 0000000..b98f8ff
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch
@@ -0,0 +1,42 @@
+From 9e0e19eac2562f73858602fe26e2044eb8b20c47 Mon Sep 17 00:00:00 2001
+From: Alexandru-Cezar Sardan <alexandru.sardan@freescale.com>
+Date: Wed, 5 Feb 2014 16:52:31 +0200
+Subject: [PATCH] Enable SPE & AltiVec generation on powepc*linux target
+
+When is configured with --target=powerpc-linux, the resulting GCC will 
+not be able to generate code for SPE targets (e500v1/v2).
+GCC configured with --target=powerpc-linuxspe will not be able to
+generate AltiVec instructions (for e6500).
+This patch modifies the configured file such that SPE or AltiVec code
+can be generated when gcc is configured with --target=powerpc-linux.
+The ABI and speciffic instructions can be selected through the
+"-mabi=spe or -mabi=altivec" and the "-mspe or -maltivec" parameters.
+
+Upstream-Status: Inappropriate [configuration]
+
+Signed-off-by: Alexandru-Cezar Sardan <alexandru.sardan@freescale.com>
+---
+ gcc/config.gcc |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/config.gcc b/gcc/config.gcc
+index cb7a94e..d392c2b 100644
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -2068,7 +2068,12 @@ powerpc-*-rtems*)
+ 	tmake_file="rs6000/t-fprules rs6000/t-rtems t-rtems rs6000/t-ppccomm"
+ 	;;
+ powerpc*-*-linux*)
+-	tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h"
++	case ${target} in
++	    powerpc*-*-linux*spe* | powerpc*-*-linux*altivec*)
++		tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h" ;;
++	    *)
++		tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h rs6000/linuxaltivec.h rs6000/linuxspe.h rs6000/e500.h" ;;
++	esac
+ 	extra_options="${extra_options} rs6000/sysv4.opt"
+ 	tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+ 	case ${target} in
+-- 
+1.7.9.5
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0050-Revert-Use-dbx_reg_number-for-spanning-registers.patch b/recipes-devtools/gcc/gcc-4.9/0050-Revert-Use-dbx_reg_number-for-spanning-registers.patch
new file mode 100644
index 0000000..aead6f6
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0050-Revert-Use-dbx_reg_number-for-spanning-registers.patch
@@ -0,0 +1,80 @@
+Upstream-Status: Pending
+
+From cb9b1c041b634a4c128896e3d3eed4082608c797 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 3 May 2014 19:25:17 -0700
+Subject: [PATCH] Revert "2013-05-21  Christian Bruel 
+ <christian.bruel@st.com>"
+
+This reverts commit 3983036a8b6b2710c57777194f21507819a73553.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Conflicts:
+	gcc/ChangeLog
+---
+ gcc/ChangeLog   | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ gcc/dwarf2out.c |  33 +++++----
+ 2 files changed, 234 insertions(+), 18 deletions(-)
+
+diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
+index 1272326..6ac2b28 100644
+--- a/gcc/dwarf2out.c
++++ b/gcc/dwarf2out.c
+@@ -10870,27 +10870,25 @@ static dw_loc_descr_ref
+ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
+ 			     enum var_init_status initialized)
+ {
+-  int size, i;
++  int nregs, size, i;
++  unsigned reg;
+   dw_loc_descr_ref loc_result = NULL;
+ 
+-  /* Simple, contiguous registers.  */
+-  if (regs == NULL_RTX)
+-    {
+-      unsigned reg = REGNO (rtl);
+-      int nregs;
+-
++  reg = REGNO (rtl);
+ #ifdef LEAF_REG_REMAP
+-      if (crtl->uses_only_leaf_regs)
+-	{
+-	  int leaf_reg = LEAF_REG_REMAP (reg);
+-	  if (leaf_reg != -1)
+-	    reg = (unsigned) leaf_reg;
+-	}
++  if (crtl->uses_only_leaf_regs)
++    {
++      int leaf_reg = LEAF_REG_REMAP (reg);
++      if (leaf_reg != -1)
++	reg = (unsigned) leaf_reg;
++    }
+ #endif
++  gcc_assert ((unsigned) DBX_REGISTER_NUMBER (reg) == dbx_reg_number (rtl));
++  nregs = hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)];
+ 
+-      gcc_assert ((unsigned) DBX_REGISTER_NUMBER (reg) == dbx_reg_number (rtl));
+-      nregs = hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)];
+-
++  /* Simple, contiguous registers.  */
++  if (regs == NULL_RTX)
++    {
+       size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs;
+ 
+       loc_result = NULL;
+@@ -10918,9 +10916,10 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
+     {
+       dw_loc_descr_ref t;
+ 
+-      t = one_reg_loc_descriptor (dbx_reg_number (XVECEXP (regs, 0, i)),
++      t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)),
+ 				  VAR_INIT_STATUS_INITIALIZED);
+       add_loc_descr (&loc_result, t);
++      size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+       add_loc_descr_op_piece (&loc_result, size);
+     }
+ 
+-- 
+1.9.2
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0051-eabispe.patch b/recipes-devtools/gcc/gcc-4.9/0051-eabispe.patch
new file mode 100644
index 0000000..55e3890
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0051-eabispe.patch
@@ -0,0 +1,23 @@
+Upstream-Status: Pending
+
+Taken from http://gcc.gnu.org/ml/gcc-patches/2014-04/msg02064.html
+
+2014-04-30  Cesar Philippidis  <cesar@codesourcery.com>
+
+	gcc/
+	* dwarf2cfi.c (dwf_regno): Don't assert reg is a pseudo
+	register.
+	
+
+diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
+index 4180890..40ef0e2 100644
+--- a/gcc/dwarf2cfi.c
++++ b/gcc/dwarf2cfi.c
+@@ -906,7 +906,6 @@ notice_eh_throw (rtx insn)
+ static inline unsigned
+ dwf_regno (const_rtx reg)
+ {
+-  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
+   return DWARF_FRAME_REGNUM (REGNO (reg));
+ }
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0052-Add-target-hook-to-override-DWARF2-frame-register-si.patch b/recipes-devtools/gcc/gcc-4.9/0052-Add-target-hook-to-override-DWARF2-frame-register-si.patch
new file mode 100644
index 0000000..f6958b3
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0052-Add-target-hook-to-override-DWARF2-frame-register-si.patch
@@ -0,0 +1,138 @@
+From d626297e87e19251a284ea1e9360e831b48999ca Mon Sep 17 00:00:00 2001
+From: mpf <mpf@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Thu, 4 Sep 2014 08:32:05 +0000
+Subject: [PATCH] Add target hook to override DWARF2 frame register size
+
+gcc/
+
+	* target.def (TARGET_DWARF_FRAME_REG_MODE): New target hook.
+	* targhooks.c (default_dwarf_frame_reg_mode): New function.
+	* targhooks.h (default_dwarf_frame_reg_mode): New prototype.
+	* doc/tm.texi.in (TARGET_DWARF_FRAME_REG_MODE): Document.
+	* doc/tm.texi: Regenerate.
+	* dwarf2cfi.c (expand_builtin_init_dwarf_reg_sizes): Abstract mode
+	selection logic to default_dwarf_frame_reg_mode.
+
+
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@214898 138bc75d-0d04-0410-961f-82ee72b054a4
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Backport [gcc 5.0]
+
+---
+ gcc/ChangeLog      | 10 ++++++++++
+ gcc/doc/tm.texi    |  7 +++++++
+ gcc/doc/tm.texi.in |  2 ++
+ gcc/dwarf2cfi.c    |  4 +---
+ gcc/target.def     | 11 +++++++++++
+ gcc/targhooks.c    | 13 +++++++++++++
+ gcc/targhooks.h    |  1 +
+ 7 files changed, 45 insertions(+), 3 deletions(-)
+
+Index: gcc-4.9.2/gcc/doc/tm.texi
+===================================================================
+--- gcc-4.9.2.orig/gcc/doc/tm.texi
++++ gcc-4.9.2/gcc/doc/tm.texi
+@@ -9017,6 +9017,13 @@ register in Dwarf.  Otherwise, this hook
+ If not defined, the default is to return @code{NULL_RTX}.
+ @end deftypefn
+ 
++@deftypefn {Target Hook} {enum machine_mode} TARGET_DWARF_FRAME_REG_MODE (int @var{regno})
++Given a register, this hook should return the mode which the
++corresponding Dwarf frame register should have.  This is normally
++used to return a smaller mode than the raw mode to prevent call
++clobbered parts of a register altering the frame register size
++@end deftypefn
++
+ @deftypefn {Target Hook} void TARGET_INIT_DWARF_REG_SIZES_EXTRA (tree @var{address})
+ If some registers are represented in Dwarf-2 unwind information in
+ multiple pieces, define this hook to fill in information about the
+Index: gcc-4.9.2/gcc/doc/tm.texi.in
+===================================================================
+--- gcc-4.9.2.orig/gcc/doc/tm.texi.in
++++ gcc-4.9.2/gcc/doc/tm.texi.in
+@@ -6745,6 +6745,8 @@ the target supports DWARF 2 frame unwind
+ 
+ @hook TARGET_DWARF_REGISTER_SPAN
+ 
++@hook TARGET_DWARF_FRAME_REG_MODE
++
+ @hook TARGET_INIT_DWARF_REG_SIZES_EXTRA
+ 
+ @hook TARGET_ASM_TTYPE
+Index: gcc-4.9.2/gcc/dwarf2cfi.c
+===================================================================
+--- gcc-4.9.2.orig/gcc/dwarf2cfi.c
++++ gcc-4.9.2/gcc/dwarf2cfi.c
+@@ -271,11 +271,9 @@ expand_builtin_init_dwarf_reg_sizes (tre
+       if (rnum < DWARF_FRAME_REGISTERS)
+ 	{
+ 	  HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (mode);
+-	  enum machine_mode save_mode = reg_raw_mode[i];
+ 	  HOST_WIDE_INT size;
++	  enum machine_mode save_mode = targetm.dwarf_frame_reg_mode (i);
+ 
+-	  if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
+-	    save_mode = choose_hard_reg_mode (i, 1, true);
+ 	  if (dnum == DWARF_FRAME_RETURN_COLUMN)
+ 	    {
+ 	      if (save_mode == VOIDmode)
+Index: gcc-4.9.2/gcc/target.def
+===================================================================
+--- gcc-4.9.2.orig/gcc/target.def
++++ gcc-4.9.2/gcc/target.def
+@@ -3218,6 +3218,17 @@ If not defined, the default is to return
+  rtx, (rtx reg),
+  hook_rtx_rtx_null)
+ 
++/* Given a register return the mode of the corresponding DWARF frame
++   register.  */
++DEFHOOK
++(dwarf_frame_reg_mode,
++ "Given a register, this hook should return the mode which the\n\
++corresponding Dwarf frame register should have.  This is normally\n\
++used to return a smaller mode than the raw mode to prevent call\n\
++clobbered parts of a register altering the frame register size",
++ enum machine_mode, (int regno),
++ default_dwarf_frame_reg_mode)
++
+ /* If expand_builtin_init_dwarf_reg_sizes needs to fill in table
+    entries not corresponding directly to registers below
+    FIRST_PSEUDO_REGISTER, this hook should generate the necessary
+Index: gcc-4.9.2/gcc/targhooks.c
+===================================================================
+--- gcc-4.9.2.orig/gcc/targhooks.c
++++ gcc-4.9.2/gcc/targhooks.c
+@@ -1438,6 +1438,19 @@ default_debug_unwind_info (void)
+   return UI_NONE;
+ }
+ 
++/* Determine the correct mode for a Dwarf frame register that represents
++   register REGNO.  */
++
++enum machine_mode
++default_dwarf_frame_reg_mode (int regno)
++{
++  enum machine_mode save_mode = reg_raw_mode[regno];
++
++  if (HARD_REGNO_CALL_PART_CLOBBERED (regno, save_mode))
++    save_mode = choose_hard_reg_mode (regno, 1, true);
++  return save_mode;
++}
++
+ /* To be used by targets where reg_raw_mode doesn't return the right
+    mode for registers used in apply_builtin_return and apply_builtin_arg.  */
+ 
+Index: gcc-4.9.2/gcc/targhooks.h
+===================================================================
+--- gcc-4.9.2.orig/gcc/targhooks.h
++++ gcc-4.9.2/gcc/targhooks.h
+@@ -194,6 +194,7 @@ extern int default_label_align_max_skip
+ extern int default_jump_align_max_skip (rtx);
+ extern section * default_function_section(tree decl, enum node_frequency freq,
+ 					  bool startup, bool exit);
++extern enum machine_mode default_dwarf_frame_reg_mode (int);
+ extern enum machine_mode default_get_reg_raw_mode (int);
+ 
+ extern void *default_get_pch_validity (size_t *);
diff --git a/recipes-devtools/gcc/gcc-4.9/0053-gcc-fix-segfault-from-calling-free-on-non-malloc-d-a.patch b/recipes-devtools/gcc/gcc-4.9/0053-gcc-fix-segfault-from-calling-free-on-non-malloc-d-a.patch
new file mode 100644
index 0000000..23b445c
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0053-gcc-fix-segfault-from-calling-free-on-non-malloc-d-a.patch
@@ -0,0 +1,66 @@
+From a22a222c8f9299f6c07a0274388ade7d4ab8c28d Mon Sep 17 00:00:00 2001
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+Date: Fri, 20 Jun 2014 16:41:08 -0400
+Subject: [PATCH] gcc: fix segfault from calling free on non-malloc'd area
+
+We see the following on a 32bit gcc installed on 64 bit host:
+
+  Reading symbols from ./i586-pokymllib32-linux-gcc...done.
+  (gdb) run
+  Starting program: x86-pokymllib32-linux/lib32-gcc/4.9.0-r0/image/usr/bin/i586-pokymllib32-linux-gcc
+
+  Program received signal SIGSEGV, Segmentation fault.
+  0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6
+  (gdb) bt
+  #0  0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6
+  #1  0x0804b73c in set_multilib_dir () at gcc-4.9.0/gcc/gcc.c:7827
+  #2  main (argc=1, argv=0xffffd504) at gcc-4.9.0/gcc/gcc.c:6688
+  (gdb)
+
+The problem arises because we conditionally assign the pointer we
+eventually free, and the conditional may assign the pointer to the
+non-malloc'd internal string "." which fails when we free it here:
+
+   if (multilib_dir == NULL && multilib_os_dir != NULL
+       && strcmp (multilib_os_dir, ".") == 0)
+     {
+       free (CONST_CAST (char *, multilib_os_dir));
+       ...
+
+As suggested by Jakub, ensure the "." case is also malloc'd via
+xstrdup() and hence the pointer for the "." case can be freed.
+
+Cc: Jakub Jelinek <jakub@redhat.com>
+Cc: Jeff Law <law@redhat.com>
+Cc: Matthias Klose <doko@ubuntu.com>
+CC: Tobias Burnus <burnus@net-b.de>
+Upstream-Status: Accepted [ https://gcc.gnu.org/ml/gcc-patches/2014-06/msg02069.html ]
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+
+diff --git a/gcc/gcc.c b/gcc/gcc.c
+index 9ac18e60d801..168acf7eb0c9 100644
+--- a/gcc/gcc.c
++++ b/gcc/gcc.c
+@@ -7790,10 +7790,15 @@ set_multilib_dir (void)
+ 		q2++;
+ 	      if (*q2 == ':')
+ 		ml_end = q2;
+-	      new_multilib_os_dir = XNEWVEC (char, ml_end - q);
+-	      memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
+-	      new_multilib_os_dir[ml_end - q - 1] = '\0';
+-	      multilib_os_dir = *new_multilib_os_dir ? new_multilib_os_dir : ".";
++	      if (ml_end - q == 1)
++		multilib_os_dir = xstrdup (".");
++	      else
++		{
++		  new_multilib_os_dir = XNEWVEC (char, ml_end - q);
++		  memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
++		  new_multilib_os_dir[ml_end - q - 1] = '\0';
++		  multilib_os_dir = new_multilib_os_dir;
++		}
+ 
+ 	      if (q2 < end && *q2 == ':')
+ 		{
+-- 
+1.9.2
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0054-gcc-Makefile.in-fix-parallel-building-failure.patch b/recipes-devtools/gcc/gcc-4.9/0054-gcc-Makefile.in-fix-parallel-building-failure.patch
new file mode 100644
index 0000000..7e8efa1
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0054-gcc-Makefile.in-fix-parallel-building-failure.patch
@@ -0,0 +1,61 @@
+gcc/Makefile.in: fix parallel building failure
+
+The gcc-ar.o, gcc-nm.o, gcc-ranlib.o and errors.o included
+config.h which was a generated file. But no explicity rule
+to clarify the dependency. There was potential building
+failure while parallel make.
+
+For gcc-ar.o, gcc-nm.o and gcc-ranlib.o, they were compiled from one C
+source file gcc-ar.c, we add them to ALL_HOST_BACKEND_OBJS, so the
+'$(ALL_HOST_OBJS) : | $(generated_files)' rule could work for these
+objects.
+
+For errors.o, it is part of gengtype, and the gengtype generator program
+is special: Two versions are built. One is for the build machine, and one
+is for the host. We refered what gengtype-parse.o did (which also is part
+of gengtype).
+
+[GCC #61899]
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61899
+
+Upstream-Status: Submitted [gcc-patches@gcc.gnu.org]
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ gcc/Makefile.in | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/Makefile.in b/gcc/Makefile.in
+index 6475cba..56e50bb 100644
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -1481,13 +1481,16 @@ OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
+ 	opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
+ 	hash-table.o file-find.o
+ 
++# Objects compiled from one C source file gcc-ar.c
++OBJS-gcc-ar = gcc-ar.o gcc-nm.o gcc-ranlib.o
++
+ # This lists all host objects for the front ends.
+ ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
+ 
+ ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) $(OBJS-libcommon) \
+   $(OBJS-libcommon-target) @TREEBROWSER@ main.o c-family/cppspec.o \
+   $(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) \
+-  lto-wrapper.o
++  lto-wrapper.o $(OBJS-gcc-ar)
+ 
+ # This lists all host object files, whether they are included in this
+ # compilation or not.
+@@ -2437,6 +2440,8 @@ gengtype-parse.o: $(CONFIG_H)
+ CFLAGS-build/gengtype-parse.o += -DGENERATOR_FILE
+ build/gengtype-parse.o: $(BCONFIG_H)
+ 
++errors.o : $(CONFIG_H)
++
+ gengtype-state.o build/gengtype-state.o: gengtype-state.c $(SYSTEM_H) \
+   gengtype.h errors.h double-int.h version.h $(HASHTAB_H) $(OBSTACK_H) \
+   $(XREGEX_H)
+-- 
+1.8.1.2
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0055-dwarf-reg-processing-helper.patch b/recipes-devtools/gcc/gcc-4.9/0055-dwarf-reg-processing-helper.patch
new file mode 100644
index 0000000..557dab0
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0055-dwarf-reg-processing-helper.patch
@@ -0,0 +1,148 @@
+From 4fd39f1329379e00f958394adde6be96f0caf21f Mon Sep 17 00:00:00 2001
+From: hainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Fri, 5 Dec 2014 16:53:22 +0000
+Subject: [PATCH] 2014-12-05  Olivier Hainque  <hainque@adacore.com>
+
+        * dwarf2cfi.c (init_one_dwarf_reg_size): New helper, processing
+        one particular reg for expand_builtin_init_dwarf_reg_sizes.
+        (expand_builtin_init_dwarf_reg_sizes): Rework to use helper and
+        account for dwarf register spans.
+
+
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218428 138bc75d-0d04-0410-961f-82ee72b054a4
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Backport [gcc 5.0]
+
+---
+ gcc/ChangeLog   |  7 +++++
+ gcc/dwarf2cfi.c | 98 +++++++++++++++++++++++++++++++++++++++++++++------------
+ 2 files changed, 85 insertions(+), 20 deletions(-)
+
+Index: gcc-4.9.2/gcc/dwarf2cfi.c
+===================================================================
+--- gcc-4.9.2.orig/gcc/dwarf2cfi.c
++++ gcc-4.9.2/gcc/dwarf2cfi.c
+@@ -252,7 +252,59 @@ init_return_column_size (enum machine_mo
+ 		  gen_int_mode (size, mode));
+ }
+ 
+-/* Generate code to initialize the register size table.  */
++/* Datastructure used by expand_builtin_init_dwarf_reg_sizes and
++   init_one_dwarf_reg_size to communicate on what has been done by the
++   latter.  */
++
++typedef struct
++{
++  /* Whether the dwarf return column was initialized.  */
++  bool wrote_return_column;
++
++  /* For each hard register REGNO, whether init_one_dwarf_reg_size
++     was given REGNO to process already.  */
++  bool processed_regno [FIRST_PSEUDO_REGISTER];
++
++} init_one_dwarf_reg_state;
++
++/* Helper for expand_builtin_init_dwarf_reg_sizes.  Generate code to
++   initialize the dwarf register size table entry corresponding to register
++   REGNO in REGMODE.  TABLE is the table base address, SLOTMODE is the mode to
++   use for the size entry to initialize, and INIT_STATE is the communication
++   datastructure conveying what we're doing to our caller.  */
++
++static
++void init_one_dwarf_reg_size (int regno, machine_mode regmode,
++			      rtx table, machine_mode slotmode,
++			      init_one_dwarf_reg_state *init_state)
++{
++  const unsigned int dnum = DWARF_FRAME_REGNUM (regno);
++  const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
++
++  const HOST_WIDE_INT slotoffset = rnum * GET_MODE_SIZE (slotmode);
++  const HOST_WIDE_INT regsize = GET_MODE_SIZE (regmode);
++
++  init_state->processed_regno[regno] = true;
++
++  if (rnum >= DWARF_FRAME_REGISTERS)
++    return;
++
++  if (dnum == DWARF_FRAME_RETURN_COLUMN)
++    {
++      if (regmode == VOIDmode)
++	return;
++      init_state->wrote_return_column = true;
++    }
++
++  if (slotoffset < 0)
++    return;
++
++  emit_move_insn (adjust_address (table, slotmode, slotoffset),
++		  gen_int_mode (regsize, slotmode));
++}
++
++/* Generate code to initialize the dwarf register size table located
++   at the provided ADDRESS.  */
+ 
+ void
+ expand_builtin_init_dwarf_reg_sizes (tree address)
+@@ -261,35 +313,40 @@ expand_builtin_init_dwarf_reg_sizes (tre
+   enum machine_mode mode = TYPE_MODE (char_type_node);
+   rtx addr = expand_normal (address);
+   rtx mem = gen_rtx_MEM (BLKmode, addr);
+-  bool wrote_return_column = false;
++
++  init_one_dwarf_reg_state init_state;
++
++  memset ((char *)&init_state, 0, sizeof (init_state));
+ 
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+-      unsigned int dnum = DWARF_FRAME_REGNUM (i);
+-      unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
+-
+-      if (rnum < DWARF_FRAME_REGISTERS)
+-	{
+-	  HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (mode);
+-	  HOST_WIDE_INT size;
+-	  enum machine_mode save_mode = targetm.dwarf_frame_reg_mode (i);
++      machine_mode save_mode;
++      rtx span;
+ 
+-	  if (dnum == DWARF_FRAME_RETURN_COLUMN)
++      /* No point in processing a register multiple times.  This could happen
++        with register spans, e.g. when a reg is first processed as a piece of
++        a span, then as a register on its own later on.  */
++
++      if (init_state.processed_regno[i])
++       continue;
++
++      save_mode = targetm.dwarf_frame_reg_mode (i);
++      span = targetm.dwarf_register_span (gen_rtx_REG (save_mode, i));
++      if (!span)
++       init_one_dwarf_reg_size (i, save_mode, mem, mode, &init_state);
++      else
++       {
++         for (int si = 0; si < XVECLEN (span, 0); si++)
+ 	    {
+-	      if (save_mode == VOIDmode)
+-		continue;
+-	      wrote_return_column = true;
+-	    }
+-	  size = GET_MODE_SIZE (save_mode);
+-	  if (offset < 0)
+-	    continue;
++             rtx reg = XVECEXP (span, 0, si);
++             init_one_dwarf_reg_size
++               (REGNO (reg), GET_MODE (reg), mem, mode, &init_state);
++           }
+ 
+-	  emit_move_insn (adjust_address (mem, mode, offset),
+-			  gen_int_mode (size, mode));
+ 	}
+     }
+ 
+-  if (!wrote_return_column)
++  if (!init_state.wrote_return_column)
+     init_return_column_size (mode, mem, DWARF_FRAME_RETURN_COLUMN);
+ 
+ #ifdef DWARF_ALT_FRAME_RETURN_COLUMN
diff --git a/recipes-devtools/gcc/gcc-4.9/0056-define-default-cfa-register-mapping.patch b/recipes-devtools/gcc/gcc-4.9/0056-define-default-cfa-register-mapping.patch
new file mode 100644
index 0000000..3b6c94c
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0056-define-default-cfa-register-mapping.patch
@@ -0,0 +1,75 @@
+From c0235a33de8c4f78cce35b2a8c2035c83fe1bd14 Mon Sep 17 00:00:00 2001
+From: hainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Fri, 5 Dec 2014 17:01:42 +0000
+Subject: [PATCH] 2014-12-05  Olivier Hainque  <hainque@adacore.com>
+
+        gcc/
+        * defaults.h: (DWARF_REG_TO_UNWIND_COLUMN): Define default.
+        * dwarf2cfi.c (init_one_dwarf_reg_size): Honor
+        DWARF_REG_TO_UNWIND_COLUMN.
+
+        libgcc/
+        * unwind-dw2.c (DWARF_REG_TO_UNWIND_COLUMN): Remove default def,
+        now provided by defaults.h.
+
+
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218429 138bc75d-0d04-0410-961f-82ee72b054a4
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Backport [gcc 5.0]
+
+---
+ gcc/ChangeLog       | 6 ++++++
+ gcc/defaults.h      | 5 +++++
+ gcc/dwarf2cfi.c     | 3 ++-
+ libgcc/ChangeLog    | 5 +++++
+ libgcc/unwind-dw2.c | 4 ----
+ 5 files changed, 18 insertions(+), 5 deletions(-)
+
+Index: gcc-4.9.2/gcc/defaults.h
+===================================================================
+--- gcc-4.9.2.orig/gcc/defaults.h
++++ gcc-4.9.2/gcc/defaults.h
+@@ -438,6 +438,11 @@ see the files COPYING3 and COPYING.RUNTI
+ #define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
+ #endif
+ 
++/* The mapping from dwarf CFA reg number to internal dwarf reg numbers.  */
++#ifndef DWARF_REG_TO_UNWIND_COLUMN
++#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
++#endif
++
+ /* Map register numbers held in the call frame info that gcc has
+    collected using DWARF_FRAME_REGNUM to those that should be output in
+    .debug_frame and .eh_frame.  */
+Index: gcc-4.9.2/gcc/dwarf2cfi.c
+===================================================================
+--- gcc-4.9.2.orig/gcc/dwarf2cfi.c
++++ gcc-4.9.2/gcc/dwarf2cfi.c
+@@ -280,8 +280,9 @@ void init_one_dwarf_reg_size (int regno,
+ {
+   const unsigned int dnum = DWARF_FRAME_REGNUM (regno);
+   const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
++  const unsigned int dcol = DWARF_REG_TO_UNWIND_COLUMN (rnum);
+ 
+-  const HOST_WIDE_INT slotoffset = rnum * GET_MODE_SIZE (slotmode);
++  const HOST_WIDE_INT slotoffset = dcol * GET_MODE_SIZE (slotmode);
+   const HOST_WIDE_INT regsize = GET_MODE_SIZE (regmode);
+ 
+   init_state->processed_regno[regno] = true;
+Index: gcc-4.9.2/libgcc/unwind-dw2.c
+===================================================================
+--- gcc-4.9.2.orig/libgcc/unwind-dw2.c
++++ gcc-4.9.2/libgcc/unwind-dw2.c
+@@ -55,10 +55,6 @@
+ #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
+ #endif
+ 
+-#ifndef DWARF_REG_TO_UNWIND_COLUMN
+-#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
+-#endif
+-
+ /* ??? For the public function interfaces, we tend to gcc_assert that the
+    column numbers are in range.  For the dwarf2 unwind info this does happen,
+    although so far in a case that doesn't actually matter.
diff --git a/recipes-devtools/gcc/gcc-4.9/0057-aarch64-config.patch b/recipes-devtools/gcc/gcc-4.9/0057-aarch64-config.patch
new file mode 100644
index 0000000..f295596
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0057-aarch64-config.patch
@@ -0,0 +1,32 @@
+Disable the MULTILIB_OSDIRNAMES and other multilib options.
+
+Hard coding the MULTILIB_OSDIRNAMES with ../lib64 is causing problems on
+systems where the libdir is NOT set to /lib64.  This is allowed by the ABI, as
+long as the dynamic loader is present in /lib.
+
+We simply want to use the default rules in gcc to find and configure the 
+normal libdir.
+
+Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
+
+Index: gcc-4.9.1/gcc/config/aarch64/t-aarch64-linux
+===================================================================
+--- gcc-4.9.1.orig/gcc/config/aarch64/t-aarch64-linux
++++ gcc-4.9.1/gcc/config/aarch64/t-aarch64-linux
+@@ -21,11 +21,11 @@
+ LIB1ASMSRC   = aarch64/lib1funcs.asm
+ LIB1ASMFUNCS = _aarch64_sync_cache_range
+ 
+-AARCH_BE = $(if $(findstring TARGET_BIG_ENDIAN_DEFAULT=1, $(tm_defines)),_be)
+-MULTILIB_OSDIRNAMES = .=../lib64$(call if_multiarch,:aarch64$(AARCH_BE)-linux-gnu)
+-MULTIARCH_DIRNAME = $(call if_multiarch,aarch64$(AARCH_BE)-linux-gnu)
++#AARCH_BE = $(if $(findstring TARGET_BIG_ENDIAN_DEFAULT=1, $(tm_defines)),_be)
++#MULTILIB_OSDIRNAMES = .=../lib64$(call if_multiarch,:aarch64$(AARCH_BE)-linux-gnu)
++#MULTIARCH_DIRNAME = $(call if_multiarch,aarch64$(AARCH_BE)-linux-gnu)
+ 
+ # Disable the multilib for linux-gnu targets for the time being; focus
+ # on the baremetal targets.
+-MULTILIB_OPTIONS    =
+-MULTILIB_DIRNAMES   =
++#MULTILIB_OPTIONS    =
++#MULTILIB_DIRNAMES   =
diff --git a/recipes-devtools/gcc/gcc-4.9/0058-gcc-r212171.patch b/recipes-devtools/gcc/gcc-4.9/0058-gcc-r212171.patch
new file mode 100644
index 0000000..d442ba8
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0058-gcc-r212171.patch
@@ -0,0 +1,113 @@
+From ca03cf1b133d66eb978c68f6dbc345e9aabcba88 Mon Sep 17 00:00:00 2001
+From: uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Mon, 30 Jun 2014 19:30:52 +0000
+Subject: [PATCH] r212171
+
+* except.c (emit_note_eh_region_end): New helper
+ function. 	(convert_to_eh_region_ranges): Use
+ emit_note_eh_region_end to 	emit EH_REGION_END note. 
+ * jump.c (cleanup_barriers): Do not split a call and its 
+ corresponding CALL_ARG_LOCATION note.
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212171 138bc75d-0d04-0410-961f-82ee72b054a4
+
+Upstream-Status: Backport [https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=212171]
+Signed-off-by: Baoshan Pang <baoshan.pang@windriver.com>
+---
+ gcc/except.c |   23 ++++++++++++++++++-----
+ gcc/jump.c   |   19 +++++++++++++++----
+ 2 files changed, 33 insertions(+), 9 deletions(-)
+
+diff --git a/gcc/except.c b/gcc/except.c
+index dc5c1d2..7ac114f 100644
+--- a/gcc/except.c
++++ b/gcc/except.c
+@@ -2466,6 +2466,20 @@ add_call_site (rtx landing_pad, int action, int section)
+   return call_site_base + crtl->eh.call_site_record_v[section]->length () - 1;
+ }
+ 
++static rtx
++emit_note_eh_region_end (rtx insn)
++{
++  rtx next = NEXT_INSN (insn);
++
++  /* Make sure we do not split a call and its corresponding
++     CALL_ARG_LOCATION note.  */
++  if (next && NOTE_P (next)
++      && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
++    insn = next;
++
++  return emit_note_after (NOTE_INSN_EH_REGION_END, insn);
++}
++
+ /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
+    The new note numbers will not refer to region numbers, but
+    instead to call site entries.  */
+@@ -2544,8 +2558,8 @@ convert_to_eh_region_ranges (void)
+ 		note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
+ 					 first_no_action_insn_before_switch);
+ 		NOTE_EH_HANDLER (note) = call_site;
+-		note = emit_note_after (NOTE_INSN_EH_REGION_END,
+-					last_no_action_insn_before_switch);
++		note
++		  = emit_note_eh_region_end (last_no_action_insn_before_switch);
+ 		NOTE_EH_HANDLER (note) = call_site;
+ 		gcc_assert (last_action != -3
+ 			    || (last_action_insn
+@@ -2569,8 +2583,7 @@ convert_to_eh_region_ranges (void)
+ 		    first_no_action_insn = NULL_RTX;
+ 		  }
+ 
+-		note = emit_note_after (NOTE_INSN_EH_REGION_END,
+-					last_action_insn);
++		note = emit_note_eh_region_end (last_action_insn);
+ 		NOTE_EH_HANDLER (note) = call_site;
+ 	      }
+ 
+@@ -2617,7 +2630,7 @@ convert_to_eh_region_ranges (void)
+ 
+   if (last_action >= -1 && ! first_no_action_insn)
+     {
+-      note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
++      note = emit_note_eh_region_end (last_action_insn);
+       NOTE_EH_HANDLER (note) = call_site;
+     }
+ 
+diff --git a/gcc/jump.c b/gcc/jump.c
+index 9418f65..a5e5f52 100644
+--- a/gcc/jump.c
++++ b/gcc/jump.c
+@@ -121,15 +121,26 @@ rebuild_jump_labels_chain (rtx chain)
+ static unsigned int
+ cleanup_barriers (void)
+ {
+-  rtx insn, next, prev;
+-  for (insn = get_insns (); insn; insn = next)
++  rtx insn;
++  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+     {
+-      next = NEXT_INSN (insn);
+       if (BARRIER_P (insn))
+ 	{
+-	  prev = prev_nonnote_insn (insn);
++	  rtx prev = prev_nonnote_insn (insn);
+ 	  if (!prev)
+ 	    continue;
++
++	  if (CALL_P (prev))
++	    {
++	      /* Make sure we do not split a call and its corresponding
++		 CALL_ARG_LOCATION note.  */
++	      rtx next = NEXT_INSN (prev);
++
++	      if (NOTE_P (next)
++		  && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
++		prev = next;
++	    }
++
+ 	  if (BARRIER_P (prev))
+ 	    delete_insn (insn);
+ 	  else if (prev != PREV_INSN (insn))
+-- 
+1.7.9.5
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0059-gcc-PR-rtl-optimization-63348.patch b/recipes-devtools/gcc/gcc-4.9/0059-gcc-PR-rtl-optimization-63348.patch
new file mode 100644
index 0000000..de827cb
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0059-gcc-PR-rtl-optimization-63348.patch
@@ -0,0 +1,59 @@
+From 6eae3e637fcc22d21b51d44d61e3a9cb4825e776 Mon Sep 17 00:00:00 2001
+From: Jackie Huang <jackie.huang@windriver.com>
+Date: Thu, 30 Oct 2014 20:37:14 -0700
+Subject: [PATCH]PR rtl-optimization/63348
+ 
+PR rtl-optimization/63348
+* emit-rtl.c (try_split): Do not emit extra barrier.
+
+Note: this patch is to fix the side effect introduced by r212171 which was reported at:
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63348
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@215613 138bc75d-0d04-0410-961f-82ee72b054a4
+
+Upstream-Status: Backport [https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=215613]
+Signed-off-by: Baoshan Pang <baoshan.pang@windriver.com>
+Signed-off-by: Jackie Huang <jackie.huang@windriver.com>
+---
+ gcc/emit-rtl.c |   11 -----------
+ 1 files changed, 0 insertions(+), 11 deletions(-)
+
+diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
+index 4736f8d..ae69dbd 100644
+--- a/gcc/emit-rtl.c
++++ b/gcc/emit-rtl.c
+@@ -3422,7 +3422,6 @@ try_split (rtx pat, rtx trial, int last)
+ {
+   rtx before = PREV_INSN (trial);
+   rtx after = NEXT_INSN (trial);
+-  int has_barrier = 0;
+   rtx note, seq, tem;
+   int probability;
+   rtx insn_last, insn;
+@@ -3441,14 +3440,6 @@ try_split (rtx pat, rtx trial, int last)
+ 
+   split_branch_probability = -1;
+ 
+-  /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER.
+-     We may need to handle this specially.  */
+-  if (after && BARRIER_P (after))
+-    {
+-      has_barrier = 1;
+-      after = NEXT_INSN (after);
+-    }
+-
+   if (!seq)
+     return trial;
+ 
+@@ -3594,8 +3585,6 @@ try_split (rtx pat, rtx trial, int last)
+   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATION (trial));
+ 
+   delete_insn (trial);
+-  if (has_barrier)
+-    emit_barrier_after (tem);
+ 
+   /* Recursively call try_split for each new insn created; by the
+      time control returns here that insn will be fully split, so
+-- 
+1.7.1
+
diff --git a/recipes-devtools/gcc/gcc-4.9/0060-Only-allow-e500-double-in-SPE_SIMD_REGNO_P-registers.patch b/recipes-devtools/gcc/gcc-4.9/0060-Only-allow-e500-double-in-SPE_SIMD_REGNO_P-registers.patch
new file mode 100644
index 0000000..75a9fdd
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0060-Only-allow-e500-double-in-SPE_SIMD_REGNO_P-registers.patch
@@ -0,0 +1,55 @@
+From 5c0092070253113cf0d9c45eacc884b3ecc34d81 Mon Sep 17 00:00:00 2001
+From: jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Sat, 25 Oct 2014 00:23:17 +0000
+Subject: [PATCH] Only allow e500 double in SPE_SIMD_REGNO_P registers.
+
+rs6000_hard_regno_nregs_internal allows SPE vectors in single
+registers satisfying SPE_SIMD_REGNO_P (i.e. register numbers 0 to
+31).  However, the corresponding test for e500 double treats all
+registers as being able to store a 64-bit value, rather than just
+those GPRs.
+
+Logically this inconsistency is wrong; in addition, it causes problems
+unwinding from signal handlers.  linux-unwind.h uses
+ARG_POINTER_REGNUM as a place to store the return address from a
+signal handler, but this logic in rs6000_hard_regno_nregs_internal
+results in that being considered an 8-byte register, resulting in
+assertion failures.
+(<https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02625.html> first
+needs to be applied for unwinding to work in general on e500.)  This
+patch makes rs6000_hard_regno_nregs_internal handle the e500 double
+case consistently with SPE vectors.
+
+Tested with no regressions with cross to powerpc-linux-gnuspe (given
+the aforementioned patch applied).  Failures of signal handling
+unwinding tests such as gcc.dg/cleanup-{8,9,10,11}.c are fixed by this
+patch.
+
+	* config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Do
+	not allow e500 double in registers not satisyfing
+	SPE_SIMD_REGNO_P.
+
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216688 138bc75d-0d04-0410-961f-82ee72b054a4
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Backport [gcc 5.0]
+
+---
+ gcc/ChangeLog              | 6 ++++++
+ gcc/config/rs6000/rs6000.c | 2 +-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+Index: gcc-4.9.2/gcc/config/rs6000/rs6000.c
+===================================================================
+--- gcc-4.9.2.orig/gcc/config/rs6000/rs6000.c
++++ gcc-4.9.2/gcc/config/rs6000/rs6000.c
+@@ -1703,7 +1703,7 @@ rs6000_hard_regno_nregs_internal (int re
+      SCmode so as to pass the value correctly in a pair of
+      registers.  */
+   else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
+-	   && !DECIMAL_FLOAT_MODE_P (mode))
++	   && !DECIMAL_FLOAT_MODE_P (mode) && SPE_SIMD_REGNO_P (regno))
+     reg_size = UNITS_PER_FP_WORD;
+ 
+   else
diff --git a/recipes-devtools/gcc/gcc-4.9/0061-target-gcc-includedir.patch b/recipes-devtools/gcc/gcc-4.9/0061-target-gcc-includedir.patch
new file mode 100644
index 0000000..f48c66d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0061-target-gcc-includedir.patch
@@ -0,0 +1,81 @@
+Ensure target gcc headers can be included
+
+There are a few headers installed as part of the OpenEmbedded
+gcc-runtime target (omp.h, ssp/*.h). Being installed from a recipe
+built for the target architecture, these are within the target
+sysroot and not cross/nativesdk; thus they weren't able to be
+found by gcc with the existing search paths. Add support for
+picking up these headers under the sysroot supplied on the gcc
+command line in order to resolve this.
+
+Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
+
+Upstream-Status: Pending
+
+--- a/gcc/Makefile.in	2014-12-23 11:57:33.327873331 +0000
++++ b/gcc/Makefile.in	2015-01-21 11:32:35.447305394 +0000
+@@ -587,6 +587,7 @@
+ 
+ # Directory in which the compiler finds libraries etc.
+ libsubdir = $(libdir)/gcc/$(target_noncanonical)/$(version)
++libsubdir_target = gcc/$(target_noncanonical)/$(version)
+ # Directory in which the compiler finds executables
+ libexecsubdir = $(libexecdir)/gcc/$(target_noncanonical)/$(version)
+ # Directory in which all plugin resources are installed
+@@ -2534,6 +2535,7 @@
+ 
+ PREPROCESSOR_DEFINES = \
+   -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
++  -DGCC_INCLUDE_SUBDIR_TARGET=\"$(libsubdir_target)/include\" \
+   -DFIXED_INCLUDE_DIR=\"$(libsubdir)/include-fixed\" \
+   -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
+   -DGPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT=$(gcc_gxx_include_dir_add_sysroot) \
+--- a/gcc/cppdefault.c	2015-01-13 17:40:26.131012725 +0000
++++ b/gcc/cppdefault.c	2015-01-21 11:30:08.928426492 +0000
+@@ -59,6 +59,10 @@
+     /* This is the dir for gcc's private headers.  */
+     { GCC_INCLUDE_DIR, "GCC", 0, 0, 0, 0 },
+ #endif
++#ifdef GCC_INCLUDE_SUBDIR_TARGET
++    /* This is the dir for gcc's private headers under the specified sysroot.  */
++    { STANDARD_STARTFILE_PREFIX_2 GCC_INCLUDE_SUBDIR_TARGET, "GCC", 0, 0, 1, 0 },
++#endif
+ #ifdef LOCAL_INCLUDE_DIR
+     /* /usr/local/include comes before the fixincluded header files.  */
+     { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 2 },
+diff --git a/gcc/defaults.h b/gcc/defaults.h
+index f94ae17..d98b40b 100644
+--- a/gcc/defaults.h
++++ b/gcc/defaults.h
+@@ -1390,4 +1390,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ 
+ #endif /* GCC_INSN_FLAGS_H  */
+ 
++/* Default prefixes to attach to command names.  */
++
++#ifndef STANDARD_STARTFILE_PREFIX_1
++#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
++#endif
++#ifndef STANDARD_STARTFILE_PREFIX_2
++#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
++#endif
++
+ #endif  /* ! GCC_DEFAULTS_H */
+diff --git a/gcc/gcc.c b/gcc/gcc.c
+index 9f0b781..174fca8 100644
+--- a/gcc/gcc.c
++++ b/gcc/gcc.c
+@@ -1189,13 +1189,6 @@ static const char *gcc_libexec_prefix;
+ 
+ /* Default prefixes to attach to command names.  */
+ 
+-#ifndef STANDARD_STARTFILE_PREFIX_1
+-#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
+-#endif
+-#ifndef STANDARD_STARTFILE_PREFIX_2
+-#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
+-#endif
+-
+ #ifdef CROSS_DIRECTORY_STRUCTURE  /* Don't use these prefixes for a cross compiler.  */
+ #undef MD_EXEC_PREFIX
+ #undef MD_STARTFILE_PREFIX
diff --git a/recipes-devtools/gcc/gcc-4.9/0062-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch b/recipes-devtools/gcc/gcc-4.9/0062-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch
new file mode 100644
index 0000000..c48bd48
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0062-Use-SYSTEMLIBS_DIR-replacement-instead-of-hardcoding.patch
@@ -0,0 +1,24 @@
+From 861bcfd4ae814f351e0c668ee26d01d1331e0422 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Tue, 28 Apr 2015 23:15:27 -0700
+Subject: [PATCH 36/37] Use SYSTEMLIBS_DIR replacement instead of hardcoding
+ base_libdir
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ gcc/config/aarch64/aarch64-linux.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: gcc-4.9.2/gcc/config/aarch64/aarch64-linux.h
+===================================================================
+--- gcc-4.9.2.orig/gcc/config/aarch64/aarch64-linux.h
++++ gcc-4.9.2/gcc/config/aarch64/aarch64-linux.h
+@@ -21,7 +21,7 @@
+ #ifndef GCC_AARCH64_LINUX_H
+ #define GCC_AARCH64_LINUX_H
+ 
+-#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-aarch64%{mbig-endian:_be}.so.1"
++#define GLIBC_DYNAMIC_LINKER SYSTEMLIBS_DIR "ld-linux-aarch64%{mbig-endian:_be}.so.1"
+ 
+ #define CPP_SPEC "%{pthread:-D_REENTRANT}"
+ 
diff --git a/recipes-devtools/gcc/gcc-4.9/0063-nativesdk-gcc-support.patch b/recipes-devtools/gcc/gcc-4.9/0063-nativesdk-gcc-support.patch
new file mode 100644
index 0000000..f9efa45
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0063-nativesdk-gcc-support.patch
@@ -0,0 +1,198 @@
+Being able to build a nativesdk gcc is useful, particularly in cases
+where the host compiler may be of an incompatible version (or a 32
+bit compiler is needed).
+
+Sadly, building nativesdk-gcc is not straight forward. We install
+nativesdk-gcc into a relocatable location and this means that its
+library locations can change. "Normal" sysroot support doesn't help
+in this case since the values of paths like "libdir" change, not just
+base root directory of the system.
+
+In order to handle this we do two things:
+
+a) Add %r into spec file markup which can be used for injected paths
+   such as SYSTEMLIBS_DIR (see gcc_multilib_setup()).
+b) Add other paths which need relocation into a .gccrelocprefix section
+   which the relocation code will notice and adjust automatically.
+
+Upstream-Status: Inappropriate
+RP 2015/7/28
+diff --git a/gcc/gcc.c b/gcc/gcc.c
+index 5fd3d0a..2de29aa 100644
+--- a/gcc/gcc.c
++++ b/gcc/gcc.c
+@@ -120,6 +120,8 @@ static const char *target_system_root = TARGET_SYSTEM_ROOT;
+ #else
+ static const char *target_system_root = 0;
+ #endif
++ 
++static char target_relocatable_prefix[4096] __attribute__ ((section (".gccrelocprefix"))) = SYSTEMLIBS_DIR;
+ 
+ /* Nonzero means pass the updated target_system_root to the compiler.  */
+ 
+@@ -384,6 +386,7 @@ or with constant text in a single argument.
+  %G     process LIBGCC_SPEC as a spec.
+  %R     Output the concatenation of target_system_root and
+         target_sysroot_suffix.
++ %r     Output the base path target_relocatable_prefix
+  %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
+  %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
+  %C     process CPP_SPEC as a spec.
+@@ -1218,10 +1221,10 @@ static const char *gcc_libexec_prefix;
+    gcc_exec_prefix is set because, in that case, we know where the
+    compiler has been installed, and use paths relative to that
+    location instead.  */
+-static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
+-static const char *const standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
+-static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
+-static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
++static char standard_exec_prefix[4096] __attribute__ ((section (".gccrelocprefix"))) = STANDARD_EXEC_PREFIX;
++static char standard_libexec_prefix[4096] __attribute__ ((section (".gccrelocprefix"))) = STANDARD_LIBEXEC_PREFIX;
++static char standard_bindir_prefix[4096] __attribute__ ((section (".gccrelocprefix"))) = STANDARD_BINDIR_PREFIX;
++static char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
+ 
+ /* For native compilers, these are well-known paths containing
+    components that may be provided by the system.  For cross
+@@ -1229,9 +1232,9 @@ static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
+ static const char *md_exec_prefix = MD_EXEC_PREFIX;
+ static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
+ static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
+-static const char *const standard_startfile_prefix_1
++static char standard_startfile_prefix_1[4096] __attribute__ ((section (".gccrelocprefix")))
+   = STANDARD_STARTFILE_PREFIX_1;
+-static const char *const standard_startfile_prefix_2
++static char standard_startfile_prefix_2[4096] __attribute__ ((section (".gccrelocprefix")))
+   = STANDARD_STARTFILE_PREFIX_2;
+ 
+ /* A relative path to be used in finding the location of tools
+@@ -5305,6 +5308,11 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
+ 	      }
+ 	    break;
+ 
++          case 'r':
++              obstack_grow (&obstack, target_relocatable_prefix,
++		      strlen (target_relocatable_prefix));
++            break;
++
+ 	  case 'S':
+ 	    value = do_spec_1 (startfile_spec, 0, NULL);
+ 	    if (value != 0)
+
+diff --git a/gcc/cppdefault.c b/gcc/cppdefault.c
+index dad69e6..cf43f28 100644
+--- a/gcc/cppdefault.c
++++ b/gcc/cppdefault.c
+@@ -35,6 +35,30 @@
+ # undef CROSS_INCLUDE_DIR
+ #endif
+ 
++static char GPLUSPLUS_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = GPLUSPLUS_INCLUDE_DIR;
++static char GCC_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = GCC_INCLUDE_DIR;
++static char GPLUSPLUS_TOOL_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = GPLUSPLUS_TOOL_INCLUDE_DIR;
++static char GPLUSPLUS_BACKWARD_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = GPLUSPLUS_BACKWARD_INCLUDE_DIR;
++static char STANDARD_STARTFILE_PREFIX_2VAR[4096] __attribute__ ((section (".gccrelocprefix"))) = STANDARD_STARTFILE_PREFIX_2 GCC_INCLUDE_SUBDIR_TARGET;
++#ifdef LOCAL_INCLUDE_DIR
++static char LOCAL_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = LOCAL_INCLUDE_DIR;
++#endif
++#ifdef PREFIX_INCLUDE_DIR
++static char PREFIX_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = PREFIX_INCLUDE_DIR;
++#endif
++#ifdef FIXED_INCLUDE_DIR
++static char FIXED_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = FIXED_INCLUDE_DIR;
++#endif
++#ifdef CROSS_INCLUDE_DIR
++static char CROSS_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = CROSS_INCLUDE_DIR;
++#endif
++#ifdef TOOL_INCLUDE_DIR
++static char TOOL_INCLUDE_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = TOOL_INCLUDE_DIR;
++#endif
++#ifdef NATIVE_SYSTEM_HEADER_DIR
++static char NATIVE_SYSTEM_HEADER_DIRVAR[4096] __attribute__ ((section (".gccrelocprefix"))) = NATIVE_SYSTEM_HEADER_DIR;
++#endif
++
+ const struct default_include cpp_include_defaults[]
+ #ifdef INCLUDE_DEFAULTS
+ = INCLUDE_DEFAULTS;
+@@ -42,38 +66,38 @@ const struct default_include cpp_include_defaults[]
+ = {
+ #ifdef GPLUSPLUS_INCLUDE_DIR
+     /* Pick up GNU C++ generic include files.  */
+-    { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1,
++    { GPLUSPLUS_INCLUDE_DIRVAR, "G++", 1, 1,
+       GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT, 0 },
+ #endif
+ #ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
+     /* Pick up GNU C++ target-dependent include files.  */
+-    { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1,
++    { GPLUSPLUS_TOOL_INCLUDE_DIRVAR, "G++", 1, 1,
+       GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT, 1 },
+ #endif
+ #ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+     /* Pick up GNU C++ backward and deprecated include files.  */
+-    { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1,
++    { GPLUSPLUS_BACKWARD_INCLUDE_DIRVAR, "G++", 1, 1,
+       GPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT, 0 },
+ #endif
+ #ifdef GCC_INCLUDE_DIR
+     /* This is the dir for gcc's private headers.  */
+-    { GCC_INCLUDE_DIR, "GCC", 0, 0, 0, 0 },
++    { GCC_INCLUDE_DIRVAR, "GCC", 0, 0, 0, 0 },
+ #endif
+ #ifdef GCC_INCLUDE_SUBDIR_TARGET
+     /* This is the dir for gcc's private headers under the specified sysroot.  */
+-    { STANDARD_STARTFILE_PREFIX_2 GCC_INCLUDE_SUBDIR_TARGET, "GCC", 0, 0, 1, 0 },
++    { STANDARD_STARTFILE_PREFIX_2VAR, "GCC", 0, 0, 1, 0 },
+ #endif
+ #ifdef LOCAL_INCLUDE_DIR
+     /* /usr/local/include comes before the fixincluded header files.  */
+-    { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 2 },
+-    { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 0 },
++    { LOCAL_INCLUDE_DIRVAR, 0, 0, 1, 1, 2 },
++    { LOCAL_INCLUDE_DIRVAR, 0, 0, 1, 1, 0 },
+ #endif
+ #ifdef PREFIX_INCLUDE_DIR
+-    { PREFIX_INCLUDE_DIR, 0, 0, 1, 0, 0 },
++    { PREFIX_INCLUDE_DIRVAR, 0, 0, 1, 0, 0 },
+ #endif
+ #ifdef FIXED_INCLUDE_DIR
+     /* This is the dir for fixincludes.  */
+-    { FIXED_INCLUDE_DIR, "GCC", 0, 0, 0,
++    { FIXED_INCLUDE_DIRVAR, "GCC", 0, 0, 0,
+       /* A multilib suffix needs adding if different multilibs use
+ 	 different headers.  */
+ #ifdef SYSROOT_HEADERS_SUFFIX_SPEC
+@@ -85,16 +109,16 @@ const struct default_include cpp_include_defaults[]
+ #endif
+ #ifdef CROSS_INCLUDE_DIR
+     /* One place the target system's headers might be.  */
+-    { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0, 0 },
++    { CROSS_INCLUDE_DIRVAR, "GCC", 0, 0, 0, 0 },
+ #endif
+ #ifdef TOOL_INCLUDE_DIR
+     /* Another place the target system's headers might be.  */
+-    { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0, 0 },
++    { TOOL_INCLUDE_DIRVAR, "BINUTILS", 0, 1, 0, 0 },
+ #endif
+ #ifdef NATIVE_SYSTEM_HEADER_DIR
+     /* /usr/include comes dead last.  */
+-    { NATIVE_SYSTEM_HEADER_DIR, NATIVE_SYSTEM_HEADER_COMPONENT, 0, 0, 1, 2 },
+-    { NATIVE_SYSTEM_HEADER_DIR, NATIVE_SYSTEM_HEADER_COMPONENT, 0, 0, 1, 0 },
++    { NATIVE_SYSTEM_HEADER_DIRVAR, NATIVE_SYSTEM_HEADER_COMPONENT, 0, 0, 1, 2 },
++    { NATIVE_SYSTEM_HEADER_DIRVAR, NATIVE_SYSTEM_HEADER_COMPONENT, 0, 0, 1, 0 },
+ #endif
+     { 0, 0, 0, 0, 0, 0 }
+   };
+diff --git a/gcc/cppdefault.h b/gcc/cppdefault.h
+index 30b6fed..2ef96b7 100644
+--- a/gcc/cppdefault.h
++++ b/gcc/cppdefault.h
+@@ -33,7 +33,8 @@
+ 
+ struct default_include
+ {
+-  const char *const fname;	/* The name of the directory.  */
++  const char *fname;     /* The name of the directory.  */
++
+   const char *const component;	/* The component containing the directory
+ 				   (see update_path in prefix.c) */
+   const char cplusplus;		/* Only look here if we're compiling C++.  */
diff --git a/recipes-devtools/gcc/gcc-4.9/0064-handle-target-sysroot-multilib.patch b/recipes-devtools/gcc/gcc-4.9/0064-handle-target-sysroot-multilib.patch
new file mode 100644
index 0000000..5356984
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0064-handle-target-sysroot-multilib.patch
@@ -0,0 +1,88 @@
+Search target sysroot gcc version specific dirs with multilib.
+
+We install the gcc libraries (such as crtbegin.p) into
+<sysroot><libdir>/<target-sys>/5.2.0/
+which is a default search path for GCC (aka multi_suffix in the 
+code below). <target-sys> is 'machine' in gcc's terminology. We use
+these directories so that multiple gcc versions could in theory 
+co-exist on target.
+
+We only want to build one gcc-cross-canadian per arch and have this work 
+for all multilibs. <target-sys> can be handled by mapping the multilib
+<target-sys> to the one used by gcc-cross-canadian, e.g. mips64-polkmllib32-linux 
+is symlinked to by mips64-poky-linux.
+
+The default gcc search path in the target sysroot for a "lib64" mutlilib is:
+
+<sysroot>/lib32/mips64-poky-linux/5.2.0/
+<sysroot>/lib32/../lib64/
+<sysroot>/usr/lib32/mips64-poky-linux/5.2.0/
+<sysroot>/usr/lib32/../lib64/
+<sysroot>/lib32/
+<sysroot>/usr/lib32/
+
+which means that the lib32 crtbegin.o will be found and the lib64 ones
+will not which leads to compiler failures.
+
+This patch injects a multilib version of that path first so the lib64
+binaries can be found first. With this change the search path becomes:
+
+<sysroot>/lib32/../lib64/mips64-poky-linux/5.2.0/
+<sysroot>/lib32/mips64-poky-linux/5.2.0/
+<sysroot>/lib32/../lib64/
+<sysroot>/usr/lib32/../lib64/mips64-poky-linux/5.2.0/
+<sysroot>/usr/lib32/mips64-poky-linux/5.2.0/
+<sysroot>/usr/lib32/../lib64/
+<sysroot>/lib32/
+<sysroot>/usr/lib32/
+
+Upstream-Status: Pending
+RP 2015/7/31
+
+Index: gcc-5.2.0/gcc/gcc.c
+===================================================================
+--- gcc-5.2.0.orig/gcc/gcc.c
++++ gcc-5.2.0/gcc/gcc.c
+@@ -2305,7 +2305,7 @@ for_each_path (const struct path_prefix
+       if (path == NULL)
+ 	{
+ 	  len = paths->max_len + extra_space + 1;
+-	  len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len);
++	  len += MAX ((suffix_len + multi_os_dir_len), multiarch_len);
+ 	  path = XNEWVEC (char, len);
+ 	}
+ 
+@@ -2317,6 +2317,33 @@ for_each_path (const struct path_prefix
+ 	  /* Look first in MACHINE/VERSION subdirectory.  */
+ 	  if (!skip_multi_dir)
+ 	    {
++	      if (!(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
++	        {
++	          const char *this_multi;
++	          size_t this_multi_len;
++
++	          if (pl->os_multilib)
++		    {
++		      this_multi = multi_os_dir;
++		      this_multi_len = multi_os_dir_len;
++		    }
++	          else
++		    {
++		      this_multi = multi_dir;
++		      this_multi_len = multi_dir_len;
++		    }
++
++	          /* Look in multilib MACHINE/VERSION subdirectory first */
++	          if (this_multi_len)
++	            {
++		      memcpy (path + len, this_multi, this_multi_len + 1);
++	              memcpy (path + len + this_multi_len, multi_suffix, suffix_len + 1);
++	              ret = callback (path, callback_info);
++	                if (ret)
++		          break;
++	            }
++	        }
++
+ 	      memcpy (path + len, multi_suffix, suffix_len + 1);
+ 	      ret = callback (path, callback_info);
+ 	      if (ret)
diff --git a/recipes-devtools/gcc/gcc-4.9/0065-gcc-483-universal-initializer-no-warning.patch b/recipes-devtools/gcc/gcc-4.9/0065-gcc-483-universal-initializer-no-warning.patch
new file mode 100644
index 0000000..fde227b
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/0065-gcc-483-universal-initializer-no-warning.patch
@@ -0,0 +1,107 @@
+Upstream-Status: Backport
+
+Signed-off-by: Kai Kang <kai.kang@windriver.com>
+---
+Fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
+wrong warning when using the universal zero initializer {0}
+
+Backported to GCC 4.8.3
+
+Subject: 2014-06-05  S. Gilles  <sgilles@terpmail.umd.edu>
+X-Git-Url: http://repo.or.cz/w/official-gcc.git/commitdiff_plain/95cdf3fdf2d440eb7775def8e35ab970651c33d9?hp=14a3093e9943937cbc63dfbf4d51ca60f8325b29
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@211289 138bc75d-0d04-0410-961f-82ee72b054a4
+
+--- gcc-4.8.3.org/gcc/c/c-typeck.c	2014-08-03 20:52:09.257042137 +0200
++++ gcc-4.8.3/gcc/c/c-typeck.c	2014-08-03 20:57:10.645042614 +0200
+@@ -62,9 +62,9 @@
+    if expr.original_code == SIZEOF_EXPR.  */
+ tree c_last_sizeof_arg;
+ 
+-/* Nonzero if we've already printed a "missing braces around initializer"
+-   message within this initializer.  */
+-static int missing_braces_mentioned;
++/* Nonzero if we might need to print a "missing braces around
++   initializer" message within this initializer.  */
++static int found_missing_braces;
+ 
+ static int require_constant_value;
+ static int require_constant_elements;
+@@ -6379,6 +6379,9 @@
+ /* 1 if this constructor is erroneous so far.  */
+ static int constructor_erroneous;
+ 
++/* 1 if this constructor is the universal zero initializer { 0 }.  */
++static int constructor_zeroinit;
++
+ /* Structure for managing pending initializer elements, organized as an
+    AVL tree.  */
+ 
+@@ -6540,7 +6543,7 @@
+   constructor_stack = 0;
+   constructor_range_stack = 0;
+ 
+-  missing_braces_mentioned = 0;
++  found_missing_braces = 0;
+ 
+   spelling_base = 0;
+   spelling_size = 0;
+@@ -6635,6 +6638,7 @@
+   constructor_type = type;
+   constructor_incremental = 1;
+   constructor_designated = 0;
++  constructor_zeroinit = 1;
+   designator_depth = 0;
+   designator_erroneous = 0;
+ 
+@@ -6832,11 +6836,8 @@
+ 	set_nonincremental_init (braced_init_obstack);
+     }
+ 
+-  if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
+-    {
+-      missing_braces_mentioned = 1;
+-      warning_init (OPT_Wmissing_braces, "missing braces around initializer");
+-    }
++  if (implicit == 1)
++    found_missing_braces = 1;
+ 
+   if (TREE_CODE (constructor_type) == RECORD_TYPE
+ 	   || TREE_CODE (constructor_type) == UNION_TYPE)
+@@ -6969,16 +6970,23 @@
+ 	}
+     }
+ 
++  if (vec_safe_length (constructor_elements) != 1)
++    constructor_zeroinit = 0;
++
++  /* Warn when some structs are initialized with direct aggregation.  */
++  if (!implicit && found_missing_braces && warn_missing_braces
++      && !constructor_zeroinit)
++    {
++      warning_init (OPT_Wmissing_braces,
++		    "missing braces around initializer");
++    }
++
+   /* Warn when some struct elements are implicitly initialized to zero.  */
+   if (warn_missing_field_initializers
+       && constructor_type
+       && TREE_CODE (constructor_type) == RECORD_TYPE
+       && constructor_unfilled_fields)
+     {
+-	bool constructor_zeroinit =
+-	 (vec_safe_length (constructor_elements) == 1
+-	  && integer_zerop ((*constructor_elements)[0].value));
+-
+ 	/* Do not warn for flexible array members or zero-length arrays.  */
+ 	while (constructor_unfilled_fields
+ 	       && (!DECL_SIZE (constructor_unfilled_fields)
+@@ -8093,6 +8101,9 @@
+   designator_depth = 0;
+   designator_erroneous = 0;
+ 
++  if (!implicit && value.value && !integer_zerop (value.value))
++    constructor_zeroinit = 0;
++
+   /* Handle superfluous braces around string cst as in
+      char x[] = {"foo"}; */
+   if (string_flag
diff --git a/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0019-64-bit-multilib-hack.patch b/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0019-64-bit-multilib-hack.patch
new file mode 100644
index 0000000..2a0f718
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0019-64-bit-multilib-hack.patch
@@ -0,0 +1,65 @@
+From 18fde5740b09324dfb9cf41e9849672573ff5fa0 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 29 Mar 2013 09:10:06 +0400
+Subject: [PATCH 19/35] 64-bit multilib hack.
+
+GCC has internal multilib handling code but it assumes a very specific rigid directory
+layout. The build system implementation of multilib layout is very generic and allows
+complete customisation of the library directories.
+
+This patch is a partial solution to allow any custom directories to be passed into gcc
+and handled correctly. It forces gcc to use the base_libdir (which is the current
+directory, "."). We need to do this for each multilib that is configured as we don't
+know which compiler options may be being passed into the compiler. Since we have a compiler
+per mulitlib at this point that isn't an issue.
+
+The one problem is the target compiler is only going to work for the default multlilib at
+this point. Ideally we'd figure out which multilibs were being enabled with which paths
+and be able to patch these entries with a complete set of correct paths but this we
+don't have such code at this point. This is something the target gcc recipe should do
+and override these platform defaults in its build config.
+
+RP 15/8/11
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Signed-off-by: Elvis Dowson <elvis.dowson@gmail.com>
+
+Upstream-Status: Pending
+---
+ gcc/config/i386/t-linux64   |    6 ++----
+ gcc/config/mips/t-linux64   |   10 +++-------
+ gcc/config/rs6000/t-linux64 |    5 ++---
+ 3 files changed, 7 insertions(+), 14 deletions(-)
+
+Index: gcc-4.9-20140316/gcc/config/i386/t-linux64
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/config/i386/t-linux64
++++ gcc-4.9-20140316/gcc/config/i386/t-linux64
+@@ -32,7 +32,5 @@
+ #
+ comma=,
+ MULTILIB_OPTIONS    = $(subst $(comma),/,$(TM_MULTILIB_CONFIG))
+-MULTILIB_DIRNAMES   = $(patsubst m%, %, $(subst /, ,$(MULTILIB_OPTIONS)))
+-MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-linux-gnu)
+-MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:i386-linux-gnu)
+-MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-linux-gnux32)
++MULTILIB_DIRNAMES = . .
++MULTILIB_OSDIRNAMES = ../$(shell basename $(base_libdir)) ../$(shell basename $(base_libdir))
+Index: gcc-4.9-20140316/gcc/config/mips/t-linux64
+===================================================================
+--- gcc-4.9-20140316.orig/gcc/config/mips/t-linux64
++++ gcc-4.9-20140316/gcc/config/mips/t-linux64
+@@ -17,10 +17,6 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ MULTILIB_OPTIONS = mabi=n32/mabi=32/mabi=64
+-MULTILIB_DIRNAMES = n32 32 64
+-MIPS_EL = $(if $(filter %el, $(firstword $(subst -, ,$(target)))),el)
+-MIPS_SOFT = $(if $(strip $(filter MASK_SOFT_FLOAT_ABI, $(target_cpu_default)) $(filter soft, $(with_float))),soft)
+-MULTILIB_OSDIRNAMES = \
+-	../lib32$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \
+-	../lib$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \
+-	../lib64$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT))
++MULTILIB_DIRNAMES = . . .
++MULTILIB_OSDIRNAMES = ../$(shell basename $(base_libdir)) ../$(shell basename $(base_libdir)) ../$(shell basename $(base_libdir))
++
diff --git a/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch b/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch
new file mode 100644
index 0000000..c48a106
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch
@@ -0,0 +1,43 @@
+From 9e0e19eac2562f73858602fe26e2044eb8b20c47 Mon Sep 17 00:00:00 2001
+From: Alexandru-Cezar Sardan <alexandru.sardan@freescale.com>
+Date: Wed, 5 Feb 2014 16:52:31 +0200
+Subject: [PATCH] Enable SPE & AltiVec generation on powepc*linux target
+
+When is configured with --target=powerpc-linux, the resulting GCC will 
+not be able to generate code for SPE targets (e500v1/v2).
+GCC configured with --target=powerpc-linuxspe will not be able to
+generate AltiVec instructions (for e6500).
+This patch modifies the configured file such that SPE or AltiVec code
+can be generated when gcc is configured with --target=powerpc-linux.
+The ABI and speciffic instructions can be selected through the
+"-mabi=spe or -mabi=altivec" and the "-mspe or -maltivec" parameters.
+
+Upstream-Status: Inappropriate [configuration]
+
+Signed-off-by: Alexandru-Cezar Sardan <alexandru.sardan@freescale.com>
+---
+ gcc/config.gcc |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/config.gcc b/gcc/config.gcc
+index 945b5a3..4322874 100644
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -2290,7 +2290,12 @@ powerpc-*-rtems*)
+ 	tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-rtems rs6000/t-ppccomm"
+ 	;;
+ powerpc*-*-linux*)
+-	tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h rs6000/fsl-linux.h"
++	case ${target} in
++           powerpc*-*-linux*spe* | powerpc*-*-linux*altivec*)
++               tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h" ;;
++           *)
++               tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h rs6000/linuxaltivec.h rs6000/linuxspe.h rs6000/e500.h" ;;
++        esac
+ 	extra_options="${extra_options} rs6000/sysv4.opt"
+ 	tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+ 	extra_objs="$extra_objs rs6000-linux.o"
+        tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-rtems rs6000/t-ppccomm"
+-- 
+1.7.9.5
+
diff --git a/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0066-cxxflags-for-build.patch b/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0066-cxxflags-for-build.patch
new file mode 100644
index 0000000..212c13f
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.9/qoriq-ppc/0066-cxxflags-for-build.patch
@@ -0,0 +1,126 @@
+Fix various _FOR_BUILD and related variables
+
+When doing a FOR_BUILD thing, you have to override CFLAGS with
+CFLAGS_FOR_BUILD. And if you use C++, you also have to override
+CXXFLAGS with CXXFLAGS_FOR_BUILD.
+Without this, when building for mingw, you end up trying to use
+the mingw headers for a host build.
+
+The same goes for other variables as well, such as CPPFLAGS,
+CPP, and GMPINC.
+
+Upstream-Status: Pending
+
+Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
+Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
+
+diff --git a/Makefile.in b/Makefile.in
+index bf06dce..bf2ab41 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -149,8 +149,10 @@ BUILD_EXPORTS = \
+ 	AR="$(AR_FOR_BUILD)"; export AR; \
+ 	AS="$(AS_FOR_BUILD)"; export AS; \
+ 	CC="$(CC_FOR_BUILD)"; export CC; \
++	CPP="$(CC_FOR_BUILD) -E"; export CPP; \
+ 	CFLAGS="$(CFLAGS_FOR_BUILD)"; export CFLAGS; \
+ 	CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
++	CPPFLAGS="$(CPPFLAGS_FOR_BUILD)"; export CPPFLAGS; \
+ 	CXX="$(CXX_FOR_BUILD)"; export CXX; \
+ 	CXXFLAGS="$(CXXFLAGS_FOR_BUILD)"; export CXXFLAGS; \
+ 	GCJ="$(GCJ_FOR_BUILD)"; export GCJ; \
+@@ -169,6 +171,9 @@ BUILD_EXPORTS = \
+ # built for the build system to override those in BASE_FLAGS_TO_PASS.
+ EXTRA_BUILD_FLAGS = \
+ 	CFLAGS="$(CFLAGS_FOR_BUILD)" \
++	CXXFLAGS="$(CXXFLAGS_FOR_BUILD)" \
++	CPP="$(CC_FOR_BUILD) -E" \
++	CPPFLAGS="$(CPPFLAGS_FOR_BUILD)" \
+ 	LDFLAGS="$(LDFLAGS_FOR_BUILD)"
+ 
+ # This is the list of directories to built for the host system.
+@@ -186,6 +191,7 @@ HOST_SUBDIR = @host_subdir@
+ HOST_EXPORTS = \
+ 	$(BASE_EXPORTS) \
+ 	CC="$(CC)"; export CC; \
++	CPP="$(CC) -E"; export CPP; \
+ 	ADA_CFLAGS="$(ADA_CFLAGS)"; export ADA_CFLAGS; \
+ 	CFLAGS="$(CFLAGS)"; export CFLAGS; \
+ 	CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+@@ -706,6 +712,7 @@ BASE_FLAGS_TO_PASS = \
+ 	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ 	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ 	"CXX_FOR_BUILD=$(CXX_FOR_BUILD)" \
++	"CXXFLAGS_FOR_BUILD=$(CXXFLAGS_FOR_BUILD)" \
+ 	"EXPECT=$(EXPECT)" \
+ 	"FLEX=$(FLEX)" \
+ 	"INSTALL=$(INSTALL)" \
+diff --git a/Makefile.tpl b/Makefile.tpl
+index 54a8dc3..b0214fa 100644
+--- a/Makefile.tpl
++++ b/Makefile.tpl
+@@ -154,6 +154,7 @@ BUILD_EXPORTS = \
+ 	CC="$(CC_FOR_BUILD)"; export CC; \
+ 	CFLAGS="$(CFLAGS_FOR_BUILD)"; export CFLAGS; \
+ 	CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
++	CPPFLAGS="$(CPPFLAGS_FOR_BUILD)"; export CPPFLAGS; \
+ 	CXX="$(CXX_FOR_BUILD)"; export CXX; \
+ 	CXXFLAGS="$(CXXFLAGS_FOR_BUILD)"; export CXXFLAGS; \
+ 	GCJ="$(GCJ_FOR_BUILD)"; export GCJ; \
+@@ -172,6 +173,9 @@ BUILD_EXPORTS = \
+ # built for the build system to override those in BASE_FLAGS_TO_PASS.
+ EXTRA_BUILD_FLAGS = \
+ 	CFLAGS="$(CFLAGS_FOR_BUILD)" \
++	CXXFLAGS="$(CXXFLAGS_FOR_BUILD)" \
++	CPP="$(CC_FOR_BUILD) -E" \
++	CPPFLAGS="$(CPPFLAGS_FOR_BUILD)" \
+ 	LDFLAGS="$(LDFLAGS_FOR_BUILD)"
+ 
+ # This is the list of directories to built for the host system.
+@@ -189,6 +193,7 @@ HOST_SUBDIR = @host_subdir@
+ HOST_EXPORTS = \
+ 	$(BASE_EXPORTS) \
+ 	CC="$(CC)"; export CC; \
++	CPP="$(CC) -E"; export CPP; \
+ 	ADA_CFLAGS="$(ADA_CFLAGS)"; export ADA_CFLAGS; \
+ 	CFLAGS="$(CFLAGS)"; export CFLAGS; \
+ 	CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+diff --git a/gcc/Makefile.in b/gcc/Makefile.in
+index 5bb4d74..0ed7d13 100644
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -762,7 +762,7 @@ BUILD_LINKERFLAGS = $(BUILD_CXXFLAGS)
+ # Native linker and preprocessor flags.  For x-fragment overrides.
+ BUILD_LDFLAGS=@BUILD_LDFLAGS@
+ BUILD_CPPFLAGS= -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
+-		-I$(srcdir)/../include @INCINTL@ $(CPPINC) $(CPPFLAGS)
++		-I$(srcdir)/../include @INCINTL@ $(CPPINC) $(CPPFLAGS_FOR_BUILD)
+ 
+ # Actual name to use when installing a native compiler.
+ GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)')
+diff --git a/gcc/configure b/gcc/configure
+index 9f5431f..80be44f 100755
+--- a/gcc/configure
++++ b/gcc/configure
+@@ -11306,7 +11306,7 @@ else
+ 	CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
+ 	CXX="${CXX_FOR_BUILD}" CXXFLAGS="${CXXFLAGS_FOR_BUILD}" \
+ 	LD="${LD_FOR_BUILD}" LDFLAGS="${LDFLAGS_FOR_BUILD}" \
+-	GMPINC="" CPPFLAGS="${CPPFLAGS} -DGENERATOR_FILE" \
++	GMPINC="" CPPFLAGS="${CPPFLAGS_FOR_BUILD} -DGENERATOR_FILE" \
+ 	${realsrcdir}/configure --with-gnu-ld --with-gnu-as --enable-targets=all \
+ 		--enable-languages=${enable_languages-all} \
+ 		--target=$target_alias --host=$build_alias --build=$build_alias
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index e3a824c..c88e1af 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -1539,7 +1539,7 @@ else
+ 	CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
+ 	CXX="${CXX_FOR_BUILD}" CXXFLAGS="${CXXFLAGS_FOR_BUILD}" \
+ 	LD="${LD_FOR_BUILD}" LDFLAGS="${LDFLAGS_FOR_BUILD}" \
+-	GMPINC="" CPPFLAGS="${CPPFLAGS} -DGENERATOR_FILE" \
++	GMPINC="" CPPFLAGS="${CPPFLAGS_FOR_BUILD} -DGENERATOR_FILE" \
+ 	${realsrcdir}/configure \
+ 		--enable-languages=${enable_languages-all} \
+ 		--target=$target_alias --host=$build_alias --build=$build_alias
diff --git a/recipes-devtools/gcc/gcc-configure-common.inc b/recipes-devtools/gcc/gcc-configure-common.inc
new file mode 100644
index 0000000..cee6f4a
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-configure-common.inc
@@ -0,0 +1,129 @@
+require gcc-multilib-config.inc
+require gcc-shared-source.inc
+#
+# Build the list of lanaguages to build.
+#
+# These can be overridden by the version specific .inc file.
+
+# Java (gcj doesn't work on all architectures)
+JAVA ?= ",java"
+JAVA_arm ?= ""
+JAVA_armeb ?= ""
+JAVA_mipsel ?= ""
+JAVA_sh3 ?= ""
+# gcc 3.x expects 'f77', 4.0 expects 'f95', 4.1 and 4.2 expect 'fortran'
+FORTRAN ?= ",f77"
+LANGUAGES ?= "c,c++${FORTRAN}${JAVA}"
+# disable --enable-target-optspace for powerpc SPE
+# at -Os libgcc.so.1 creates references into
+# hidden symbols in libgcc.a which linker complains
+# when linking shared libraries further in the build like (gnutls)
+
+SPECIAL_ARCH_LIST = "powerpc"
+OPTSPACE = '${@bb.utils.contains("SPECIAL_ARCH_LIST", "${TARGET_ARCH}", "", "--enable-target-optspace",d)}'
+
+EXTRA_OECONF_BASE ?= ""
+EXTRA_OECONF_PATHS ?= ""
+EXTRA_OECONF_INITIAL ?= ""
+
+GCCMULTILIB ?= "--disable-multilib"
+GCCTHREADS ?= "posix"
+
+EXTRA_OECONF = "\
+    ${@['--enable-clocale=generic', ''][d.getVar('USE_NLS', True) != 'no']} \
+    --with-gnu-ld \
+    --enable-shared \
+    --enable-languages=${LANGUAGES} \
+    --enable-threads=${GCCTHREADS} \
+    ${GCCMULTILIB} \
+    --enable-c99 \
+    --enable-long-long \
+    --enable-symvers=gnu \
+    --enable-libstdcxx-pch \
+    --program-prefix=${TARGET_PREFIX} \
+    --without-local-prefix \
+    ${OPTSPACE} \
+    ${EXTRA_OECONF_BASE} \
+    ${EXTRA_OECONF_GCC_FLOAT} \
+    ${EXTRA_OECONF_PATHS} \
+    ${@get_gcc_mips_plt_setting(bb, d)} \
+    ${@get_gcc_ppc_plt_settings(bb, d)} \
+    ${@get_long_double_setting(bb, d)} \
+    ${@get_gcc_multiarch_setting(bb, d)} \
+"
+
+export gcc_cv_collect2_libs = 'none required'
+# We need to set gcc_cv_collect2_libs else there is cross-compilation badness
+# in the config.log files (which might not get generated until do_compile
+# hence being missed by the insane do_configure check).
+
+# Build uclibc compilers without cxa_atexit support
+EXTRA_OECONF_append_linux = " --enable-__cxa_atexit"
+EXTRA_OECONF_append_libc-uclibc = " --enable-__cxa_atexit"
+
+EXTRA_OECONF_append_mips64 = " --with-abi=64 --with-arch-64=mips64 --with-tune-64=mips64"
+EXTRA_OECONF_append_mips64el = " --with-abi=64 --with-arch-64=mips64 --with-tune-64=mips64"
+EXTRA_OECONF_append_mips64n32 = " --with-abi=64 --with-arch-64=mips64 --with-tune-64=mips64"
+EXTRA_OECONF_append_mips64eln32 = " --with-abi=64 --with-arch-64=mips64 --with-tune-64=mips64"
+
+# ARMv6+ adds atomic instructions that affect the ABI in libraries built
+# with TUNE_CCARGS in gcc-runtime.  Make the compiler default to a
+# compatible architecture.  armv6 and armv7a cover the minimum tune
+# features used in OE.
+EXTRA_OECONF_append_armv6 = " --with-arch=armv6"
+EXTRA_OECONF_append_armv7a = " --with-arch=armv7-a"
+
+EXTRA_OECONF_GCC_FLOAT ??= ""
+CPPFLAGS = ""
+
+SYSTEMHEADERS = "${target_includedir}"
+SYSTEMLIBS = "${target_base_libdir}/"
+SYSTEMLIBS1 = "${target_libdir}/"
+
+do_configure_prepend () {
+	# teach gcc to find correct target includedir when checking libc ssp support
+	mkdir -p ${B}/gcc
+	echo "NATIVE_SYSTEM_HEADER_DIR = ${SYSTEMHEADERS}" > ${B}/gcc/t-oe
+	cat ${S}/gcc/defaults.h | grep -v "\#endif.*GCC_DEFAULTS_H" > ${B}/gcc/defaults.h.new
+	cat >>${B}/gcc/defaults.h.new <<_EOF
+#define NATIVE_SYSTEM_HEADER_DIR "${SYSTEMHEADERS}"
+#define STANDARD_STARTFILE_PREFIX_1 "${SYSTEMLIBS}"
+#define STANDARD_STARTFILE_PREFIX_2 "${SYSTEMLIBS1}"
+#define SYSTEMLIBS_DIR "${SYSTEMLIBS}"
+#endif /* ! GCC_DEFAULTS_H */
+_EOF
+	mv ${B}/gcc/defaults.h.new ${B}/gcc/defaults.h
+}
+
+do_configure () {
+	# Setup these vars for cross building only
+	# ... because foo_FOR_TARGET apparently gets misinterpreted inside the
+	# gcc build stuff when the build is producing a cross compiler - i.e.
+	# when the 'current' target is the 'host' system, and the host is not
+	# the target (because the build is actually making a cross compiler!)
+	if [ "${BUILD_SYS}" != "${HOST_SYS}" ]; then
+		export CC_FOR_TARGET="${CC}"
+		export GCC_FOR_TARGET="${CC}"
+		export CXX_FOR_TARGET="${CXX}"
+		export AS_FOR_TARGET="${HOST_PREFIX}as"
+		export LD_FOR_TARGET="${HOST_PREFIX}ld"
+		export NM_FOR_TARGET="${HOST_PREFIX}nm"
+		export AR_FOR_TARGET="${HOST_PREFIX}ar"
+		export GFORTRAN_FOR_TARGET="gfortran"
+		export RANLIB_FOR_TARGET="${HOST_PREFIX}ranlib"
+	fi
+	export CC_FOR_BUILD="${BUILD_CC}"
+	export CXX_FOR_BUILD="${BUILD_CXX}"
+	export CFLAGS_FOR_BUILD="${BUILD_CFLAGS}"
+	export CPPFLAGS_FOR_BUILD="${BUILD_CPPFLAGS}"
+	export CXXFLAGS_FOR_BUILD="${BUILD_CXXFLAGS}"
+	export LDFLAGS_FOR_BUILD="${BUILD_LDFLAGS}"
+	export CFLAGS_FOR_TARGET="${TARGET_CFLAGS}"
+	export CPPFLAGS_FOR_TARGET="${TARGET_CPPFLAGS}"
+	export CXXFLAGS_FOR_TARGET="${TARGET_CXXFLAGS}"
+	export LDFLAGS_FOR_TARGET="${TARGET_LDFLAGS}"
+
+
+	oe_runconf
+}
+
diff --git a/recipes-devtools/gcc/gcc-cross-canadian.inc b/recipes-devtools/gcc/gcc-cross-canadian.inc
new file mode 100644
index 0000000..54e4881
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-canadian.inc
@@ -0,0 +1,177 @@
+inherit cross-canadian
+
+SUMMARY = "GNU cc and gcc C compilers (cross-canadian for ${TARGET_ARCH} target)"
+PN = "gcc-cross-canadian-${TRANSLATED_TARGET_ARCH}"
+
+DEPENDS = "virtual/${TARGET_PREFIX}gcc virtual/${HOST_PREFIX}binutils-crosssdk virtual/nativesdk-${HOST_PREFIX}libc-for-gcc nativesdk-gettext"
+
+GCCMULTILIB = "--enable-multilib"
+
+require gcc-configure-common.inc
+
+EXTRA_OECONF_PATHS = "\
+    --with-gxx-include-dir=/not/exist${target_includedir}/c++/${BINV} \
+    --with-build-time-tools=${STAGING_DIR_NATIVE}${prefix_native}/${TARGET_SYS}/bin \
+    --with-sysroot=/not/exist \
+    --with-build-sysroot=${STAGING_DIR_TARGET} \
+"
+# We have to point gcc at a sysroot but we don't need to rebuild if this changes
+# e.g. we switch between different machines with different tunes.
+EXTRA_OECONF_PATHS[vardepsexclude] = "TUNE_PKGARCH"
+TARGET_ARCH[vardepsexclude] = "TUNE_ARCH"
+get_gcc_float_setting[vardepvalue] = ""
+
+#
+# gcc-cross looks and finds these in ${exec_prefix} but we're not so lucky
+# for the sdk. Hardcoding the paths ensures the build doesn't go canadian or worse.
+#
+export AR_FOR_TARGET = "${TARGET_PREFIX}ar"
+export AS_FOR_TARGET = "${TARGET_PREFIX}as"
+export DLLTOOL_FOR_TARGET = "${TARGET_PREFIX}dlltool"
+export CC_FOR_TARGET = "${TARGET_PREFIX}gcc"
+export CXX_FOR_TARGET = "${TARGET_PREFIX}g++"
+export GCC_FOR_TARGET = "${TARGET_PREFIX}gcc"
+export LD_FOR_TARGET = "${TARGET_PREFIX}ld"
+export LIPO_FOR_TARGET = "${TARGET_PREFIX}lipo"
+export NM_FOR_TARGET = "${TARGET_PREFIX}nm"
+export OBJDUMP_FOR_TARGET = "${TARGET_PREFIX}objdump"
+export RANLIB_FOR_TARGET = "${TARGET_PREFIX}ranlib"
+export STRIP_FOR_TARGET = "${TARGET_PREFIX}strip"
+export WINDRES_FOR_TARGET = "${TARGET_PREFIX}windres"
+
+#
+# We need to override this and make sure the compiler can find staging
+#
+export ARCH_FLAGS_FOR_TARGET = "--sysroot=${STAGING_DIR_TARGET}"
+
+do_configure () {
+	export CC_FOR_BUILD="${BUILD_CC}"
+	export CXX_FOR_BUILD="${BUILD_CXX}"
+	export CFLAGS_FOR_BUILD="${BUILD_CFLAGS}"
+	export CPPFLAGS_FOR_BUILD="${BUILD_CPPFLAGS}"
+	export CXXFLAGS_FOR_BUILD="${BUILD_CXXFLAGS}"
+	export LDFLAGS_FOR_BUILD="${BUILD_LDFLAGS}"
+	export CFLAGS_FOR_TARGET="${TARGET_CFLAGS}"
+	export CPPFLAGS_FOR_TARGET="${TARGET_CPPFLAGS}"
+	export CXXFLAGS_FOR_TARGET="${TARGET_CXXFLAGS}"
+	export LDFLAGS_FOR_TARGET="${TARGET_LDFLAGS}"
+	oe_runconf
+}
+
+do_compile () {
+	oe_runmake all-host configure-target-libgcc
+}
+
+# Having anything auto depending on gcc-cross-sdk is a really bad idea...
+EXCLUDE_FROM_SHLIBS = "1"
+
+PACKAGES = "${PN}-dbg ${PN} ${PN}-doc"
+
+FILES_${PN} = "\
+    ${exec_prefix}/bin/* \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/* \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/*.o \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/specs \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/lib* \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/include \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/include-fixed \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/plugin/include/ \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/plugin/gtype.* \
+    ${includedir}/c++/${BINV} \
+    ${prefix}/${TARGET_SYS}/bin/* \
+    ${prefix}/${TARGET_SYS}/lib/* \
+    ${prefix}/${TARGET_SYS}/usr/include/* \
+"
+INSANE_SKIP_${PN} += "dev-so"
+
+FILES_${PN}-dbg += " \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/.debug \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/plugin/.debug \
+"
+
+FILES_${PN}-doc = "\
+    ${infodir} \
+    ${mandir} \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/include/README \
+"
+
+EXEEXT = ""
+
+# Compute how to get from libexecdir to bindir in python (easier than shell)
+BINRELPATH = "${@os.path.relpath(d.expand("${bindir}"), d.expand("${libexecdir}/gcc/${TARGET_SYS}/${BINV}"))}"
+
+do_install () {
+	( cd ${B}/${TARGET_SYS}/libgcc; oe_runmake 'DESTDIR=${D}' install-unwind_h )
+	oe_runmake 'DESTDIR=${D}' install-host
+
+	# Cleanup some of the ${libdir}{,exec}/gcc stuff ...
+	rm -r ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/install-tools
+	rm -r ${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/install-tools
+	rm -rf ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/finclude
+
+	# We care about g++ not c++
+	rm -f ${D}${bindir}/*c++
+
+	# We don't care about the gcc-<version> copies
+	rm -f ${D}${bindir}/*gcc-?.?*
+
+	# We use libiberty from binutils
+	rm -f ${D}${prefix}/${TARGET_SYS}/lib/libiberty.a
+	# Not sure where the strange paths come from
+	rm -f ${D}${libdir}/../lib/libiberty.a
+	rm -f ${D}${libdir}/libiberty.a
+
+	# Cleanup empty directories which are not shipped
+	# we use rmdir instead of 'rm -f' to ensure the non empty directories are not deleted
+	# ${D}${libdir}/../lib only seems to appear with SDKMACHINE=i686
+	local empty_dirs="${D}${libdir}/../lib ${D}${prefix}/${TARGET_SYS}/lib ${D}${prefix}/${TARGET_SYS} ${D}${includedir}"
+	for i in $empty_dirs; do
+		[ -d $i ] && rmdir --ignore-fail-on-non-empty $i
+	done
+
+	# Insert symlinks into libexec so when tools without a prefix are searched for, the correct ones are
+	# found.
+	dest=${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/
+	install -d $dest
+	suffix=${EXEEXT}
+	for t in ar as ld nm objcopy objdump ranlib strip g77 gcc cpp gfortran; do
+		if [ "$t" = "g77" -o "$t" = "gfortran" ] && [ ! -e ${D}${bindir}/${TARGET_PREFIX}$t$suffix ]; then
+			continue
+		fi
+
+		ln -sf ${BINRELPATH}/${TARGET_PREFIX}$t$suffix $dest$t$suffix
+	done
+	t=real-ld
+	ln -sf ${BINRELPATH}/${TARGET_PREFIX}ld$suffix $dest$t$suffix
+
+	# libquadmath headers need to  be available in the gcc libexec dir
+	install -d ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include/
+	cp ${S}/libquadmath/quadmath.h ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include/
+	cp ${S}/libquadmath/quadmath_weak.h ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include/
+
+	chown -R root:root ${D}
+	
+	cross_canadian_bindirlinks
+}
+
+ELFUTILS = "nativesdk-elfutils"
+DEPENDS += "nativesdk-gmp nativesdk-mpfr nativesdk-libmpc ${ELFUTILS} nativesdk-zlib"
+RDEPENDS_${PN} += "nativesdk-mpfr nativesdk-libmpc ${ELFUTILS}"
+
+SYSTEMHEADERS = "/usr/include"
+SYSTEMLIBS = "${target_base_libdir}/"
+SYSTEMLIBS1 = "${target_libdir}/"
+
+EXTRA_OECONF += "--enable-poison-system-directories"
+
+EXTRA_OECONF += "\
+    --with-mpfr=${STAGING_DIR_HOST}${layout_exec_prefix} \
+    --with-mpc=${STAGING_DIR_HOST}${layout_exec_prefix} \
+"
+
+EXTRA_OECONF_append_libc-baremetal = " --without-headers"
+EXTRA_OECONF_remove_libc-baremetal = "--with-sysroot=/not/exist"
+EXTRA_OECONF_remove_libc-baremetal = "--with-build-sysroot=${STAGING_DIR_TARGET}"
+
+# gcc 4.7 needs -isystem
+export ARCH_FLAGS_FOR_TARGET = "--sysroot=${STAGING_DIR_TARGET} -isystem=${target_includedir}"
diff --git a/recipes-devtools/gcc/gcc-cross-canadian_4.9.bb b/recipes-devtools/gcc/gcc-cross-canadian_4.9.bb
new file mode 100644
index 0000000..1bd198a
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-canadian_4.9.bb
@@ -0,0 +1,5 @@
+require gcc-${PV}.inc
+require gcc-cross-canadian.inc
+
+
+
diff --git a/recipes-devtools/gcc/gcc-cross-canadian_4.9.bbappend b/recipes-devtools/gcc/gcc-cross-canadian_4.9.bbappend
new file mode 100644
index 0000000..c2e52f7
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-canadian_4.9.bbappend
@@ -0,0 +1,11 @@
+require gcc-fsl.inc
+
+DEPENDS_append_qoriq-ppc = " nativesdk-isl nativesdk-cloog"
+RDEPENDS_${PN}_append_qoriq-ppc = " nativesdk-isl nativesdk-cloog"
+
+EXTRA_OECONF_append_qoriq-ppc = " --with-isl=${STAGING_DIR_HOST}${SDKPATHNATIVE}${prefix_nativesdk} \
+                 --with-cloog=${STAGING_DIR_HOST}${SDKPATHNATIVE}${prefix_nativesdk} \
+"
+
+INSANE_SKIP_${PN} += "libdir file-rdeps build-deps"
+INSANE_SKIP_${PN}-dbg += "libdir"
diff --git a/recipes-devtools/gcc/gcc-cross-initial.inc b/recipes-devtools/gcc/gcc-cross-initial.inc
new file mode 100644
index 0000000..892b1db
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-initial.inc
@@ -0,0 +1,89 @@
+DEPENDS = "virtual/${TARGET_PREFIX}binutils ${NATIVEDEPS}"
+PROVIDES = "virtual/${TARGET_PREFIX}gcc-initial"
+PACKAGES = ""
+
+INHIBIT_AUTOTOOLS_DEPS = "1"
+INHIBIT_DEFAULT_DEPS = "1"
+
+# We still need gnu-config-native
+DEPENDS_prepend = "gnu-config-native autoconf-native "
+
+PN = "gcc-cross-initial-${TARGET_ARCH}"
+
+CROSS_TARGET_SYS_DIR_append = ".${PN}"
+
+# This is intended to be a -very- basic config
+# sysroot is needed in case we use libc-initial
+EXTRA_OECONF = "\
+    --with-newlib \
+    --without-headers \
+    --disable-shared \
+    --disable-threads \
+    --disable-multilib \
+    --disable-__cxa_atexit \
+    --enable-languages=c \
+    --program-prefix=${TARGET_PREFIX} \
+    --with-sysroot=/not/exist \
+    --with-build-sysroot=${STAGING_DIR_TARGET} \
+    ${EXTRA_OECONF_INITIAL} \
+    ${@bb.utils.contains('DISTRO_FEATURES', 'ld-is-gold', '--with-ld=${STAGING_BINDIR_TOOLCHAIN}/${TARGET_PREFIX}ld.bfd', '', d)} \
+    ${EXTRA_OECONF_GCC_FLOAT} \
+    ${@get_gcc_ppc_plt_settings(bb, d)} \
+"
+
+EXTRA_OECONF += "--with-native-system-header-dir=${SYSTEMHEADERS}"
+
+do_compile () {
+    oe_runmake all-gcc configure-target-libgcc
+    (cd ${B}/${TARGET_SYS}/libgcc; oe_runmake enable-execute-stack.c unwind.h md-unwind-support.h sfp-machine.h gthr-default.h)
+}
+
+do_install () {
+	( cd ${B}/${TARGET_SYS}/libgcc; oe_runmake 'DESTDIR=${D}' install-unwind_h-forbuild install-unwind_h)
+	oe_runmake 'DESTDIR=${D}' install-gcc
+
+	# We don't really need this (here shares/ contains man/, info/, locale/).
+	rm -rf ${D}${datadir}/
+
+	# We use libiberty from binutils
+	find ${D}${exec_prefix}/lib -name libiberty.a | xargs rm -f
+	find ${D}${exec_prefix}/lib -name libiberty.h | xargs rm -f
+
+	# Insert symlinks into libexec so when tools without a prefix are searched for, the correct ones are
+	# found. These need to be relative paths so they work in different locations.
+	dest=${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/
+	install -d $dest
+	useld=${@bb.utils.contains('DISTRO_FEATURES', 'ld-is-gold', '.bfd', '', d)}
+	ln -sf ${BINRELPATH}/${TARGET_PREFIX}ld${useld} ${dest}ld
+	for t in ar as nm objcopy objdump ranlib strip g77 gcc cpp gfortran; do
+		ln -sf ${BINRELPATH}/${TARGET_PREFIX}$t $dest$t
+	done
+	# fixed limits.h infact includes the so called real limits.h
+	# which should come from libc but when we build libc-initial
+	# then bunch of configure tests include fixed limits.h which in turn
+	# includes real limits.h but this real limits.h is not staged yet
+	# so we overwirte the generated include-fixed/limits.h for gcc-cross-initial
+	# to get rid references to real limits.h
+	cp gcc/include-fixed/limits.h ${D}${gcclibdir}/${TARGET_SYS}/${BINV}/include/limits.h
+}
+#
+# Override the default sysroot staging copy since this won't look like a target system
+#
+sysroot_stage_all() {
+	sysroot_stage_dir ${D} ${SYSROOT_DESTDIR}
+	install -d ${SYSROOT_DESTDIR}${STAGING_DIR_TARGET}${target_base_libdir}/
+	install -d ${SYSROOT_DESTDIR}${STAGING_DIR_TARGET}${target_libdir}/
+	mv ${SYSROOT_DESTDIR}${target_base_libdir}/* ${SYSROOT_DESTDIR}${STAGING_DIR_TARGET}${target_base_libdir}/ || true
+	mv ${SYSROOT_DESTDIR}${target_libdir}/* ${SYSROOT_DESTDIR}${STAGING_DIR_TARGET}${target_libdir}/ || true
+}
+
+do_populate_sysroot[sstate-inputdirs] = "${SYSROOT_DESTDIR}/${STAGING_DIR_HOST}/"
+do_populate_sysroot[sstate-outputdirs] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/${PN}"
+
+inherit nopackages
+
+COMPILERINITIAL = "-initial"
+
+
+# We really only want this built by things that need it, not any recrdeptask
+deltask do_build
diff --git a/recipes-devtools/gcc/gcc-cross-initial_4.9.bb b/recipes-devtools/gcc/gcc-cross-initial_4.9.bb
new file mode 100644
index 0000000..1639511
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-initial_4.9.bb
@@ -0,0 +1,2 @@
+require gcc-cross_${PV}.bb
+require gcc-cross-initial.inc
diff --git a/recipes-devtools/gcc/gcc-cross-initial_4.9.bbappend b/recipes-devtools/gcc/gcc-cross-initial_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross-initial_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/gcc-cross.inc b/recipes-devtools/gcc/gcc-cross.inc
new file mode 100644
index 0000000..a6df45e
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross.inc
@@ -0,0 +1,216 @@
+inherit cross
+
+INHIBIT_DEFAULT_DEPS = "1"
+EXTRADEPENDS = ""
+DEPENDS = "virtual/${TARGET_PREFIX}binutils virtual/${TARGET_PREFIX}libc-for-gcc ${EXTRADEPENDS} ${NATIVEDEPS}"
+PROVIDES = "virtual/${TARGET_PREFIX}gcc virtual/${TARGET_PREFIX}g++"
+python () {
+    if d.getVar("TARGET_OS").startswith("linux"):
+        d.setVar("EXTRADEPENDS", "linux-libc-headers")
+}
+
+PN = "gcc-cross-${TARGET_ARCH}"
+
+# Ignore how TARGET_ARCH is computed.
+TARGET_ARCH[vardepvalue] = "${TARGET_ARCH}"
+
+require recipes-devtools/gcc/gcc-configure-common.inc
+
+# While we want the 'gnu' hash style, we explicitly set it to sysv here to
+# ensure that any recipe which doesn't obey our LDFLAGS (which also set it to
+# gnu) will hit a QA failure.
+LINKER_HASH_STYLE ?= "sysv"
+
+EXTRA_OECONF += "--enable-poison-system-directories"
+EXTRA_OECONF_append_sh4 = " \
+    --with-multilib-list= \
+    --enable-incomplete-targets \
+"
+
+EXTRA_OECONF += "\
+    --with-mpfr=${STAGING_DIR_NATIVE}${prefix_native} \
+    --with-system-zlib \
+"
+
+DEPENDS_remove_libc-baremetal := "virtual/${TARGET_PREFIX}libc-for-gcc"
+EXTRA_OECONF_append_libc-baremetal = " --without-headers"
+EXTRA_OECONF_remove_libc-baremetal = "--enable-threads=posix"
+
+EXTRA_OECONF_PATHS = "\
+    --with-gxx-include-dir=/not/exist${target_includedir}/c++/${BINV} \
+    --with-sysroot=/not/exist \
+    --with-build-sysroot=${STAGING_DIR_TARGET} \
+"
+
+ARCH_FLAGS_FOR_TARGET += "-isystem${STAGING_DIR_TARGET}${target_includedir}"
+
+do_compile () {
+	export CC="${BUILD_CC}"
+	export AR_FOR_TARGET="${TARGET_SYS}-ar"
+	export RANLIB_FOR_TARGET="${TARGET_SYS}-ranlib"
+	export LD_FOR_TARGET="${TARGET_SYS}-ld"
+	export NM_FOR_TARGET="${TARGET_SYS}-nm"
+	export CC_FOR_TARGET="${CCACHE} ${TARGET_SYS}-gcc"
+	export CFLAGS_FOR_TARGET="${TARGET_CFLAGS}"
+	export CPPFLAGS_FOR_TARGET="${TARGET_CPPFLAGS}"
+	export CXXFLAGS_FOR_TARGET="${TARGET_CXXFLAGS}"
+	export LDFLAGS_FOR_TARGET="${TARGET_LDFLAGS}"
+
+	oe_runmake all-host configure-target-libgcc
+	(cd ${B}/${TARGET_SYS}/libgcc; oe_runmake enable-execute-stack.c unwind.h md-unwind-support.h sfp-machine.h gthr-default.h)
+	# now generate script to drive testing
+	echo "#!/usr/bin/env sh" >${B}/${TARGET_PREFIX}testgcc
+	set >> ${B}/${TARGET_PREFIX}testgcc
+	# prune out the unneeded vars
+	sed -i -e "/^BASH/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^USER/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^OPT/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^DIRSTACK/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^EUID/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^FUNCNAME/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^GROUPS/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^HOST/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^HOME/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^IFS/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^LC_ALL/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^LOGNAME/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^MACHTYPE/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^OSTYPE/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^PIPE/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^SHELL/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^'/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^UID/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^TERM/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^PKG_/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^POSIXLY_/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^PPID/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^PS4/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^Q/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^SHLVL/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^STAGING/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^LD_LIBRARY_PATH/d" ${B}/${TARGET_PREFIX}testgcc
+	sed -i -e "/^PSEUDO/d" ${B}/${TARGET_PREFIX}testgcc
+
+	# append execution part of the script
+cat >> ${B}/${TARGET_PREFIX}testgcc << STOP
+target="\$1"
+usage () {
+	echo "Usage:"
+	echo "\$0 user@target 'extra options to dejagnu'"
+	echo "\$0 target 'extra options to dejagnu'"
+	echo "\$0 target"
+	echo "e.g. \$0 192.168.7.2 ' dg.exp=visibility-d.c'"
+	echo "will only run visibility-d.c test case"
+	echo "e.g. \$0 192.168.7.2 '/-mthumb dg.exp=visibility-d.c'"
+	echo "will only run visibility-d.c test case in thumb mode"
+	echo "You need to have dejagnu autogen expect installed"
+	echo "on the build host"
+    }
+if [ "x\$target" = "x" ]
+then
+	echo "Please specify the target machine and remote user in form of user@target\n"
+	usage
+	exit 1;
+fi
+
+shift
+
+echo "\$target" | grep "@" 2>&1 > /dev/null
+if [ "x\$?" = "x0" ]
+then
+   user=\$(echo \$target | cut -d '@' -f 1)
+   target=\$(echo \$target | cut -d '@' -f 2)
+else
+   user=\$USER
+fi
+ssh \$user@\$target date 2>&1 > /dev/null
+if [ "x\$?" != "x0" ]
+then
+	echo "Failed connecting to \$user@\$target it could be because"
+	echo "you don't have passwordless ssh setup to access \$target"
+	echo "or sometimes host key has been changed"
+	echo "in such case do something like below on build host"
+	echo "ssh-keygen -f "~/.ssh/known_hosts" -R \$target"
+	echo "and then try ssh \$user@\$target"
+
+	usage
+	exit 1
+fi
+	echo "lappend boards_dir [pwd]/../../.." > ${B}/site.exp
+	echo "load_generic_config \"unix\"" > ${B}/${PACKAGE_ARCH}.exp
+	echo "set_board_info username \$user" >> ${B}/${PACKAGE_ARCH}.exp
+	echo "set_board_info rsh_prog ssh" >> ${B}/${PACKAGE_ARCH}.exp
+	echo "set_board_info rcp_prog scp" >> ${B}/${PACKAGE_ARCH}.exp
+	echo "set_board_info hostname \$target" >> ${B}/${PACKAGE_ARCH}.exp
+	DEJAGNU=${B}/site.exp make -k check RUNTESTFLAGS="--target_board=${PACKAGE_ARCH}\$@"
+
+STOP
+
+	chmod +x ${B}/${TARGET_PREFIX}testgcc
+
+}
+
+INHIBIT_PACKAGE_STRIP = "1"
+
+# Compute how to get from libexecdir to bindir in python (easier than shell)
+BINRELPATH = "${@os.path.relpath(d.expand("${STAGING_DIR_NATIVE}${prefix_native}/bin/${TARGET_SYS}"), d.expand("${libexecdir}/gcc/${TARGET_SYS}/${BINV}"))}"
+
+do_install () {
+	( cd ${B}/${TARGET_SYS}/libgcc; oe_runmake 'DESTDIR=${D}' install-unwind_h-forbuild install-unwind_h )
+	oe_runmake 'DESTDIR=${D}' install-host
+
+	install -d ${D}${target_base_libdir}
+	install -d ${D}${target_libdir}
+    
+	# Link gfortran to g77 to satisfy not-so-smart configure or hard coded g77
+	# gfortran is fully backwards compatible. This is a safe and practical solution. 
+	ln -sf ${STAGING_DIR_NATIVE}${prefix_native}/bin/${TARGET_PREFIX}gfortran ${STAGING_DIR_NATIVE}${prefix_native}/bin/${TARGET_PREFIX}g77 || true
+
+	
+	# Insert symlinks into libexec so when tools without a prefix are searched for, the correct ones are
+	# found. These need to be relative paths so they work in different locations.
+	dest=${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/
+	install -d $dest
+	for t in ar as ld nm objcopy objdump ranlib strip g77 gcc cpp gfortran; do
+		ln -sf ${BINRELPATH}/${TARGET_PREFIX}$t $dest$t
+		ln -sf ${BINRELPATH}/${TARGET_PREFIX}$t ${dest}${TARGET_PREFIX}$t
+	done
+
+	# Remove things we don't need but keep share/java
+	for d in info man share/doc share/locale share/man share/info; do
+		rm -rf ${D}${STAGING_DIR_NATIVE}${prefix_native}/$d
+	done
+
+	# libquadmath headers need to  be available in the gcc libexec dir
+	install -d ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include/
+	cp ${S}/libquadmath/quadmath.h ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include/
+	cp ${S}/libquadmath/quadmath_weak.h ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include/
+
+	# We use libiberty from binutils
+	find ${D}${exec_prefix}/lib -name libiberty.a | xargs rm -f
+	find ${D}${exec_prefix}/lib -name libiberty.h | xargs rm -f
+}
+
+do_package[noexec] = "1"
+do_packagedata[noexec] = "1"
+do_package_write_ipk[noexec] = "1"
+do_package_write_rpm[noexec] = "1"
+do_package_write_deb[noexec] = "1"
+
+BUILDDIRSTASH = "${WORKDIR}/stashed-builddir"
+do_gcc_stash_builddir[dirs] = "${B}"
+do_gcc_stash_builddir[cleandirs] = "${BUILDDIRSTASH}"
+do_gcc_stash_builddir () {
+	dest=${BUILDDIRSTASH}
+	hardlinkdir . $dest
+}
+addtask do_gcc_stash_builddir after do_compile before do_install
+SSTATETASKS += "do_gcc_stash_builddir"
+do_gcc_stash_builddir[sstate-inputdirs] = "${BUILDDIRSTASH}"
+do_gcc_stash_builddir[sstate-outputdirs] = "${COMPONENTS_DIR}/${BUILD_ARCH}/gcc-stashed-builddir${COMPILERINITIAL}-${TARGET_SYS}"
+do_gcc_stash_builddir[sstate-fixmedir] = "${COMPONENTS_DIR}/${BUILD_ARCH}/gcc-stashed-builddir${COMPILERINITIAL}-${TARGET_SYS}"
+
+python do_gcc_stash_builddir_setscene () {
+    sstate_setscene(d)
+}
+addtask do_gcc_stash_builddir_setscene
diff --git a/recipes-devtools/gcc/gcc-cross_4.9.bb b/recipes-devtools/gcc/gcc-cross_4.9.bb
new file mode 100644
index 0000000..0a8aa75
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross_4.9.bb
@@ -0,0 +1,3 @@
+require recipes-devtools/gcc/gcc-${PV}.inc
+require recipes-devtools/gcc/gcc-cross.inc
+
diff --git a/recipes-devtools/gcc/gcc-cross_4.9.bbappend b/recipes-devtools/gcc/gcc-cross_4.9.bbappend
new file mode 100644
index 0000000..ef22c73
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-cross_4.9.bbappend
@@ -0,0 +1,5 @@
+require gcc-fsl.inc
+
+EXTRA_OECONF_PATHS_append_qoriq-ppc = " --with-isl=${STAGING_DIR_NATIVE}${prefix_native} \
+                       --with-cloog=${STAGING_DIR_NATIVE}${prefix_native} \
+"
diff --git a/recipes-devtools/gcc/gcc-crosssdk-initial.inc b/recipes-devtools/gcc/gcc-crosssdk-initial.inc
new file mode 100644
index 0000000..08eda5d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk-initial.inc
@@ -0,0 +1,10 @@
+inherit crosssdk
+
+PN = "gcc-crosssdk-initial-${SDK_SYS}"
+
+SYSTEMHEADERS = "${SDKPATHNATIVE}${prefix_nativesdk}/include"
+SYSTEMLIBS = "${SDKPATHNATIVE}${base_libdir_nativesdk}/"
+SYSTEMLIBS1 = "${SDKPATHNATIVE}${libdir_nativesdk}/"
+
+DEPENDS = "virtual/${TARGET_PREFIX}binutils-crosssdk gettext-native ${NATIVEDEPS}"
+PROVIDES = "virtual/${TARGET_PREFIX}gcc-initial-crosssdk"
diff --git a/recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bb b/recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bb
new file mode 100644
index 0000000..ba62885
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bb
@@ -0,0 +1,3 @@
+require gcc-cross-initial_${PV}.bb
+require gcc-crosssdk-initial.inc
+
diff --git a/recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bbappend b/recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk-initial_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/gcc-crosssdk.inc b/recipes-devtools/gcc/gcc-crosssdk.inc
new file mode 100644
index 0000000..cda2927
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk.inc
@@ -0,0 +1,12 @@
+inherit crosssdk
+
+PN = "gcc-crosssdk-${SDK_SYS}"
+
+SYSTEMHEADERS = "${SDKPATHNATIVE}${prefix_nativesdk}/include"
+SYSTEMLIBS = "${SDKPATHNATIVE}${base_libdir_nativesdk}/"
+SYSTEMLIBS1 = "${SDKPATHNATIVE}${libdir_nativesdk}/"
+
+GCCMULTILIB = "--disable-multilib"
+
+DEPENDS = "virtual/${TARGET_PREFIX}binutils-crosssdk virtual/nativesdk-${TARGET_PREFIX}libc-for-gcc gettext-native ${NATIVEDEPS}"
+PROVIDES = "virtual/${TARGET_PREFIX}gcc-crosssdk virtual/${TARGET_PREFIX}g++-crosssdk"
diff --git a/recipes-devtools/gcc/gcc-crosssdk_4.9.bb b/recipes-devtools/gcc/gcc-crosssdk_4.9.bb
new file mode 100644
index 0000000..7430888
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk_4.9.bb
@@ -0,0 +1,2 @@
+require gcc-cross_${PV}.bb
+require gcc-crosssdk.inc
diff --git a/recipes-devtools/gcc/gcc-crosssdk_4.9.bbappend b/recipes-devtools/gcc/gcc-crosssdk_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-crosssdk_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/gcc-fsl.inc b/recipes-devtools/gcc/gcc-fsl.inc
new file mode 100644
index 0000000..0b9c2e4
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-fsl.inc
@@ -0,0 +1,70 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/gcc-4.9:"
+
+NATIVEDEPS_append_qoriq-ppc = " cloog-native"
+EXTRA_OECONF_BASE_remove_qoriq-ppc = "--with-cloog=no"
+
+PV = "4.9.2"
+
+# BINV should be incremented to a revision after a minor gcc release
+BINV = "4.9.2"
+
+SRC_URI_qoriq-ppc = "\
+    ${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.bz2 \
+    file://0001.gcc.e6500-FSF-49x.patch \
+    file://0002.gcc.builtin_isel-49x.patch \
+    file://0003.gcc.widen_types-49x.patch \
+    file://0004.gcc.extelim-v4-49x.patch \
+    file://0005.gcc.extelim_vrp_kugan-v1-49x.patch \
+    file://0006.gcc.opt-array-offset-49x.patch \
+    file://0007.gcc.aeabi-49x.patch \
+    file://0008.gcc.fix_regalloc_for_482.patch \
+    file://0009.gcc.rm_slow_tests-47.patch \
+    file://0010.gcc.fix_mingw32.patch \
+    file://0011.gcc.no_power_builtins-48.patch \
+    file://0012.gcc.ld_unaligned-460.patch \
+    file://0013.gcc.local_unaligned_altivec.patch \
+    file://0014.gcc.soft_float-470.patch \
+    file://0015.gcc.case_values-48.patch \
+    file://0016.gcc.fix_pr63854_pass_manager.patch \
+    file://0017.gcc.builtin_isel_doc.patch \
+    file://0018.gcc.experimental_move.patch \
+    file://0019.gcc.e5500_mfocr.patch \
+    file://0020.gcc.load_on_store_bypass-48x.patch \
+    file://0021.gcc.fix_constvector.patch \
+    file://0022.gcc.fix_pr63908_unwind_info.patch \
+    file://0023.gcc.fix_pr60158_fixup_table.patch \
+    file://0024.gcc.have-pre-modify-disp-support-49x.patch \
+    file://0025.gcc.fix_ENGR00298583_dwarf-vector-reg_49x.patch \
+    file://0026.gcc.fix_MTWX51605-memset-array-init_48.patch \
+    file://0027.gcc.fix_altivec_constant_alignment-v2.patch \
+    file://0028.gcc.fix_altivec_reload_gs8.patch \
+    file://0029.gcc.fix_postfix_gimplifier.patch \
+    file://0030.gcc.fix_adjust_address_cost.patch \
+    file://0031.gcc.fix_adjust_sched_loopinv_cost.patch \
+    file://0032.gcc.fix_e5500_mulli_pipeline.patch \
+    file://0033.gcc.fix_e500mc_addi_pipeline.patch \
+    file://0034.gcc.fix_ENGR00292364_debug_frame.patch \
+    file://0035.gcc.fix_ENGR00215936_49x.patch \
+    file://0036.gcc.enable_soft_multilib-49x.patch \
+    file://0037.gcc.fix_49x-doc.patch \
+    file://0038.gcc.fix_emulation_spec_48.patch \
+    file://0039.gcc.create_maeabi.patch \
+    file://0040.gcc.rm_e500v2_loops_48.patch \
+    file://0041.gcc.fix_e5500-e6500-aeabi-multi-lib.patch \
+    file://0042.gcc.fix_ivopts.patch \
+    file://0043.gcc.sysroot_spec_only_linux.patch \
+    file://0019-64-bit-multilib-hack.patch \
+    file://0020-optional-libstdc.patch \
+    file://0023-Use-the-defaults.h-in-B-instead-of-S-and-t-oe-in-B.patch \
+    file://0029-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch \
+    file://0032-libtool.patch \
+    file://0034-Use-the-multilib-config-files-from-B-instead-of-usin.patch \
+    file://0040-fix-g++-sysroot.patch \
+    file://0041-libtool-avoid-libdir.patch \
+    file://0046-libatomic-deptracking.patch \
+    file://0049-Enable-SPE-AltiVec-generation-on-powepc-linux-target.patch \
+    file://0054-gcc-Makefile.in-fix-parallel-building-failure.patch \
+    file://0066-cxxflags-for-build.patch \
+"
+SRC_URI[md5sum] = "4df8ee253b7f3863ad0b86359cd39c43"
+SRC_URI[sha256sum] = "2020c98295856aa13fda0f2f3a4794490757fc24bcca918d52cc8b4917b972dd"
diff --git a/recipes-devtools/gcc/gcc-multilib-config.inc b/recipes-devtools/gcc/gcc-multilib-config.inc
new file mode 100644
index 0000000..1c0a45a
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-multilib-config.inc
@@ -0,0 +1,228 @@
+# following code modifies these definitions in the gcc config
+#    MULTILIB_OPTIONS
+#    MULTILIB_DIRNAMES
+#    MULTILIB_OSDIRNAMES
+#    GLIBC_DYNAMIC_LINKER32
+#    GLIBC_DYNAMIC_LINKER64
+#    GLIBC_DYNAMIC_LINKERX32
+#    GLIBC_DYNAMIC_LINKERN32
+#  For more information on use of these variables look at these files in the gcc source code
+#    gcc/config/i386/t-linux64
+#    gcc/config/mips/t-linux64
+#    gcc/config/rs6000/t-linux64
+#    gcc/config/i386/linux64.h
+#    gcc/config/mips/linux64.h
+#    gcc/config/rs6000/linux64.h
+
+MULTILIB_OPTION_WHITELIST ??= "-m32 -m64 -mx32 -mabi=n32 -mabi=32 -mabi=64" 
+
+python gcc_multilib_setup() {
+    import re
+    import shutil
+    import glob
+
+    srcdir = d.getVar('S', True)
+    builddir = d.getVar('B', True)
+    src_conf_dir = '%s/gcc/config' % srcdir
+    build_conf_dir = '%s/gcc/config' % builddir
+
+    bb.utils.remove(build_conf_dir, True)
+    ml_globs = ('%s/*/t-linux64' % src_conf_dir,
+                '%s/*/linux64.h' % src_conf_dir,
+                '%s/*/linux.h' % src_conf_dir,
+                '%s/linux.h' % src_conf_dir)
+
+    # copy the target multilib config files to ${B}
+    for ml_glob in ml_globs:
+        for fn in glob.glob(ml_glob):
+            rel_path = os.path.relpath(fn, src_conf_dir)
+            parent_dir = os.path.dirname(rel_path)
+            bb.utils.mkdirhier('%s/%s' % (build_conf_dir, parent_dir))
+            bb.utils.copyfile(fn, '%s/%s' % (build_conf_dir, rel_path))
+
+    pn = d.getVar('PN', True)
+    multilibs = (d.getVar('MULTILIB_VARIANTS', True) or '').split()
+    if not multilibs and pn != "nativesdk-gcc":
+        return
+
+    mlprefix = d.getVar('MLPREFIX', True)
+
+    if ('%sgcc' % mlprefix) != pn and (not pn.startswith('gcc-cross-canadian')) and pn != "nativesdk-gcc":
+        return
+
+
+    def write_config(root, files, options, dirnames, osdirnames):
+        for ml_conf_file in files:
+            with open(root + '/' + ml_conf_file, 'r') as f:
+                filelines = f.readlines()
+                # recreate multilib configuration variables
+                substs = [
+                    (r'^(\s*(MULTILIB_OPTIONS\s*=).*)$', r'\2 %s' % '/'.join(options)),
+                    (r'^(\s*MULTILIB_OPTIONS\s*\+=.*)$', ''),
+                    (r'^(\s*(MULTILIB_DIRNAMES\s*=).*)$', r'\2 %s' % ' '.join(dirnames)),
+                    (r'^(\s*MULTILIB_DIRNAMES\s*\+=.*)$', ''),
+                    (r'^(\s*(MULTILIB_OSDIRNAMES\s*=).*)$', r'\2 %s' % ' '.join(osdirnames)),
+                    (r'^(\s*MULTILIB_OSDIRNAMES\s*\+=.*)$', ''),
+                ]
+
+                for (i, line) in enumerate(filelines):
+                    for subst in substs:
+                        line = re.sub(subst[0], subst[1], line)
+                    filelines[i] = line
+
+                with open(root + '/' + ml_conf_file, 'w') as f:
+                    f.write(''.join(filelines))
+
+    def write_headers(root, files, libdir32, libdir64, libdirx32, libdirn32):
+        def wrap_libdir(libdir):
+            if libdir.find('SYSTEMLIBS_DIR') != -1:
+                return '"%r"'
+            else:
+                return '"/%s/"' % libdir
+
+        for ml_conf_file in files:
+            fn = root + '/' + ml_conf_file
+            if not os.path.exists(fn):
+                continue
+            with open(fn, 'r') as f:
+                filelines = f.readlines()
+
+                # replace lines like
+                # #define GLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld-linux.so.2"
+                # by
+                # #define GLIBC_DYNAMIC_LINKER32 "/lib/" "ld-linux.so.2"
+                # this is needed to put the correct dynamic loader path in the generated binaries
+                substs = [
+                    (r'^(#define\s*GLIBC_DYNAMIC_LINKER32\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdir32) + r'\3'),
+                    (r'^(#define\s*GLIBC_DYNAMIC_LINKER64\s*)(\S+)(\s*\"\S+\")$',
+                        r'\1' + wrap_libdir(libdir64) + r'\3'),
+                    (r'^(#define\s*GLIBC_DYNAMIC_LINKER64\s*\"\S+\"\s*)(\S+)(\s*\"\S+\"\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdir64) + r'\3' + wrap_libdir(libdir64) + r'\5'),
+                    (r'^(#define\s*GLIBC_DYNAMIC_LINKERX32\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdirx32) + r'\3'),
+                    (r'^(#define\s*GLIBC_DYNAMIC_LINKERN32\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdirn32) + r'\3'),
+                    (r'^(#define\s*UCLIBC_DYNAMIC_LINKER32\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdir32) + r'\3'),
+                    (r'^(#define\s*UCLIBC_DYNAMIC_LINKER64\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdir64) + r'\3'),
+                    (r'^(#define\s*UCLIBC_DYNAMIC_LINKERN32\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdirn32) + r'\3'),
+                    (r'^(#define\s*UCLIBC_DYNAMIC_LINKER\b\s*)(\S+)(\s*\".*\")$',
+                        r'\1' + wrap_libdir(libdir32) + r'\3'),
+                ]
+
+                for (i, line) in enumerate(filelines):
+                    for subst in substs:
+                        line = re.sub(subst[0], subst[1], line)
+                    filelines[i] = line
+
+                with open(root + '/' + ml_conf_file, 'w') as f:
+                    f.write(''.join(filelines))
+
+
+    gcc_target_config_files = {
+        'x86_64'    : ['gcc/config/i386/t-linux64'],
+        'i586'      : ['gcc/config/i386/t-linux64'],
+        'i686'      : ['gcc/config/i386/t-linux64'],
+        'mips'      : ['gcc/config/mips/t-linux64'],
+        'mips64'    : ['gcc/config/mips/t-linux64'],
+        'powerpc'   : ['gcc/config/rs6000/t-linux64'],
+        'powerpc64' : ['gcc/config/rs6000/t-linux64'],
+    }
+
+    gcc_header_config_files = {
+        'x86_64'    : ['gcc/config/i386/linux64.h'],
+        'i586'      : ['gcc/config/i386/linux64.h'],
+        'i686'      : ['gcc/config/i386/linux64.h'],
+        'mips'      : ['gcc/config/mips/linux.h', 'gcc/config/mips/linux64.h'],
+        'mips64'    : ['gcc/config/mips/linux.h', 'gcc/config/mips/linux64.h'],
+        'powerpc'   : ['gcc/config/rs6000/linux64.h'],
+        'powerpc64' : ['gcc/config/rs6000/linux64.h'],
+    }
+
+    libdir32 = 'SYSTEMLIBS_DIR'
+    libdir64 = 'SYSTEMLIBS_DIR'
+    libdirx32 = 'SYSTEMLIBS_DIR'
+    libdirn32 = 'SYSTEMLIBS_DIR'
+
+
+    target_arch = (d.getVar('TARGET_ARCH_MULTILIB_ORIGINAL', True) if mlprefix
+                    else d.getVar('TARGET_ARCH', True))
+    if pn == "nativesdk-gcc":
+        header_config_files = gcc_header_config_files[d.getVar("SDK_ARCH", True)]
+        write_headers(builddir, header_config_files, libdir32, libdir64, libdirx32, libdirn32)
+        return
+
+    if target_arch not in gcc_target_config_files:
+        bb.warn('gcc multilib setup is not supported for TARGET_ARCH=' + target_arch)
+        return
+
+    target_config_files = gcc_target_config_files[target_arch]
+    header_config_files = gcc_header_config_files[target_arch]
+
+    ml_list = ['DEFAULTTUNE_MULTILIB_ORIGINAL' if mlprefix else 'DEFAULTTUNE']
+    mltunes = [('DEFAULTTUNE_virtclass-multilib-%s' % ml) for ml in multilibs]
+    if mlprefix:
+        mlindex = 0
+        for ml in multilibs:
+            if mlprefix == ml + '-':
+                break
+            mlindex += 1
+
+        ml_list.extend(mltunes[:mlindex] + ['DEFAULTTUNE'] + mltunes[(mlindex + 1):])
+    else:
+        ml_list.extend(mltunes)
+
+    options = []
+    dirnames = []
+    osdirnames = []
+    optsets = []
+
+    for ml in ml_list:
+        tune = d.getVar(ml, True)
+        if not tune:
+            bb.warn("%s doesn't have a corresponding tune. Skipping..." % ml)
+            continue
+        tune_parameters = get_tune_parameters(tune, d)
+
+        tune_baselib = tune_parameters['baselib']
+        if not tune_baselib:
+            bb.warn("Tune %s doesn't have a baselib set. Skipping..." % tune)
+            continue
+
+        if tune_baselib == 'lib64':
+            libdir64 = tune_baselib
+        elif tune_baselib == 'libx32':
+            libdirx32 = tune_baselib
+        elif tune_baselib == 'lib32':
+            libdirn32 = tune_baselib
+        elif tune_baselib == 'lib':
+            libdir32 = tune_baselib
+        else:
+            bb.error('Unknown libdir (%s) of the tune : %s' % (tune_baselib, tune))
+
+        # take out '-' mcpu='s and march='s from parameters
+        opts = []
+        whitelist = (d.getVar("MULTILIB_OPTION_WHITELIST", True) or "").split()
+        for i in d.expand(tune_parameters['ccargs']).split():
+            if i in whitelist:
+                # Need to strip '-' from option
+                opts.append(i[1:])
+        options.append(" ".join(opts))
+
+        if tune_baselib == 'lib':
+            dirnames.append('32')  # /lib => 32bit lib
+        else:
+            dirnames.append(tune_baselib.replace('lib', ''))
+        osdirnames.append('../' + tune_baselib)
+
+    write_config(builddir, target_config_files, options, dirnames, osdirnames)
+    write_headers(builddir, header_config_files, libdir32, libdir64, libdirx32, libdirn32)
+}
+
+gcc_multilib_setup[cleandirs] = "${B}/gcc/config"
+gcc_multilib_setup[vardepsexclude] = "SDK_ARCH"
+
+EXTRACONFFUNCS += "gcc_multilib_setup"
diff --git a/recipes-devtools/gcc/gcc-runtime_4.9.bb b/recipes-devtools/gcc/gcc-runtime_4.9.bb
new file mode 100644
index 0000000..f91b4ea
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-runtime_4.9.bb
@@ -0,0 +1,3 @@
+require gcc-${PV}.inc
+require recipes-devtools/gcc/gcc-runtime.inc
+
diff --git a/recipes-devtools/gcc/gcc-runtime_4.9.bbappend b/recipes-devtools/gcc/gcc-runtime_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-runtime_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/gcc-sanitizers.inc b/recipes-devtools/gcc/gcc-sanitizers.inc
new file mode 100644
index 0000000..c987ccb
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-sanitizers.inc
@@ -0,0 +1,119 @@
+require gcc-configure-common.inc
+
+LICENSE = "NCSA | MIT"
+
+LIC_FILES_CHKSUM = "\
+    file://libsanitizer/LICENSE.TXT;md5=0249c37748936faf5b1efd5789587909 \
+"
+
+EXTRA_OECONF_PATHS = "\
+    --with-sysroot=/not/exist \
+    --with-build-sysroot=${STAGING_DIR_TARGET} \
+"
+
+do_configure () {
+    mtarget=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+    target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+    if [ -d ${STAGING_INCDIR_NATIVE}/gcc-build-internal-$mtarget ]; then
+        hardlinkdir ${STAGING_INCDIR_NATIVE}/gcc-build-internal-$mtarget ${B}
+    fi
+
+    echo "Configuring libsanitizer"
+    rm -rf ${B}/$target/libsanitizer/
+    mkdir -p ${B}/$target/libsanitizer/
+    # This is kind of gross, but it's an easy way to make configure happy
+    # without hacking it up to use the system stdc++ instead of the one it
+    # expects to be newly built.
+    rm -rf ${B}/$target/libstdc++-v3/
+    mkdir -p ${B}/$target/libstdc++-v3/src/
+    ln -s ${STAGING_LIBDIR}/libstdc++.la ${B}/$target/libstdc++-v3/src/
+    ln -s ${STAGING_LIBDIR}/libstdc++.so ${B}/$target/libstdc++-v3/src/
+    cd ${B}/$target/libsanitizer/
+    chmod a+x ${S}/libsanitizer/configure
+    ${S}/libsanitizer/configure ${CONFIGUREOPTS} ${EXTRA_OECONF}
+    # Easiest way to stop bad RPATHs getting into the library since we have a
+    # broken libtool here
+    sed -i -e 's/hardcode_into_libs=yes/hardcode_into_libs=no/' ${B}/$target/libsanitizer/libtool
+}
+
+do_compile () {
+    target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+    cd ${B}/$target/libsanitizer/
+    oe_runmake MULTIBUILDTOP=${B}/$target/libsanitizer/
+}
+
+do_install () {
+    target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+    cd ${B}/$target/libsanitizer/
+    oe_runmake 'DESTDIR=${D}' MULTIBUILDTOP=${B}/$target/libsanitizer/ install
+    if [ -d ${D}${infodir} ]; then
+        rmdir --ignore-fail-on-non-empty -p ${D}${infodir}
+    fi
+    chown -R root:root ${D}
+}
+
+INHIBIT_DEFAULT_DEPS = "1"
+ALLOW_EMPTY_${PN} = "1"
+DEPENDS = "gcc-runtime"
+
+BBCLASSEXTEND = "nativesdk"
+
+PACKAGES = "${PN}"
+PACKAGES += "libasan libubsan liblsan libtsan"
+PACKAGES += "libasan-dev libubsan-dev liblsan-dev libtsan-dev"
+PACKAGES += "libasan-dbg libubsan-dbg liblsan-dbg libtsan-dbg"
+PACKAGES += "libasan-staticdev libubsan-staticdev liblsan-staticdev libtsan-staticdev"
+
+RDEPENDS_libasan += "libstdc++"
+RDEPENDS_libubsan += "libstdc++"
+RDEPENDS_liblsan += "libstdc++"
+RDEPENDS_libtsan += "libstdc++"
+RDEPENDS_libasan-dev += "${PN}"
+RDEPENDS_libubsan-dev += "${PN}"
+RDEPENDS_liblsan-dev += "${PN}"
+RDEPENDS_libtsan-dev += "${PN}"
+RRECOMMENDS_${PN} += "libasan libubsan"
+RRECOMMENDS_${PN}_append_x86-64 = " liblsan libtsan"
+RRECOMMENDS_${PN}_append_x86 = " liblsan"
+
+do_package_write_ipk[depends] += "virtual/${MLPREFIX}${TARGET_PREFIX}compilerlibs:do_packagedata"
+do_package_write_deb[depends] += "virtual/${MLPREFIX}${TARGET_PREFIX}compilerlibs:do_packagedata"
+do_package_write_rpm[depends] += "virtual/${MLPREFIX}${TARGET_PREFIX}compilerlibs:do_packagedata"
+
+# MIPS, aarch64, and SPARC are broken.
+COMPATIBLE_HOST = '(x86_64|i.86|powerpc|arm).*-linux'
+
+FILES_libasan += "${libdir}/libasan.so.*"
+FILES_libasan-dbg += "${libdir}/.debug/libasan.so.*"
+FILES_libasan-dev += "\
+    ${libdir}/libasan_preinit.o \
+    ${libdir}/libasan.so \
+    ${libdir}/libasan.la \
+"
+FILES_libasan-staticdev += "${libdir}/libasan.a"
+
+FILES_libubsan += "${libdir}/libubsan.so.*"
+FILES_libubsan-dbg += "${libdir}/.debug/libubsan.so.*"
+FILES_libubsan-dev += "\
+    ${libdir}/libubsan.so \
+    ${libdir}/libubsan.la \
+"
+FILES_libubsan-staticdev += "${libdir}/libubsan.a"
+
+FILES_liblsan += "${libdir}/liblsan.so.*"
+FILES_liblsan-dbg += "${libdir}/.debug/liblsan.so.*"
+FILES_liblsan-dev += "\
+    ${libdir}/liblsan.so \
+    ${libdir}/liblsan.la \
+"
+FILES_liblsan-staticdev += "${libdir}/liblsan.a"
+
+FILES_libtsan += "${libdir}/libtsan.so.*"
+FILES_libtsan-dbg += "${libdir}/.debug/libtsan.so.*"
+FILES_libtsan-dev += "\
+    ${libdir}/libtsan.so \
+    ${libdir}/libtsan.la \
+"
+FILES_libtsan-staticdev += "${libdir}/libtsan.a"
+
+FILES_${PN} = "${libdir}/*.spec ${libdir}/gcc/${TARGET_SYS}/${BINV}/include/sanitizer/*.h"
diff --git a/recipes-devtools/gcc/gcc-sanitizers_4.9.bb b/recipes-devtools/gcc/gcc-sanitizers_4.9.bb
new file mode 100644
index 0000000..6daaf08
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-sanitizers_4.9.bb
@@ -0,0 +1,2 @@
+require gcc-${PV}.inc
+require gcc-sanitizers.inc
diff --git a/recipes-devtools/gcc/gcc-sanitizers_4.9.bbappend b/recipes-devtools/gcc/gcc-sanitizers_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-sanitizers_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/gcc-shared-source.inc b/recipes-devtools/gcc/gcc-shared-source.inc
new file mode 100644
index 0000000..aac4b49
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-shared-source.inc
@@ -0,0 +1,11 @@
+do_fetch() {
+	:
+}
+do_fetch[noexec] = "1"
+deltask do_unpack
+deltask do_patch
+
+SRC_URI = ""
+
+do_configure[depends] += "gcc-source-${PV}:do_preconfigure"
+do_populate_lic[depends] += "gcc-source-${PV}:do_unpack"
diff --git a/recipes-devtools/gcc/gcc-source.inc b/recipes-devtools/gcc/gcc-source.inc
new file mode 100644
index 0000000..794fd4d
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-source.inc
@@ -0,0 +1,36 @@
+deltask do_configure 
+deltask do_compile 
+deltask do_package 
+deltask do_package_write_rpm 
+deltask do_package_write_ipk 
+deltask do_package_write_deb
+deltask do_install 
+deltask do_populate_sysroot
+deltask do_populate_lic 
+deltask do_package_qa
+deltask do_packagedata
+deltask do_rm_work
+
+PN = "gcc-source-${PV}"
+WORKDIR = "${TMPDIR}/work-shared/gcc-${PV}-${PR}"
+SSTATE_SWSPEC = "sstate:gcc::${PV}:${PR}::${SSTATE_VERSION}:"
+
+STAMP = "${STAMPS_DIR}/work-shared/gcc-${PV}-${PR}"
+STAMPCLEAN = "${STAMPS_DIR}/work-shared/gcc-${PV}-*"
+
+INHIBIT_DEFAULT_DEPS = "1"
+DEPENDS = ""
+PACKAGES = ""
+
+python do_preconfigure () {
+    import subprocess
+    cmd = d.expand('cd ${S} && PATH=${PATH} gnu-configize')
+    subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
+    # See 0044-gengtypes.patch, we need to regenerate this file
+    bb.utils.remove(d.expand("${S}/gcc/gengtype-lex.c"))
+    cmd = d.expand("sed -i 's/BUILD_INFO=info/BUILD_INFO=/' ${S}/gcc/configure")
+    subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
+}
+addtask do_preconfigure after do_patch
+do_preconfigure[depends] += "gnu-config-native:do_populate_sysroot autoconf-native:do_populate_sysroot"
+
diff --git a/recipes-devtools/gcc/gcc-source_4.9.bb b/recipes-devtools/gcc/gcc-source_4.9.bb
new file mode 100644
index 0000000..0a1fc6f
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-source_4.9.bb
@@ -0,0 +1,4 @@
+require gcc-${PV}.inc
+require gcc-source.inc
+
+EXCLUDE_FROM_WORLD = "1"
diff --git a/recipes-devtools/gcc/gcc-source_4.9.bbappend b/recipes-devtools/gcc/gcc-source_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-source_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/gcc-target.inc b/recipes-devtools/gcc/gcc-target.inc
new file mode 100644
index 0000000..d62c15a
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-target.inc
@@ -0,0 +1,214 @@
+GCCMULTILIB = "--enable-multilib"
+require gcc-configure-common.inc
+
+EXTRA_OECONF_PATHS = "\
+    --with-sysroot=/ \
+    --with-build-sysroot=${STAGING_DIR_TARGET} \
+    --with-native-system-header-dir=${STAGING_DIR_TARGET}${target_includedir} \
+    --with-gxx-include-dir=${includedir}/c++/${BINV} \
+"
+
+EXTRA_OECONF_append_linuxstdbase = " --enable-clocale=gnu"
+
+# libcc1 requres gcc_cv_objdump when cross build, but gcc_cv_objdump is
+# set in subdir gcc, so subdir libcc1 can't use it, export it here to
+# fix the problem.
+export gcc_cv_objdump = "${TARGET_PREFIX}objdump"
+
+EXTRA_OECONF_GCC_FLOAT = "${@get_gcc_float_setting(bb, d)}"
+
+PACKAGES = "\
+    ${PN} ${PN}-plugins ${PN}-symlinks \
+    g++ g++-symlinks \
+    cpp cpp-symlinks \
+    g77 g77-symlinks \
+    gfortran gfortran-symlinks \
+    gcov gcov-symlinks \
+    ${PN}-doc \
+    ${PN}-dev \
+    ${PN}-dbg \
+"
+
+FILES_${PN} = "\
+    ${bindir}/${TARGET_PREFIX}gcc* \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/collect2* \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/cc* \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/lto* \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/lib*${SOLIBS} \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/liblto*${SOLIBSDEV} \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/*.o \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/specs \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/lib*${SOLIBS} \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/include \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/include-fixed \
+"
+INSANE_SKIP_${PN} += "dev-so"
+
+FILES_${PN}-dbg += "\
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/.debug/ \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/plugin/.debug/ \
+"
+FILES_${PN}-dev = "\
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/lib*${SOLIBSDEV} \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/lib*${SOLIBSDEV} \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/plugin/include/ \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/plugin/gengtype \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/plugin/gtype.state \
+"
+FILES_${PN}-symlinks = "\
+    ${bindir}/cc \
+    ${bindir}/gcc \
+    ${bindir}/gccbug \
+"
+
+FILES_${PN}-plugins = "\
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/plugin \
+"
+ALLOW_EMPTY_${PN}-plugins = "1"
+
+FILES_g77 = "\
+    ${bindir}/${TARGET_PREFIX}g77 \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/f771 \
+"
+FILES_g77-symlinks = "\
+    ${bindir}/g77 \
+    ${bindir}/f77 \
+"
+FILES_gfortran = "\
+    ${bindir}/${TARGET_PREFIX}gfortran \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/f951 \
+"
+FILES_gfortran-symlinks = "\
+    ${bindir}/gfortran \
+    ${bindir}/f95"
+
+FILES_cpp = "\
+    ${bindir}/${TARGET_PREFIX}cpp* \
+    ${base_libdir}/cpp \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/cc1"
+FILES_cpp-symlinks = "${bindir}/cpp"
+
+FILES_gcov = "${bindir}/${TARGET_PREFIX}gcov* \
+    ${bindir}/${TARGET_PREFIX}gcov-tool* \
+"
+FILES_gcov-symlinks = "${bindir}/gcov \
+    ${bindir}/gcov-tool \
+"
+
+FILES_g++ = "\
+    ${bindir}/${TARGET_PREFIX}g++* \
+    ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/cc1plus \
+"
+FILES_g++-symlinks = "\
+    ${bindir}/c++ \
+    ${bindir}/g++ \
+"
+
+FILES_${PN}-doc = "\
+    ${infodir} \
+    ${mandir} \
+    ${gcclibdir}/${TARGET_SYS}/${BINV}/include/README \
+"
+
+do_compile () {
+	oe_runmake all-host
+}
+
+do_install () {
+	oe_runmake 'DESTDIR=${D}' install-host
+
+	# Add unwind.h, it comes from libgcc which we don't want to build again
+	install ${STAGING_LIBDIR_NATIVE}/${TARGET_SYS}/gcc/${TARGET_SYS}/${BINV}/include/unwind.h ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include/
+
+	# Info dir listing isn't interesting at this point so remove it if it exists.
+	if [ -e "${D}${infodir}/dir" ]; then
+		rm -f ${D}${infodir}/dir
+	fi
+
+	# Cleanup some of the ${libdir}{,exec}/gcc stuff ...
+	rm -r ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/install-tools
+	rm -r ${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/install-tools
+	rm -rf ${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/*.la
+	rmdir ${D}${includedir}
+	rm -rf ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/finclude
+
+	# Hack around specs file assumptions
+	test -f ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/specs && sed -i -e '/^*cross_compile:$/ { n; s/1/0/; }' ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/specs
+
+	# Cleanup manpages..
+	rm -rf ${D}${mandir}/man7
+
+	cd ${D}${bindir}
+
+	# We care about g++ not c++
+	rm -f *c++*
+
+	# We don't care about the gcc-<version> ones for this
+	rm -f *gcc-?.?*
+
+	# We use libiberty from binutils
+	find ${D}${libdir} -name libiberty.a | xargs rm -f
+	find ${D}${libdir} -name libiberty.h | xargs rm -f
+
+	# Not sure why we end up with these but we don't want them...
+	rm -f ${TARGET_PREFIX}${TARGET_PREFIX}*
+
+	# Symlinks so we can use these trivially on the target
+	if [ -e ${TARGET_PREFIX}g77 ]; then
+		ln -sf ${TARGET_PREFIX}g77 g77 || true
+		ln -sf g77 f77 || true
+	fi
+	if [ -e ${TARGET_PREFIX}gfortran ]; then
+		ln -sf ${TARGET_PREFIX}gfortran gfortran || true
+		ln -sf gfortran f95 || true
+	fi
+	ln -sf ${TARGET_PREFIX}g++ g++
+	ln -sf ${TARGET_PREFIX}gcc gcc
+	ln -sf ${TARGET_PREFIX}cpp cpp
+	install -d ${D}${base_libdir}
+	ln -sf ${bindir}/${TARGET_PREFIX}cpp ${D}${base_libdir}/cpp
+	ln -sf g++ c++
+	ln -sf gcc cc
+
+	chown -R root:root ${D}
+}
+
+do_install_append () {
+        #
+        # Thefixinc.sh script, run on the gcc's compile phase, looks into sysroot header
+        # files and places the modified files into
+        # {D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include-fixed folder. This makes the
+        # build not deterministic. The following code prunes all those headers
+        # except those under include-fixed/linux, *limits.h and README, yielding
+        # the same include-fixed folders no matter what sysroot
+
+        include_fixed="${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/include-fixed"
+        for f in $(find ${include_fixed} -type f); do
+                case $f in
+                */include-fixed/linux/*)
+                    continue
+                    ;;
+                */include-fixed/*limits.h)
+                    continue
+                    ;;
+                */include-fixed/README)
+                    continue
+                    ;;
+                *)
+                    # remove file and directory if empty
+                    bbdebug 2 "Pruning $f"
+                    rm $f
+                    find $(dirname $f) -maxdepth 0 -empty -exec rmdir {} \;
+                    ;;
+                esac
+        done
+}
+
+# Installing /usr/lib/gcc/* means we'd have two copies, one from gcc-cross
+# and one from here. These can confuse gcc cross where includes use #include_next
+# and builds track file dependencies (e.g. perl and its makedepends code).
+# For determinism we don't install this ever and rely on the copy from gcc-cross.
+# [YOCTO #7287]
+sysroot_stage_dirs_append () {
+	rm -rf $to${libdir}/gcc
+}
diff --git a/recipes-devtools/gcc/gcc_4.9.bb b/recipes-devtools/gcc/gcc_4.9.bb
new file mode 100644
index 0000000..33654da
--- /dev/null
+++ b/recipes-devtools/gcc/gcc_4.9.bb
@@ -0,0 +1,13 @@
+require gcc-${PV}.inc
+require gcc-target.inc
+
+# http://errors.yoctoproject.org/Errors/Details/20497/
+ARM_INSTRUCTION_SET_armv4 = "arm"
+ARM_INSTRUCTION_SET_armv5 = "arm"
+
+BBCLASSEXTEND = "nativesdk"
+
+#SYSTEMHEADERS_class-nativesdk = "${@'${target_includedir}'.replace(d.getVar('SDKPATH', True),'%r')}"
+#SYSTEMLIBS_class-nativesdk = "${@'${target_base_libdir}'.replace(d.getVar('SDKPATH', True),'%r')}/"
+#SYSTEMLIBS1_class-nativesdk = "${@'${target_libdir}'.replace(d.getVar('SDKPATH', True),'%r')}/"
+
diff --git a/recipes-devtools/gcc/gcc_4.9.bbappend b/recipes-devtools/gcc/gcc_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/gcc_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/libgcc-common.inc b/recipes-devtools/gcc/libgcc-common.inc
new file mode 100644
index 0000000..b09ea65
--- /dev/null
+++ b/recipes-devtools/gcc/libgcc-common.inc
@@ -0,0 +1,144 @@
+BPN = "libgcc"
+
+require gcc-shared-source.inc
+
+INHIBIT_DEFAULT_DEPS = "1"
+
+do_configure () {
+	target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+	install -d ${D}${base_libdir} ${D}${libdir}
+	hardlinkdir ${STAGING_INCDIR_NATIVE}/${LIBGCCBUILDTREENAME}$target/ ${B}
+	mkdir -p ${B}/${BPN}
+	mkdir -p ${B}/$target/${BPN}/
+	cd ${B}/${BPN}
+	chmod a+x ${S}/${BPN}/configure
+	${S}/${BPN}/configure ${CONFIGUREOPTS} ${EXTRA_OECONF}
+}
+
+do_compile () {
+	target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+	cd ${B}/${BPN}
+	oe_runmake MULTIBUILDTOP=${B}/$target/${BPN}/
+}
+
+do_install () {
+	target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+	cd ${B}/${BPN}
+	oe_runmake 'DESTDIR=${D}' MULTIBUILDTOP=${B}/$target/${BPN}/ install
+
+	# Move libgcc_s into /lib
+	mkdir -p ${D}${base_libdir}
+	if [ -f ${D}${libdir}/nof/libgcc_s.so ]; then
+		mv ${D}${libdir}/nof/libgcc* ${D}${base_libdir}
+	else
+		mv ${D}${libdir}/libgcc* ${D}${base_libdir} || true
+	fi
+
+	# install the runtime in /usr/lib/ not in /usr/lib/gcc on target
+	# so that cross-gcc can find it in the sysroot
+
+	mv ${D}${libdir}/gcc/* ${D}${libdir}
+	rm -rf ${D}${libdir}/gcc/
+	# unwind.h is installed here which is shipped in gcc-cross
+	# as well as target gcc and they are identical so we dont
+	# ship one with libgcc here
+	rm -rf ${D}${libdir}/${TARGET_SYS}/${BINV}/include
+}
+
+do_install_append_libc-baremetal () {
+	rmdir ${D}${base_libdir}
+}
+
+RDEPENDS_${PN}-dev_libc-baremetal = ""
+
+BBCLASSEXTEND = "nativesdk"
+
+addtask multilib_install after do_install before do_package do_populate_sysroot
+# this makes multilib gcc files findable for target gcc
+# e.g.
+#    /usr/lib/i586-pokymllib32-linux/4.7/
+# by creating this symlink to it
+#    /usr/lib64/x86_64-poky-linux/4.7/32
+
+fakeroot python do_multilib_install() {
+    import re
+
+    multilibs = d.getVar('MULTILIB_VARIANTS', True)
+    if not multilibs or bb.data.inherits_class('nativesdk', d):
+        return
+
+    binv = d.getVar('BINV', True)
+
+    mlprefix = d.getVar('MLPREFIX', True)
+    if ('%slibgcc' % mlprefix) != d.getVar('PN', True):
+        return
+
+    if mlprefix:
+        orig_tune = d.getVar('DEFAULTTUNE_MULTILIB_ORIGINAL', True)
+        orig_tune_params = get_tune_parameters(orig_tune, d)
+        orig_tune_baselib = orig_tune_params['baselib']
+        orig_tune_bitness = orig_tune_baselib.replace('lib', '')
+        if not orig_tune_bitness:
+            orig_tune_bitness = '32'
+
+        src = '../../../' + orig_tune_baselib + '/' + \
+            d.getVar('TARGET_SYS_MULTILIB_ORIGINAL', True) + '/' + binv + '/'
+
+        dest = d.getVar('D', True) + d.getVar('libdir', True) + '/' + \
+            d.getVar('TARGET_SYS', True) + '/' + binv + '/' + orig_tune_bitness
+
+        if os.path.lexists(dest):
+            os.unlink(dest)
+        os.symlink(src, dest)
+        return
+
+
+    for ml in multilibs.split():
+        tune = d.getVar('DEFAULTTUNE_virtclass-multilib-' + ml, True)
+        if not tune:
+            bb.warn('DEFAULTTUNE_virtclass-multilib-%s is not defined. Skipping...' % ml)
+            continue
+
+        tune_parameters = get_tune_parameters(tune, d)
+        tune_baselib = tune_parameters['baselib']
+        if not tune_baselib:
+            bb.warn("Tune %s doesn't have a baselib set. Skipping..." % tune)
+            continue
+
+        tune_arch = tune_parameters['arch']
+        tune_bitness = tune_baselib.replace('lib', '')
+        if not tune_bitness:
+            tune_bitness = '32' # /lib => 32bit lib
+
+        src = '../../../' + tune_baselib + '/' + \
+            tune_arch + d.getVar('TARGET_VENDOR', True) + 'ml' + ml + \
+            '-' + d.getVar('TARGET_OS', True) + '/' + binv + '/'
+
+        dest = d.getVar('D', True) + d.getVar('libdir', True) + '/' + \
+            d.getVar('TARGET_SYS', True) + '/' + binv + '/' + tune_bitness
+
+        if os.path.lexists(dest):
+            os.unlink(dest)
+        os.symlink(src, dest)
+}
+
+def get_original_vendoros(d):
+    vendoros = d.expand('${TARGET_VENDOR}-${TARGET_OS}')
+    for suffix in [d.getVar('ABIEXTENSION', True), d.getVar('LIBCEXTENSION', True)]:
+        if suffix and vendoros.endswith(suffix):
+            vendoros = vendoros[:-len(suffix)]
+    return vendoros
+
+ORIG_TARGET_VENDOROS := "${@get_original_vendoros(d)}"
+BASETARGET_SYS = "${TARGET_ARCH}${ORIG_TARGET_VENDOROS}"
+
+addtask extra_symlinks after do_multilib_install before do_package do_populate_sysroot
+fakeroot python do_extra_symlinks() {
+    targetsys = d.getVar('BASETARGET_SYS', True)
+
+    if targetsys != d.getVar('TARGET_SYS', True):
+        dest = d.getVar('D', True) + d.getVar('libdir', True) + '/' + targetsys
+        src = d.getVar('TARGET_SYS', True)
+        if not os.path.lexists(dest) and os.path.lexists(d.getVar('D', True) + d.getVar('libdir', True)):
+            os.symlink(src, dest)
+}
diff --git a/recipes-devtools/gcc/libgcc-initial_4.9.bb b/recipes-devtools/gcc/libgcc-initial_4.9.bb
new file mode 100644
index 0000000..053c293
--- /dev/null
+++ b/recipes-devtools/gcc/libgcc-initial_4.9.bb
@@ -0,0 +1,2 @@
+require gcc-${PV}.inc
+require recipes-devtools/gcc/libgcc-initial.inc
diff --git a/recipes-devtools/gcc/libgcc-initial_4.9.bbappend b/recipes-devtools/gcc/libgcc-initial_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/libgcc-initial_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/libgcc_4.9.bb b/recipes-devtools/gcc/libgcc_4.9.bb
new file mode 100644
index 0000000..119e8e0
--- /dev/null
+++ b/recipes-devtools/gcc/libgcc_4.9.bb
@@ -0,0 +1,2 @@
+require gcc-${PV}.inc
+require recipes-devtools/gcc/libgcc.inc
diff --git a/recipes-devtools/gcc/libgcc_4.9.bbappend b/recipes-devtools/gcc/libgcc_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/libgcc_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/recipes-devtools/gcc/libgfortran.inc b/recipes-devtools/gcc/libgfortran.inc
new file mode 100644
index 0000000..e42843d
--- /dev/null
+++ b/recipes-devtools/gcc/libgfortran.inc
@@ -0,0 +1,74 @@
+require gcc-configure-common.inc
+
+EXTRA_OECONF_PATHS = "\
+    --with-sysroot=/not/exist \
+    --with-build-sysroot=${STAGING_DIR_TARGET} \
+"
+
+do_configure () {
+	mtarget=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+	target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+	hardlinkdir ${STAGING_INCDIR_NATIVE}/gcc-build-internal-$mtarget ${B}
+
+	echo "Configuring libgfortran"
+	rm -rf ${B}/$target/libgfortran/
+	mkdir -p ${B}/$target/libgfortran/
+	cd ${B}/$target/libgfortran/
+	chmod a+x ${S}/libgfortran/configure
+	${S}/libgfortran/configure ${CONFIGUREOPTS} ${EXTRA_OECONF}
+	# Easiest way to stop bad RPATHs getting into the library since we have a
+	# broken libtool here
+	sed -i -e 's/hardcode_into_libs=yes/hardcode_into_libs=no/' ${B}/$target/libgfortran/libtool
+}
+
+do_compile () {
+	target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+	cd ${B}/$target/libgfortran/
+	oe_runmake MULTIBUILDTOP=${B}/$target/libgfortran/
+}
+
+do_install () {
+	target=`echo ${TARGET_SYS} | sed -e s#-${SDKPKGSUFFIX}##`
+	cd ${B}/$target/libgfortran/
+	oe_runmake 'DESTDIR=${D}' MULTIBUILDTOP=${B}/$target/libgfortran/ install
+	if [ -d ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/finclude ]; then
+		rmdir --ignore-fail-on-non-empty -p ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/finclude
+	fi
+	if [ -d ${D}${infodir} ]; then
+		rmdir --ignore-fail-on-non-empty -p ${D}${infodir}
+	fi
+	chown -R root:root ${D}
+}
+
+INHIBIT_DEFAULT_DEPS = "1"
+DEPENDS = "gcc-runtime"
+
+BBCLASSEXTEND = "nativesdk"
+
+PACKAGES = "\
+    ${PN}-dbg \
+    libgfortran \
+    libgfortran-dev \
+    libgfortran-staticdev \
+"
+FILES_${PN} = "${libdir}/libgfortran.so.*"
+FILES_${PN}-dev = "\
+    ${libdir}/libgfortran*.so \
+    ${libdir}/libgfortran.spec \
+    ${libdir}/libgfortran.la \
+    ${libdir}/gcc/${TARGET_SYS}/${BINV}/libgfortranbegin.* \
+    ${libdir}/gcc/${TARGET_SYS}/${BINV}/libcaf_single* \
+"
+FILES_${PN}-staticdev = "${libdir}/libgfortran.a"
+
+INSANE_SKIP_${MLPREFIX}libgfortran-dev = "staticdev"
+
+do_package_write_ipk[depends] += "virtual/${MLPREFIX}libc:do_packagedata"
+do_package_write_deb[depends] += "virtual/${MLPREFIX}libc:do_packagedata"
+do_package_write_rpm[depends] += "virtual/${MLPREFIX}libc:do_packagedata"
+
+python __anonymous () {
+    f = d.getVar("FORTRAN", True)
+    if "fortran" not in f:
+        raise bb.parse.SkipPackage("libgfortran needs fortran support to be enabled in the compiler")
+}
diff --git a/recipes-devtools/gcc/libgfortran_4.9.bb b/recipes-devtools/gcc/libgfortran_4.9.bb
new file mode 100644
index 0000000..1af805e
--- /dev/null
+++ b/recipes-devtools/gcc/libgfortran_4.9.bb
@@ -0,0 +1,3 @@
+require gcc-${PV}.inc
+require libgfortran.inc
+
diff --git a/recipes-devtools/gcc/libgfortran_4.9.bbappend b/recipes-devtools/gcc/libgfortran_4.9.bbappend
new file mode 100644
index 0000000..1c725f2
--- /dev/null
+++ b/recipes-devtools/gcc/libgfortran_4.9.bbappend
@@ -0,0 +1 @@
+require gcc-fsl.inc
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 09/18] glibc : add 2.20 version
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (15 preceding siblings ...)
  2017-12-28 10:05 ` [PATCH 11/18] gcc : add 4.9 version Chunrong Guo
@ 2017-12-28 10:05 ` Chunrong Guo
  2018-01-04 14:33 ` [PATCH 01/18] e500v2.inc: add recipe Bob Cochran
  17 siblings, 0 replies; 22+ messages in thread
From: Chunrong Guo @ 2017-12-28 10:05 UTC (permalink / raw)
  To: meta-freescale; +Cc: chunrong.guo

From: Chunrong Guo <chunrong.guo@nxp.com>

*ppc machine only  support glibc 2.20 version

Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
---
 .../fix_for_centos_5.8.patch                       |    18 +
 recipes-core/glibc/cross-localedef-native_2.20.bb  |    57 +
 recipes-core/glibc/cross-localedef-native_2.22.bb  |    59 +
 .../glibc/cross-localedef-native_2.22.bbappend     |     7 +
 .../cross-localedef/enable-host-aarch64.patch      |    13 +
 recipes-core/glibc/glibc-common.inc                |     9 +
 .../glibc/glibc-fsl/0001.glibc.fix_sqrt2.patch     |  1692 ++
 .../glibc-fsl/0002.glibc.fix_sqrt_finite.patch     |   187 +
 .../0003.glibc.fix_slow_ieee754_sqrt.patch         |   410 +
 .../glibc-fsl/0004.glibc.fsl-ppc-no-fsqrt.patch    |   101 +
 .../glibc/glibc-fsl/0005.glibc.fix_prof.patch      |    47 +
 .../glibc/glibc-fsl/0006.glibc.fsl-crosszic.patch  |    76 +
 .../0007.glibc.fix_MTWX51911-enable_8xx.patch      |   530 +
 .../glibc-fsl/0008.glibc.e500v2_lib_support.patch  |  2542 +++
 .../0009.glibc.fsl-mcpy-e500mc-e5500-e6500.patch   |  1191 ++
 .../0010.glibc.fsl-e500mc-e5500-mset.patch         |  1337 ++
 .../glibc-fsl/0011.glibc.fsl-mset-e6500.patch      |   537 +
 .../glibc-fsl/0012.glibc.fsl-mcmp-e6500.patch      |   832 +
 .../glibc-fsl/0013.glibc.fsl-stcmp-e5500.patch     |   380 +
 .../0014.glibc.fsl-strchr-e500mc-e5500.patch       |   659 +
 .../0015.glibc.fsl-strcpy-e500mc-e5500.patch       |   627 +
 ...move-bash-dependency-for-nscd-init-script.patch |    75 +
 .../0016.glibc.fsl-strlen-e500mc-e5500.patch       |   407 +
 .../0017.glibc.fsl-strrchr-e500mc-e5500.patch      |  1072 ++
 ...0018.glibc.testsuite_remove-blocking-test.patch |   258 +
 .../glibc/glibc-fsl/0019.glibc.readv_proto.patch   |    61 +
 ...20.glibc.fsl-largemcpy-e500mc-e5500-e6500.patch |   932 +
 .../glibc-fsl/0021.glibc.undefined_static.patch    |    37 +
 .../glibc-fsl/0022.glibc.use-option-groups.patch   |   149 +
 .../00xx.glibc.add-option-groups-support.patch     |  1389 ++
 .../00xx.glibc.rtld_debug_option_group.patch       |   517 +
 .../glibc-fsl/00xx.glibc.use-option-groups.patch   | 16551 ++++++++++++++++++
 recipes-core/glibc/glibc-initial.inc               |    83 +
 recipes-core/glibc/glibc-initial_2.20.bb           |    11 +
 recipes-core/glibc/glibc-ld.inc                    |    56 +
 recipes-core/glibc/glibc-locale_2.20.bb            |     1 +
 recipes-core/glibc/glibc-mtrace_2.20.bb            |     1 +
 recipes-core/glibc/glibc-options.inc               |   162 +
 recipes-core/glibc/glibc-package.inc               |   227 +
 recipes-core/glibc/glibc-scripts_2.20.bb           |     1 +
 recipes-core/glibc/glibc-testing.inc               |    79 +
 .../glibc/glibc/0001-R_ARM_TLS_DTPOFF32.patch      |    56 +
 ...n-libm-err-tab.pl-with-specific-dirs-in-S.patch |    33 +
 ...-timezone-re-written-tzselect-as-posix-sh.patch |    45 +
 ...c-Cross-building-and-testing-instructions.patch |   619 +
 ...g-Eglibc-option-group-infrastructure-to-g.patch |  1436 ++
 ...020-eglibc-Help-bootstrap-cross-toolchain.patch |   100 +
 ...ry-picked-from-http-www.eglibc.org-archiv.patch |    64 +
 .../0022-eglibc-Clear-cache-lines-on-ppc8xx.patch  |    81 +
 ...0023-eglibc-Resolve-__fpscr_values-on-SH4.patch |    56 +
 ...orward-port-eglibc-options-groups-support.patch | 16842 +++++++++++++++++++
 .../glibc/0025-eglibc-Install-PIC-archives.patch   |   123 +
 ...ebug_mask-is-controlled-by-__OPTION_EGLIB.patch |   556 +
 ...option-groups-Conditionally-exclude-c-tes.patch |   145 +
 ...-3406-Stack-overflow-in-vfprintf-BZ-16617.patch |   339 +
 ...4-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch |   215 +
 .../CVE-2014-9402_endless-loop-in-getaddr_r.patch  |    65 +
 ...81-resolv-nss_dns-dns-host.c-buffer-overf.patch |    43 +
 recipes-core/glibc/glibc/GLRO_dl_debug_mask.patch  |   529 +
 recipes-core/glibc/glibc/IO-acquire-lock-fix.patch |    17 +
 .../glibc/glibc/add_resource_h_to_wait_h.patch     |    20 +
 .../glibc/glibc/eglibc-header-bootstrap.patch      |    85 +
 .../glibc/glibc/eglibc-install-pic-archives.patch  |   109 +
 .../eglibc-ppc8xx-cache-line-workaround.patch      |    68 +
 .../glibc/glibc/eglibc-resolv-dynamic.patch        |    54 +
 .../glibc/glibc/eglibc-sh4-fpscr_values.patch      |    42 +
 .../glibc/glibc/eglibc-use-option-groups.patch     | 16546 ++++++++++++++++++
 recipes-core/glibc/glibc/eglibc.patch              |   602 +
 recipes-core/glibc/glibc/etc/ld.so.conf            |     0
 .../glibc/glibc/fix-tibetian-locales.patch         |    38 +
 recipes-core/glibc/glibc/fix_am_rootsbindir.patch  |    29 +
 recipes-core/glibc/glibc/fsl-ppc-no-fsqrt.patch    |   100 +
 recipes-core/glibc/glibc/generate-supported.mk     |    11 +
 recipes-core/glibc/glibc/glibc.fix_sqrt2.patch     |  1516 ++
 recipes-core/glibc/glibc/grok_gold.patch           |    34 +
 recipes-core/glibc/glibc/initgroups_keys.patch     |    20 +
 .../intl-Merge-with-gettext-version-0.19.3.patch   |  4797 ++++++
 recipes-core/glibc/glibc/ld-search-order.patch     |    56 +
 recipes-core/glibc/glibc/mips-rld-map-check.patch  |    27 +
 recipes-core/glibc/glibc/multilib_readlib.patch    |    19 +
 recipes-core/glibc/glibc/option-groups.patch       |  1397 ++
 recipes-core/glibc/glibc/ppc-sqrt_finite.patch     |   184 +
 .../glibc/glibc/ppc_slow_ieee754_sqrt.patch        |   365 +
 .../glibc/ppce6500-32b_slow_ieee754_sqrt.patch     |    47 +
 recipes-core/glibc/glibc/relocatable_sdk.patch     |   108 +
 .../glibc/glibc/relocatable_sdk_fix_openpath.patch |    41 +
 .../timezone-re-written-tzselect-as-posix-sh.patch |    38 +
 recipes-core/glibc/glibc_2.20.bb                   |   193 +
 .../glibc/ldconfig-native-2.12.1/32and64bit.patch  |   331 +
 recipes-core/glibc/ldconfig-native-2.12.1/README   |     8 +
 .../endian-ness_handling.patch                     |   454 +
 .../endian-ness_handling_fix.patch                 |    47 +
 .../ldconfig-native-2.12.1/endianess-header.patch  |   113 +
 .../glibc/ldconfig-native-2.12.1/flag_fix.patch    |    24 +
 .../ldconfig-default-to-all-multilib-dirs.patch    |    37 +
 .../ldconfig-native-2.12.1.tar.bz2                 |   Bin 0 -> 21491 bytes
 .../glibc/ldconfig-native-2.12.1/ldconfig.patch    |   471 +
 .../ldconfig_aux-cache_path_fix.patch              |    36 +
 recipes-core/glibc/ldconfig-native_2.12.1.bb       |    33 +
 recipes-core/glibc/site_config/funcs               |   474 +
 recipes-core/glibc/site_config/headers             |   156 +
 recipes-core/glibc/site_config/types               |    21 +
 102 files changed, 83495 insertions(+)
 create mode 100644 recipes-core/glibc/cross-localedef-native/fix_for_centos_5.8.patch
 create mode 100644 recipes-core/glibc/cross-localedef-native_2.20.bb
 create mode 100644 recipes-core/glibc/cross-localedef-native_2.22.bb
 create mode 100644 recipes-core/glibc/cross-localedef-native_2.22.bbappend
 create mode 100644 recipes-core/glibc/cross-localedef/enable-host-aarch64.patch
 create mode 100644 recipes-core/glibc/glibc-common.inc
 create mode 100755 recipes-core/glibc/glibc-fsl/0001.glibc.fix_sqrt2.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0002.glibc.fix_sqrt_finite.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0003.glibc.fix_slow_ieee754_sqrt.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0004.glibc.fsl-ppc-no-fsqrt.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0005.glibc.fix_prof.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0006.glibc.fsl-crosszic.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0007.glibc.fix_MTWX51911-enable_8xx.patch
 create mode 100644 recipes-core/glibc/glibc-fsl/0008.glibc.e500v2_lib_support.patch
 create mode 100644 recipes-core/glibc/glibc-fsl/0009.glibc.fsl-mcpy-e500mc-e5500-e6500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0010.glibc.fsl-e500mc-e5500-mset.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0011.glibc.fsl-mset-e6500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0012.glibc.fsl-mcmp-e6500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0013.glibc.fsl-stcmp-e5500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0014.glibc.fsl-strchr-e500mc-e5500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0015.glibc.fsl-strcpy-e500mc-e5500.patch
 create mode 100644 recipes-core/glibc/glibc-fsl/0016-Remove-bash-dependency-for-nscd-init-script.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0016.glibc.fsl-strlen-e500mc-e5500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0017.glibc.fsl-strrchr-e500mc-e5500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0018.glibc.testsuite_remove-blocking-test.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0019.glibc.readv_proto.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0020.glibc.fsl-largemcpy-e500mc-e5500-e6500.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/0021.glibc.undefined_static.patch
 create mode 100644 recipes-core/glibc/glibc-fsl/0022.glibc.use-option-groups.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/00xx.glibc.add-option-groups-support.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/00xx.glibc.rtld_debug_option_group.patch
 create mode 100755 recipes-core/glibc/glibc-fsl/00xx.glibc.use-option-groups.patch
 create mode 100644 recipes-core/glibc/glibc-initial.inc
 create mode 100644 recipes-core/glibc/glibc-initial_2.20.bb
 create mode 100644 recipes-core/glibc/glibc-ld.inc
 create mode 100644 recipes-core/glibc/glibc-locale_2.20.bb
 create mode 100644 recipes-core/glibc/glibc-mtrace_2.20.bb
 create mode 100644 recipes-core/glibc/glibc-options.inc
 create mode 100644 recipes-core/glibc/glibc-package.inc
 create mode 100644 recipes-core/glibc/glibc-scripts_2.20.bb
 create mode 100644 recipes-core/glibc/glibc-testing.inc
 create mode 100644 recipes-core/glibc/glibc/0001-R_ARM_TLS_DTPOFF32.patch
 create mode 100644 recipes-core/glibc/glibc/0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
 create mode 100644 recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch
 create mode 100644 recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
 create mode 100644 recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch
 create mode 100644 recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch
 create mode 100644 recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch
 create mode 100644 recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch
 create mode 100644 recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch
 create mode 100644 recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch
 create mode 100644 recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch
 create mode 100644 recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch
 create mode 100644 recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch
 create mode 100644 recipes-core/glibc/glibc/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
 create mode 100644 recipes-core/glibc/glibc/CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch
 create mode 100644 recipes-core/glibc/glibc/CVE-2014-9402_endless-loop-in-getaddr_r.patch
 create mode 100644 recipes-core/glibc/glibc/CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch
 create mode 100644 recipes-core/glibc/glibc/GLRO_dl_debug_mask.patch
 create mode 100644 recipes-core/glibc/glibc/IO-acquire-lock-fix.patch
 create mode 100644 recipes-core/glibc/glibc/add_resource_h_to_wait_h.patch
 create mode 100644 recipes-core/glibc/glibc/eglibc-header-bootstrap.patch
 create mode 100644 recipes-core/glibc/glibc/eglibc-install-pic-archives.patch
 create mode 100644 recipes-core/glibc/glibc/eglibc-ppc8xx-cache-line-workaround.patch
 create mode 100644 recipes-core/glibc/glibc/eglibc-resolv-dynamic.patch
 create mode 100644 recipes-core/glibc/glibc/eglibc-sh4-fpscr_values.patch
 create mode 100644 recipes-core/glibc/glibc/eglibc-use-option-groups.patch
 create mode 100644 recipes-core/glibc/glibc/eglibc.patch
 create mode 100644 recipes-core/glibc/glibc/etc/ld.so.conf
 create mode 100644 recipes-core/glibc/glibc/fix-tibetian-locales.patch
 create mode 100644 recipes-core/glibc/glibc/fix_am_rootsbindir.patch
 create mode 100644 recipes-core/glibc/glibc/fsl-ppc-no-fsqrt.patch
 create mode 100644 recipes-core/glibc/glibc/generate-supported.mk
 create mode 100644 recipes-core/glibc/glibc/glibc.fix_sqrt2.patch
 create mode 100644 recipes-core/glibc/glibc/grok_gold.patch
 create mode 100644 recipes-core/glibc/glibc/initgroups_keys.patch
 create mode 100644 recipes-core/glibc/glibc/intl-Merge-with-gettext-version-0.19.3.patch
 create mode 100644 recipes-core/glibc/glibc/ld-search-order.patch
 create mode 100644 recipes-core/glibc/glibc/mips-rld-map-check.patch
 create mode 100644 recipes-core/glibc/glibc/multilib_readlib.patch
 create mode 100644 recipes-core/glibc/glibc/option-groups.patch
 create mode 100644 recipes-core/glibc/glibc/ppc-sqrt_finite.patch
 create mode 100644 recipes-core/glibc/glibc/ppc_slow_ieee754_sqrt.patch
 create mode 100644 recipes-core/glibc/glibc/ppce6500-32b_slow_ieee754_sqrt.patch
 create mode 100644 recipes-core/glibc/glibc/relocatable_sdk.patch
 create mode 100644 recipes-core/glibc/glibc/relocatable_sdk_fix_openpath.patch
 create mode 100644 recipes-core/glibc/glibc/timezone-re-written-tzselect-as-posix-sh.patch
 create mode 100644 recipes-core/glibc/glibc_2.20.bb
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/32and64bit.patch
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/README
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling.patch
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling_fix.patch
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/endianess-header.patch
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/flag_fix.patch
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/ldconfig-default-to-all-multilib-dirs.patch
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/ldconfig-native-2.12.1.tar.bz2
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/ldconfig.patch
 create mode 100644 recipes-core/glibc/ldconfig-native-2.12.1/ldconfig_aux-cache_path_fix.patch
 create mode 100644 recipes-core/glibc/ldconfig-native_2.12.1.bb
 create mode 100644 recipes-core/glibc/site_config/funcs
 create mode 100644 recipes-core/glibc/site_config/headers
 create mode 100644 recipes-core/glibc/site_config/types

diff --git a/recipes-core/glibc/cross-localedef-native/fix_for_centos_5.8.patch b/recipes-core/glibc/cross-localedef-native/fix_for_centos_5.8.patch
new file mode 100644
index 0000000..186a480
--- /dev/null
+++ b/recipes-core/glibc/cross-localedef-native/fix_for_centos_5.8.patch
@@ -0,0 +1,18 @@
+Upstream-Status: Inappropriate [other]
+
+This is a hack to fix building the locale bits on an older
+CentOs 5.X machine
+
+Index: git/locale/programs/config.h
+===================================================================
+--- git/locale/programs/config.h
++++ git.orig/locale/programs/config.h
+@@ -19,6 +19,8 @@
+ #ifndef _LD_CONFIG_H
+ #define _LD_CONFIG_H	1
+ 
++#define DUMMY_LOCALE_T
++
+ /* Use the internal textdomain used for libc messages.  */
+ #define PACKAGE _libc_intl_domainname
+ #ifndef VERSION
diff --git a/recipes-core/glibc/cross-localedef-native_2.20.bb b/recipes-core/glibc/cross-localedef-native_2.20.bb
new file mode 100644
index 0000000..c94501a
--- /dev/null
+++ b/recipes-core/glibc/cross-localedef-native_2.20.bb
@@ -0,0 +1,57 @@
+SUMMARY = "Cross locale generation tool for glibc"
+HOMEPAGE = "http://www.gnu.org/software/libc/libc.html"
+SECTION = "libs"
+LICENSE = "LGPL-2.1"
+
+LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \
+      file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
+      file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \
+      file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c"
+
+
+inherit native
+inherit autotools
+
+FILESEXTRAPATHS =. "${FILE_DIRNAME}/${PN}:${FILE_DIRNAME}/glibc:"
+
+PV = "2.20"
+
+SRC_URI = "git://sourceware.org/git/glibc.git;branch=release/${PV}/master;name=glibc \
+           git://github.com/kraj/localedef;branch=master;name=localedef;destsuffix=git/localedef \
+	   file://fix_for_centos_5.8.patch \
+           ${EGLIBCPATCHES} \
+          "
+EGLIBCPATCHES = "\
+           file://intl-Merge-with-gettext-version-0.19.3.patch \
+           file://timezone-re-written-tzselect-as-posix-sh.patch \
+           file://eglibc.patch \
+           file://option-groups.patch \
+           file://GLRO_dl_debug_mask.patch \
+           file://eglibc-header-bootstrap.patch \
+           file://eglibc-resolv-dynamic.patch \
+           file://eglibc-ppc8xx-cache-line-workaround.patch \
+           file://eglibc-sh4-fpscr_values.patch \
+           file://eglibc-use-option-groups.patch \
+          "
+
+SRCREV_glibc = "b8079dd0d360648e4e8de48656c5c38972621072"
+SRCREV_localedef = "c833367348d39dad7ba018990bfdaffaec8e9ed3"
+
+# Makes for a rather long rev (22 characters), but...
+#
+SRCREV_FORMAT = "glibc__localedef"
+
+S = "${WORKDIR}/git"
+
+EXTRA_OECONF = "--with-glibc=${S}"
+CFLAGS += "-fgnu89-inline -std=gnu99 -DNOT_IN_libc=1"
+
+do_configure () {
+	${S}/localedef/configure ${EXTRA_OECONF}
+}
+
+
+do_install() {
+	install -d ${D}${bindir} 
+	install -m 0755 ${B}/localedef ${D}${bindir}/cross-localedef
+}
diff --git a/recipes-core/glibc/cross-localedef-native_2.22.bb b/recipes-core/glibc/cross-localedef-native_2.22.bb
new file mode 100644
index 0000000..03be9c0
--- /dev/null
+++ b/recipes-core/glibc/cross-localedef-native_2.22.bb
@@ -0,0 +1,59 @@
+SUMMARY = "Cross locale generation tool for glibc"
+HOMEPAGE = "http://www.gnu.org/software/libc/libc.html"
+SECTION = "libs"
+LICENSE = "LGPL-2.1"
+
+LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \
+      file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
+      file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \
+      file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c"
+
+
+inherit native
+inherit autotools
+
+FILESEXTRAPATHS =. "${FILE_DIRNAME}/${PN}:${FILE_DIRNAME}/glibc:"
+
+SRCBRANCH ?= "release/${PV}/master"
+GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git"
+
+SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
+           git://github.com/kraj/localedef;branch=master;name=localedef;destsuffix=git/localedef \
+           file://fix_for_centos_5.8.patch \
+           ${EGLIBCPATCHES} \
+"
+EGLIBCPATCHES = "\
+           file://0017-timezone-re-written-tzselect-as-posix-sh.patch \
+           file://0018-eglibc-Cross-building-and-testing-instructions.patch \
+           file://0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch \
+           file://0020-eglibc-Help-bootstrap-cross-toolchain.patch \
+           file://0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch \
+           file://0022-eglibc-Clear-cache-lines-on-ppc8xx.patch \
+           file://0023-eglibc-Resolve-__fpscr_values-on-SH4.patch \
+           file://0024-eglibc-Forward-port-eglibc-options-groups-support.patch \
+           file://0025-eglibc-Install-PIC-archives.patch \
+           file://0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch \
+           file://0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch \
+"
+
+SRCREV_glibc ?= "a34d1c6afc86521d6ad17662a3b5362d8481514c"
+SRCREV_localedef ?= "c833367348d39dad7ba018990bfdaffaec8e9ed3"
+
+# Makes for a rather long rev (22 characters), but...
+#
+SRCREV_FORMAT = "glibc_localedef"
+
+S = "${WORKDIR}/git"
+
+EXTRA_OECONF = "--with-glibc=${S}"
+CFLAGS += "-fgnu89-inline -std=gnu99 -DIS_IN\(x\)='0'"
+
+do_configure () {
+	${S}/localedef/configure ${EXTRA_OECONF}
+}
+
+
+do_install() {
+	install -d ${D}${bindir}
+	install -m 0755 ${B}/localedef ${D}${bindir}/cross-localedef
+}
diff --git a/recipes-core/glibc/cross-localedef-native_2.22.bbappend b/recipes-core/glibc/cross-localedef-native_2.22.bbappend
new file mode 100644
index 0000000..2fe775d
--- /dev/null
+++ b/recipes-core/glibc/cross-localedef-native_2.22.bbappend
@@ -0,0 +1,7 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:"
+
+# We need this patch to allow host side aarch64
+SRC_URI_append_fsl-qoriq = "\
+    file://enable-host-aarch64.patch \
+"
+
diff --git a/recipes-core/glibc/cross-localedef/enable-host-aarch64.patch b/recipes-core/glibc/cross-localedef/enable-host-aarch64.patch
new file mode 100644
index 0000000..c129a51
--- /dev/null
+++ b/recipes-core/glibc/cross-localedef/enable-host-aarch64.patch
@@ -0,0 +1,13 @@
+diff --git a/localedef/config.guess b/localedef/config.guess
+index 61f2e4c..9834a43 100644
+--- a/localedef/config.guess
++++ b/localedef/config.guess
+@@ -820,7 +820,7 @@ EOF
+     i*86:Minix:*:*)
+ 	echo ${UNAME_MACHINE}-pc-minix
+ 	exit 0 ;;
+-    arm*:Linux:*:*)
++    arm*:Linux:*:* | aarch*:Linux:*:*)
+ 	echo ${UNAME_MACHINE}-unknown-linux-gnu
+ 	exit 0 ;;
+     cris:Linux:*:*)
diff --git a/recipes-core/glibc/glibc-common.inc b/recipes-core/glibc/glibc-common.inc
new file mode 100644
index 0000000..bba1568
--- /dev/null
+++ b/recipes-core/glibc/glibc-common.inc
@@ -0,0 +1,9 @@
+SUMMARY = "GLIBC (GNU C Library)"
+DESCRIPTION = "The GNU C Library is used as the system C library in most systems with the Linux kernel."
+HOMEPAGE = "http://www.gnu.org/software/libc/libc.html"
+SECTION = "libs"
+LICENSE = "GPLv2 & LGPLv2.1"
+LIC_FILES_CHKSUM ?= "file://LICENSES;md5=07a394b26e0902b9ffdec03765209770 \
+      file://COPYING;md5=393a5ca445f6965873eca0259a17f833 \
+      file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \
+      file://COPYING.LIB;md5=bbb461211a33b134d42ed5ee802b37ff "
diff --git a/recipes-core/glibc/glibc-fsl/0001.glibc.fix_sqrt2.patch b/recipes-core/glibc/glibc-fsl/0001.glibc.fix_sqrt2.patch
new file mode 100755
index 0000000..16f742a
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0001.glibc.fix_sqrt2.patch
@@ -0,0 +1,1692 @@
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c	2012-06-14 14:51:50.452001745 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c	2012-06-14 14:51:50.452001745 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c	2012-06-14 14:55:14.749001061 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c	2012-06-14 14:55:14.749001061 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c	2012-06-14 14:55:21.812002270 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c	2012-06-14 14:55:21.812002270 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2012-06-14 14:55:24.620001266 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2012-06-14 14:55:24.620001266 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c	2012-06-14 14:51:50.452001745 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c	2012-06-14 14:51:50.452001745 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c	2012-06-14 14:56:02.080000985 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c	2012-06-14 14:56:02.080000985 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies	2012-06-14 14:51:50.452001745 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc32/603e/fpu
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies	2012-06-14 14:54:00.481000876 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc32/e500mc/fpu
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies	2012-06-14 14:54:17.000001007 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc32/e5500/fpu
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies	2012-06-14 14:54:31.054001299 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc32/e6500/fpu
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies	2012-06-14 14:51:50.453001709 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc64/e5500/fpu
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies	1969-12-31 18:00:00.000000000 -0600
++++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies	2012-06-14 14:58:14.298001288 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc64/e6500/fpu
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c	2014-07-24 04:42:30.366372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c	2014-07-24 04:42:46.249372001 -0500
+@@ -80,7 +80,7 @@
+ 
+           g = b * y;
+           h = 0.5 * y;
+-  
++
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+             return __ieee754_sqrt (b * two108) * twom54;
+@@ -125,7 +125,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c	2014-07-24 04:42:30.366372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c	2014-07-24 04:42:46.249372001 -0500
+@@ -92,7 +92,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c	2014-07-24 04:42:30.366372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c	2014-07-24 04:42:46.249372001 -0500
+@@ -80,7 +80,7 @@
+ 
+           g = b * y;
+           h = 0.5 * y;
+-  
++
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+             return __ieee754_sqrt (b * two108) * twom54;
+@@ -125,7 +125,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c	2014-07-24 04:42:30.366372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c	2014-07-24 04:42:46.249372001 -0500
+@@ -92,7 +92,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c	2014-07-24 04:42:30.367372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c	2014-07-24 04:42:46.250372001 -0500
+@@ -80,7 +80,7 @@
+ 
+           g = b * y;
+           h = 0.5 * y;
+-  
++
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+             return __ieee754_sqrt (b * two108) * twom54;
+@@ -125,7 +125,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c	2014-07-24 04:42:30.367372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c	2014-07-24 04:42:46.250372001 -0500
+@@ -92,7 +92,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-07-24 04:42:30.367372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-07-24 04:42:46.250372001 -0500
+@@ -80,7 +80,7 @@
+ 
+           g = b * y;
+           h = 0.5 * y;
+-  
++
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+             return __ieee754_sqrt (b * two108) * twom54;
+@@ -125,7 +125,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc-sqrt-patch/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-07-24 04:42:30.367372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-07-24 04:42:46.250372001 -0500
+@@ -92,7 +92,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c libc-sqrt-patch/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c	2014-07-24 04:42:30.367372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c	2014-07-24 04:42:46.250372001 -0500
+@@ -80,7 +80,7 @@
+ 
+           g = b * y;
+           h = 0.5 * y;
+-  
++
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+             return __ieee754_sqrt (b * two108) * twom54;
+@@ -125,7 +125,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c libc-sqrt-patch/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c	2014-07-24 04:42:30.367372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c	2014-07-24 04:42:46.250372001 -0500
+@@ -92,7 +92,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c libc-sqrt-patch/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c	2014-07-24 04:42:30.368372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c	2014-07-24 04:42:46.251372001 -0500
+@@ -80,7 +80,7 @@
+ 
+           g = b * y;
+           h = 0.5 * y;
+-  
++
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+             return __ieee754_sqrt (b * two108) * twom54;
+@@ -125,7 +125,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c libc-sqrt-patch/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+--- libc-sqrt-orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c	2014-07-24 04:42:30.368372001 -0500
++++ libc-sqrt-patch/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c	2014-07-24 04:42:46.251372001 -0500
+@@ -92,7 +92,7 @@
+       feraiseexcept (FE_INVALID_SQRT);
+ 
+       fenv_union_t u = { .fenv = fegetenv_register () };
+-      if ((u.l[1] & FE_INVALID) == 0)
++      if ((u.l & FE_INVALID) == 0)
+ #endif
+ 	feraiseexcept (FE_INVALID);
+       b = a_nan.value;
+diff -Naur libc-sqrt-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies libc-sqrt-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies
+--- libc-sqrt-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies	1969-12-31 18:00:00.000000000 -0600
++++ libc-sqrt-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies	2014-07-24 04:42:46.251372001 -0500
+@@ -0,0 +1,2 @@
++# e300c3 is a variant of 603e so use the same optimizations for sqrt
++powerpc/powerpc32/603e/fpu
diff --git a/recipes-core/glibc/glibc-fsl/0002.glibc.fix_sqrt_finite.patch b/recipes-core/glibc/glibc-fsl/0002.glibc.fix_sqrt_finite.patch
new file mode 100755
index 0000000..d793774
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0002.glibc.fix_sqrt_finite.patch
@@ -0,0 +1,187 @@
+# Problem Statement:
+  on ppc fixes the errors like below
+  | ./.libs/libpulsecore-1.1.so: undefined reference to `__sqrt_finite'
+  | collect2: ld returned 1 exit status
+
+# Reference:
+  ppc-sqrt_finite.patch
+
+ChangeLog
+
+2012-01-06  Khem Raj  <raj.khem@gmail.com>
+
+	* sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Add __*_finite alias.
+	Remove cruft.
+	* sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Ditto.
+	* sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c: Ditto.
+	* sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c: Ditto.
+ 
+Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+@@ -39,14 +39,8 @@ static const float half = 0.5;
+    We find the actual square root and half of its reciprocal
+    simultaneously.  */
+ 
+-#ifdef __STDC__
+ double
+ __ieee754_sqrt (double b)
+-#else
+-double
+-__ieee754_sqrt (b)
+-     double b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -132,3 +126,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+@@ -37,14 +37,8 @@ static const float threehalf = 1.5;
+    We find the reciprocal square root and use that to compute the actual
+    square root.  */
+ 
+-#ifdef __STDC__
+ float
+ __ieee754_sqrtf (float b)
+-#else
+-float
+-__ieee754_sqrtf (b)
+-     float b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -99,3 +93,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+@@ -39,14 +39,8 @@ static const float half = 0.5;
+    We find the actual square root and half of its reciprocal
+    simultaneously.  */
+ 
+-#ifdef __STDC__
+ double
+ __ieee754_sqrt (double b)
+-#else
+-double
+-__ieee754_sqrt (b)
+-     double b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -132,3 +126,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+@@ -37,14 +37,8 @@ static const float threehalf = 1.5;
+    We find the reciprocal square root and use that to compute the actual
+    square root.  */
+ 
+-#ifdef __STDC__
+ float
+ __ieee754_sqrtf (float b)
+-#else
+-float
+-__ieee754_sqrtf (b)
+-     float b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -99,3 +93,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+
diff --git a/recipes-core/glibc/glibc-fsl/0003.glibc.fix_slow_ieee754_sqrt.patch b/recipes-core/glibc/glibc-fsl/0003.glibc.fix_slow_ieee754_sqrt.patch
new file mode 100755
index 0000000..b1fcaba
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0003.glibc.fix_slow_ieee754_sqrt.patch
@@ -0,0 +1,410 @@
+# Problem Statement:
+  __ieee754_sqrt{,f} are now inline functions and call out __slow versions
+
+# Reference 
+  ppc_slow_ieee754_sqrt.patch
+
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Pending
+Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+@@ -40,7 +40,7 @@ static const float half = 0.5;
+    simultaneously.  */
+ 
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -77,7 +77,7 @@ __ieee754_sqrt (double b)
+   
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -126,4 +126,12 @@ __ieee754_sqrt (double b)
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+@@ -38,7 +38,7 @@ static const float threehalf = 1.5;
+    square root.  */
+ 
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -93,4 +93,10 @@ __ieee754_sqrtf (float b)
+     }
+   return f_washf (b);
+ }
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+@@ -40,7 +40,7 @@ static const float half = 0.5;
+    simultaneously.  */
+ 
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -77,7 +77,7 @@ __ieee754_sqrt (double b)
+   
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -126,4 +126,12 @@ __ieee754_sqrt (double b)
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++  return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+@@ -38,7 +38,7 @@ static const float threehalf = 1.5;
+    square root.  */
+ 
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -93,4 +93,11 @@ __ieee754_sqrtf (float b)
+     }
+   return f_washf (b);
+ }
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+@@ -41,10 +41,10 @@ static const float half = 0.5;
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@ __ieee754_sqrt (b)
+   
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -132,4 +132,12 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+@@ -39,10 +39,10 @@ static const float threehalf = 1.5;
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
+@@ -99,4 +99,12 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+@@ -41,10 +41,10 @@ static const float half = 0.5;
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@ __ieee754_sqrt (b)
+   
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -132,4 +132,12 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+@@ -39,10 +39,10 @@ static const float threehalf = 1.5;
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
+@@ -99,4 +99,12 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+@@ -41,10 +41,10 @@ static const float half = 0.5;
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@ __ieee754_sqrt (b)
+   
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -132,4 +132,12 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+@@ -39,10 +39,10 @@ static const float threehalf = 1.5;
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
+@@ -99,4 +99,12 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+@@ -132,4 +132,12 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+@@ -99,4 +99,12 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+diff -rNu libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-04-08 04:39:58.487229887 -0500
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-04-08 04:40:52.643069198 -0500
+@@ -41,10 +41,10 @@
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@
+ 
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+diff -rNu libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-04-08 04:39:58.487229887 -0500
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-04-08 04:41:26.017067682 -0500
+@@ -39,10 +39,10 @@
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
diff --git a/recipes-core/glibc/glibc-fsl/0004.glibc.fsl-ppc-no-fsqrt.patch b/recipes-core/glibc/glibc-fsl/0004.glibc.fsl-ppc-no-fsqrt.patch
new file mode 100755
index 0000000..24a85b6
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0004.glibc.fsl-ppc-no-fsqrt.patch
@@ -0,0 +1,101 @@
+Create e5500 specific math_private.h and let it include when compiling for e5500/64bit core
+We prefefine __CPU_HAS_FSQRT to 0 and then in general ppc64 math_private.h we check if its
+already defined before redefining it. This way we can ensure that on e5500 builds it wont
+emit fsqrt intructions
+
+-Khem
+
+Upstream-Status: Pending
+
+Index: git/sysdeps/powerpc/fpu/math_private.h
+===================================================================
+--- git.orig/sysdeps/powerpc/fpu/math_private.h	2014-08-29 10:31:30.224070587 -0700
++++ git/sysdeps/powerpc/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -25,10 +25,12 @@
+ #include <fenv_private.h>
+ #include_next <math_private.h>
+ 
+-# if __WORDSIZE == 64 || defined _ARCH_PWR4
+-#  define __CPU_HAS_FSQRT 1
+-# else
+-#  define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
++# ifndef __CPU_HAS_FSQRT
++#  if __WORDSIZE == 64 || defined _ARCH_PWR4
++#   define __CPU_HAS_FSQRT 1
++#  else
++#   define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
++#  endif
+ # endif
+ 
+ extern double __slow_ieee754_sqrt (double);
+Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e5500/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E5500_MATH_PRIVATE_H_
++#define _E5500_MATH_PRIVATE_H_ 1
++/* E5500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E5500_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e6500/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E6500_MATH_PRIVATE_H_
++#define _E6500_MATH_PRIVATE_H_ 1
++/* E6500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E6500_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E500MC_MATH_PRIVATE_H_
++#define _E500MC_MATH_PRIVATE_H_ 1
++/* E500MC core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E500MC_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e5500/fpu/math_private.h	2014-08-29 10:31:30.216070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E5500_MATH_PRIVATE_H_
++#define _E5500_MATH_PRIVATE_H_ 1
++/* E5500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E5500_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e6500/fpu/math_private.h	2014-08-29 10:31:30.216070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E6500_MATH_PRIVATE_H_
++#define _E6500_MATH_PRIVATE_H_ 1
++/* E6500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E6500_MATH_PRIVATE_H_ */
+
diff --git a/recipes-core/glibc/glibc-fsl/0005.glibc.fix_prof.patch b/recipes-core/glibc/glibc-fsl/0005.glibc.fix_prof.patch
new file mode 100755
index 0000000..43ba12b
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0005.glibc.fix_prof.patch
@@ -0,0 +1,47 @@
+# Problem Statement:
+  Modify Glibc so that gnu profiling is works with Glibc
+# Reported by:
+  James Yang 
+# Owned by:
+  Srinivas
+# Action:
+  * Modify Glibc such that it can be built with profiling and gprof data is generated correctly for Glibc functions
+  * Added profiling fixes provided in 'powerpc-profiling-fix.diff' file to the latest sources and checked flat-profiling
+    data generated for Glibc functions.
+
+diff -ruN libc-orig/elf/dl-runtime.c libc/elf/dl-runtime.c
+--- libc-orig/elf/dl-runtime.c	2014-06-11 02:51:20.000000000 -0500
++++ libc/elf/dl-runtime.c	2014-07-25 00:36:20.743371998 -0500
+@@ -148,7 +148,6 @@
+   return elf_machine_fixup_plt (l, result, reloc, rel_addr, value);
+ }
+ 
+-#ifndef PROF
+ DL_FIXUP_VALUE_TYPE
+ __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
+ _dl_profile_fixup (
+@@ -433,7 +432,6 @@
+   return value;
+ }
+ 
+-#endif /* PROF */
+ 
+ 
+ #include <stdio.h>
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/dl-trampoline.S libc/sysdeps/powerpc/powerpc32/dl-trampoline.S
+--- libc-orig/sysdeps/powerpc/powerpc32/dl-trampoline.S	2014-06-11 02:44:56.000000000 -0500
++++ libc/sysdeps/powerpc/powerpc32/dl-trampoline.S	2014-07-25 00:36:20.942372001 -0500
+@@ -70,7 +70,6 @@
+ 	cfi_endproc
+ 	.size	 _dl_runtime_resolve,.-_dl_runtime_resolve
+ 
+-#ifndef PROF
+ 	.align 2
+ 	.globl _dl_prof_resolve
+ 	.type _dl_prof_resolve,@function
+@@ -186,4 +185,4 @@
+ 	bctr
+ 	cfi_endproc
+ 	.size	 _dl_prof_resolve,.-_dl_prof_resolve
+-#endif
++
diff --git a/recipes-core/glibc/glibc-fsl/0006.glibc.fsl-crosszic.patch b/recipes-core/glibc/glibc-fsl/0006.glibc.fsl-crosszic.patch
new file mode 100755
index 0000000..5077771
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0006.glibc.fsl-crosszic.patch
@@ -0,0 +1,76 @@
+# Problem Statement:
+  Install timezone data while building glibc v2.20.
+
+# Owned by:
+  Rohit
+
+# Actions:
+  * Created a patch which updates the timezone/Makefile to build cross-zic.
+  * Updated build.sh script to build & install tzdata after glibc build is
+    complete.
+
+diff -Naur glibc-2.20/timezone/Makefile glibc-2.20-tzdata/timezone/Makefile
+--- glibc-2.20/timezone/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-tzdata/timezone/Makefile	2015-02-18 08:02:49.041739203 -0600
+@@ -25,6 +25,9 @@
+ extra-objs := scheck.o ialloc.o
+ 
+ others	:= zdump zic
++ifneq ($(cross-compiling),no)
++others	+= cross-zic
++endif
+ tests	:= test-tz tst-timezone
+ 
+ # pacificnew doesn't compile; if it is to be used, it should be included in
+@@ -53,10 +56,21 @@
+ 
+ include ../Rules
+ 
++zic-objs = zic.o ialloc.o scheck.o
++
++$(addprefix $(objpfx)cross-,$(zic-objs)): $(objpfx)cross-%.o: %.c
++	$(BUILD_CC) $< -c $(OUTPUT_OPTION) $(CFLAGS-$*.c) $(CPPFLAGS-$*) \
++		-DREPORT_BUGS_TO='"$(REPORT_BUGS_TO)"' \
++		-DPKGVERSION='"$(PKGVERSION)"' \
++		$(compile-mkdep-flags) -iquote $(objpfx)
++
++$(objpfx)cross-zic: $(addprefix $(objpfx)cross-,$(zic-objs))
++	$(BUILD_CC) $(addprefix $(objpfx)cross-,$(zic-objs)) -o $@
+ 
+ $(objpfx)zic: $(objpfx)scheck.o $(objpfx)ialloc.o
+ 
+ $(objpfx)zic.o $(objpfx)zdump.o: $(objpfx)version.h
++$(objpfx)cross-zic.o $(objpfx)cross-zdump.o: $(objpfx)version.h
+ 
+ $(objpfx)version.h: $(common-objpfx)config.make
+ 	echo 'static char const TZVERSION[]="$(version)";' \
+@@ -77,10 +91,17 @@
+ # We have to make sure the data for testing the tz functions is available.
+ # Don't add leapseconds here since test-tz made checks that work only without
+ # leapseconds.
++ifeq (no,$(cross-compiling))
+ define build-testdata
+ $(built-program-cmd) -d $(testdata) -y ./yearistype $<; \
+ $(evaluate-test)
+ endef
++else
++define build-testdata
++LANGUAGE=C LC_ALL=C \
++  $(objpfx)cross-zic -d $(testdata) -y ./yearistype $<
++endef
++endif
+ 
+ $(objpfx)test-tz.out: $(addprefix $(testdata)/, America/New_York Etc/UTC UTC)
+ $(objpfx)tst-timezone.out: $(addprefix $(testdata)/, \
+@@ -93,7 +114,11 @@
+ tst-timezone-ENV = TZDIR=$(testdata)
+ 
+ # Note this must come second in the deps list for $(built-program-cmd) to work.
++ifeq (no,$(cross-compiling))
+ zic-deps = $(objpfx)zic $(leapseconds) yearistype
++else
++zic-deps = $(objpfx)cross-zic $(objpfx)zic $(leapseconds) yearistype
++endif
+ 
+ $(testdata)/America/New_York: northamerica $(zic-deps)
+ 	$(build-testdata)
diff --git a/recipes-core/glibc/glibc-fsl/0007.glibc.fix_MTWX51911-enable_8xx.patch b/recipes-core/glibc/glibc-fsl/0007.glibc.fix_MTWX51911-enable_8xx.patch
new file mode 100755
index 0000000..f4159a3
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0007.glibc.fix_MTWX51911-enable_8xx.patch
@@ -0,0 +1,530 @@
+# Problem Statement:
+  ENGR00215432:
+  The purpose of this patch is to disable the use of dcbz in the 32-bit memset.
+  However, this does not fix the root problem because any program
+  -- not just one using eglibc's memset -- can contain dcbz instruction,
+  so it is an incomplete fix anyway.
+
+  There is support in the Linux kernel as of 2.6.33 to emulate the correct
+  behavior (though it seems nobody really knows how well the workaround works),
+  so if the program that uses libc is running on this or a later kernel it does
+  not need to check for an 8xx.
+
+  Therefore one solution is to require kernel 2.6.33 or later.
+
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/dl-sysdep.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/dl-sysdep.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/dl-sysdep.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/dl-sysdep.c	2015-02-24 13:57:36.709739425 -0600
+@@ -0,0 +1,35 @@
++/* Operating system support for run-time dynamic linker.  Linux/PPC version.
++   Copyright (C) 1997-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <config.h>
++#include <ldsodefs.h>
++
++int __cache_line_size attribute_hidden;
++
++/* Scan the Aux Vector for the "Data Cache Block Size" entry.  If found
++   verify that the static extern __cache_line_size is defined by checking
++   for not NULL.  If it is defined then assign the cache block size
++   value to __cache_line_size. This is used by memset to
++   optimize setting to zero.  We have to detect 8xx processors, which
++   have buggy dcbz implementations that cannot report page faults
++   correctly. */
++#define DL_PLATFORM_AUXV						      \
++      case AT_DCACHEBSIZE:						      \
++	break;
++
++#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/libc-start.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/libc-start.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/libc-start.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/801/libc-start.c	2015-02-24 13:53:49.721737701 -0600
+@@ -0,0 +1,86 @@
++/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdlib.h>
++#include <unistd.h>
++#include <ldsodefs.h>
++#include <sysdep.h>
++
++
++int __cache_line_size attribute_hidden;
++/* The main work is done in the generic function.  */
++#define LIBC_START_MAIN generic_start_main
++#define LIBC_START_DISABLE_INLINE
++#define LIBC_START_MAIN_AUXVEC_ARG
++#define MAIN_AUXVEC_ARG
++#define INIT_MAIN_ARGS
++#include <csu/libc-start.c>
++
++struct startup_info
++  {
++    void *sda_base;
++    int (*main) (int, char **, char **, void *);
++    int (*init) (int, char **, char **, void *);
++    void (*fini) (void);
++  };
++
++int
++__libc_start_main (int argc, char **argv,
++		   char **ev,
++		   ElfW (auxv_t) * auxvec,
++		   void (*rtld_fini) (void),
++		   struct startup_info *stinfo,
++		   char **stack_on_entry)
++{
++  /* the PPC SVR4 ABI says that the top thing on the stack will
++     be a NULL pointer, so if not we assume that we're being called
++     as a statically-linked program by Linux...  */
++  if (*stack_on_entry != NULL)
++    {
++      char **temp;
++      /* ...in which case, we have argc as the top thing on the
++         stack, followed by argv (NULL-terminated), envp (likewise),
++         and the auxiliary vector.  */
++      /* 32/64-bit agnostic load from stack */
++      argc = *(long int *) stack_on_entry;
++      argv = stack_on_entry + 1;
++      ev = argv + argc + 1;
++#ifdef HAVE_AUX_VECTOR
++      temp = ev;
++      while (*temp != NULL)
++	++temp;
++      auxvec = (ElfW (auxv_t) *)++ temp;
++#endif
++      rtld_fini = NULL;
++    }
++
++  /* Initialize the __cache_line_size variable from the aux vector.
++     This is used by memset to optimize setting to zero.  We have to
++     detect 8xx processors, which have buggy dcbz implementations that
++     cannot report page faults correctly.  That requires reading SPR,
++     which is a privileged operation.*/
++  for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
++    switch (av->a_type)
++      {
++      case AT_DCACHEBSIZE:
++	break;
++      }
++
++  return generic_start_main (stinfo->main, argc, argv, auxvec,
++			     stinfo->init, stinfo->fini, rtld_fini,
++			     stack_on_entry);
++}
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/dl-sysdep.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/dl-sysdep.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/dl-sysdep.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/dl-sysdep.c	2015-02-24 13:58:00.043738993 -0600
+@@ -0,0 +1,35 @@
++/* Operating system support for run-time dynamic linker.  Linux/PPC version.
++   Copyright (C) 1997-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <config.h>
++#include <ldsodefs.h>
++
++int __cache_line_size attribute_hidden;
++
++/* Scan the Aux Vector for the "Data Cache Block Size" entry.  If found
++   verify that the static extern __cache_line_size is defined by checking
++   for not NULL.  If it is defined then assign the cache block size
++   value to __cache_line_size. This is used by memset to
++   optimize setting to zero.  We have to detect 8xx processors, which
++   have buggy dcbz implementations that cannot report page faults
++   correctly. */
++#define DL_PLATFORM_AUXV						      \
++      case AT_DCACHEBSIZE:						      \
++	break;
++
++#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/libc-start.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/libc-start.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/libc-start.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/821/libc-start.c	2015-02-24 13:58:00.043738993 -0600
+@@ -0,0 +1,86 @@
++/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdlib.h>
++#include <unistd.h>
++#include <ldsodefs.h>
++#include <sysdep.h>
++
++
++int __cache_line_size attribute_hidden;
++/* The main work is done in the generic function.  */
++#define LIBC_START_MAIN generic_start_main
++#define LIBC_START_DISABLE_INLINE
++#define LIBC_START_MAIN_AUXVEC_ARG
++#define MAIN_AUXVEC_ARG
++#define INIT_MAIN_ARGS
++#include <csu/libc-start.c>
++
++struct startup_info
++  {
++    void *sda_base;
++    int (*main) (int, char **, char **, void *);
++    int (*init) (int, char **, char **, void *);
++    void (*fini) (void);
++  };
++
++int
++__libc_start_main (int argc, char **argv,
++		   char **ev,
++		   ElfW (auxv_t) * auxvec,
++		   void (*rtld_fini) (void),
++		   struct startup_info *stinfo,
++		   char **stack_on_entry)
++{
++  /* the PPC SVR4 ABI says that the top thing on the stack will
++     be a NULL pointer, so if not we assume that we're being called
++     as a statically-linked program by Linux...  */
++  if (*stack_on_entry != NULL)
++    {
++      char **temp;
++      /* ...in which case, we have argc as the top thing on the
++         stack, followed by argv (NULL-terminated), envp (likewise),
++         and the auxiliary vector.  */
++      /* 32/64-bit agnostic load from stack */
++      argc = *(long int *) stack_on_entry;
++      argv = stack_on_entry + 1;
++      ev = argv + argc + 1;
++#ifdef HAVE_AUX_VECTOR
++      temp = ev;
++      while (*temp != NULL)
++	++temp;
++      auxvec = (ElfW (auxv_t) *)++ temp;
++#endif
++      rtld_fini = NULL;
++    }
++
++  /* Initialize the __cache_line_size variable from the aux vector.
++     This is used by memset to optimize setting to zero.  We have to
++     detect 8xx processors, which have buggy dcbz implementations that
++     cannot report page faults correctly.  That requires reading SPR,
++     which is a privileged operation.*/
++  for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
++    switch (av->a_type)
++      {
++      case AT_DCACHEBSIZE:
++	break;
++      }
++
++  return generic_start_main (stinfo->main, argc, argv, auxvec,
++			     stinfo->init, stinfo->fini, rtld_fini,
++			     stack_on_entry);
++}
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/dl-sysdep.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/dl-sysdep.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/dl-sysdep.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/dl-sysdep.c	2015-02-24 13:58:03.323739026 -0600
+@@ -0,0 +1,35 @@
++/* Operating system support for run-time dynamic linker.  Linux/PPC version.
++   Copyright (C) 1997-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <config.h>
++#include <ldsodefs.h>
++
++int __cache_line_size attribute_hidden;
++
++/* Scan the Aux Vector for the "Data Cache Block Size" entry.  If found
++   verify that the static extern __cache_line_size is defined by checking
++   for not NULL.  If it is defined then assign the cache block size
++   value to __cache_line_size. This is used by memset to
++   optimize setting to zero.  We have to detect 8xx processors, which
++   have buggy dcbz implementations that cannot report page faults
++   correctly. */
++#define DL_PLATFORM_AUXV						      \
++      case AT_DCACHEBSIZE:						      \
++	break;
++
++#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/libc-start.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/libc-start.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/libc-start.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/823/libc-start.c	2015-02-24 13:58:03.323739026 -0600
+@@ -0,0 +1,86 @@
++/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdlib.h>
++#include <unistd.h>
++#include <ldsodefs.h>
++#include <sysdep.h>
++
++
++int __cache_line_size attribute_hidden;
++/* The main work is done in the generic function.  */
++#define LIBC_START_MAIN generic_start_main
++#define LIBC_START_DISABLE_INLINE
++#define LIBC_START_MAIN_AUXVEC_ARG
++#define MAIN_AUXVEC_ARG
++#define INIT_MAIN_ARGS
++#include <csu/libc-start.c>
++
++struct startup_info
++  {
++    void *sda_base;
++    int (*main) (int, char **, char **, void *);
++    int (*init) (int, char **, char **, void *);
++    void (*fini) (void);
++  };
++
++int
++__libc_start_main (int argc, char **argv,
++		   char **ev,
++		   ElfW (auxv_t) * auxvec,
++		   void (*rtld_fini) (void),
++		   struct startup_info *stinfo,
++		   char **stack_on_entry)
++{
++  /* the PPC SVR4 ABI says that the top thing on the stack will
++     be a NULL pointer, so if not we assume that we're being called
++     as a statically-linked program by Linux...  */
++  if (*stack_on_entry != NULL)
++    {
++      char **temp;
++      /* ...in which case, we have argc as the top thing on the
++         stack, followed by argv (NULL-terminated), envp (likewise),
++         and the auxiliary vector.  */
++      /* 32/64-bit agnostic load from stack */
++      argc = *(long int *) stack_on_entry;
++      argv = stack_on_entry + 1;
++      ev = argv + argc + 1;
++#ifdef HAVE_AUX_VECTOR
++      temp = ev;
++      while (*temp != NULL)
++	++temp;
++      auxvec = (ElfW (auxv_t) *)++ temp;
++#endif
++      rtld_fini = NULL;
++    }
++
++  /* Initialize the __cache_line_size variable from the aux vector.
++     This is used by memset to optimize setting to zero.  We have to
++     detect 8xx processors, which have buggy dcbz implementations that
++     cannot report page faults correctly.  That requires reading SPR,
++     which is a privileged operation.*/
++  for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
++    switch (av->a_type)
++      {
++      case AT_DCACHEBSIZE:
++	break;
++      }
++
++  return generic_start_main (stinfo->main, argc, argv, auxvec,
++			     stinfo->init, stinfo->fini, rtld_fini,
++			     stack_on_entry);
++}
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/dl-sysdep.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/dl-sysdep.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/dl-sysdep.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/dl-sysdep.c	2015-02-24 13:58:41.664736975 -0600
+@@ -0,0 +1,35 @@
++/* Operating system support for run-time dynamic linker.  Linux/PPC version.
++   Copyright (C) 1997-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <config.h>
++#include <ldsodefs.h>
++
++int __cache_line_size attribute_hidden;
++
++/* Scan the Aux Vector for the "Data Cache Block Size" entry.  If found
++   verify that the static extern __cache_line_size is defined by checking
++   for not NULL.  If it is defined then assign the cache block size
++   value to __cache_line_size. This is used by memset to
++   optimize setting to zero.  We have to detect 8xx processors, which
++   have buggy dcbz implementations that cannot report page faults
++   correctly. */
++#define DL_PLATFORM_AUXV						      \
++      case AT_DCACHEBSIZE:						      \
++	break;
++
++#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/libc-start.c glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/libc-start.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/libc-start.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/powerpc/powerpc32/860/libc-start.c	2015-02-24 13:58:41.664736975 -0600
+@@ -0,0 +1,86 @@
++/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdlib.h>
++#include <unistd.h>
++#include <ldsodefs.h>
++#include <sysdep.h>
++
++
++int __cache_line_size attribute_hidden;
++/* The main work is done in the generic function.  */
++#define LIBC_START_MAIN generic_start_main
++#define LIBC_START_DISABLE_INLINE
++#define LIBC_START_MAIN_AUXVEC_ARG
++#define MAIN_AUXVEC_ARG
++#define INIT_MAIN_ARGS
++#include <csu/libc-start.c>
++
++struct startup_info
++  {
++    void *sda_base;
++    int (*main) (int, char **, char **, void *);
++    int (*init) (int, char **, char **, void *);
++    void (*fini) (void);
++  };
++
++int
++__libc_start_main (int argc, char **argv,
++		   char **ev,
++		   ElfW (auxv_t) * auxvec,
++		   void (*rtld_fini) (void),
++		   struct startup_info *stinfo,
++		   char **stack_on_entry)
++{
++  /* the PPC SVR4 ABI says that the top thing on the stack will
++     be a NULL pointer, so if not we assume that we're being called
++     as a statically-linked program by Linux...  */
++  if (*stack_on_entry != NULL)
++    {
++      char **temp;
++      /* ...in which case, we have argc as the top thing on the
++         stack, followed by argv (NULL-terminated), envp (likewise),
++         and the auxiliary vector.  */
++      /* 32/64-bit agnostic load from stack */
++      argc = *(long int *) stack_on_entry;
++      argv = stack_on_entry + 1;
++      ev = argv + argc + 1;
++#ifdef HAVE_AUX_VECTOR
++      temp = ev;
++      while (*temp != NULL)
++	++temp;
++      auxvec = (ElfW (auxv_t) *)++ temp;
++#endif
++      rtld_fini = NULL;
++    }
++
++  /* Initialize the __cache_line_size variable from the aux vector.
++     This is used by memset to optimize setting to zero.  We have to
++     detect 8xx processors, which have buggy dcbz implementations that
++     cannot report page faults correctly.  That requires reading SPR,
++     which is a privileged operation.*/
++  for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
++    switch (av->a_type)
++      {
++      case AT_DCACHEBSIZE:
++	break;
++      }
++
++  return generic_start_main (stinfo->main, argc, argv, auxvec,
++			     stinfo->init, stinfo->fini, rtld_fini,
++			     stack_on_entry);
++}
diff --git a/recipes-core/glibc/glibc-fsl/0008.glibc.e500v2_lib_support.patch b/recipes-core/glibc/glibc-fsl/0008.glibc.e500v2_lib_support.patch
new file mode 100644
index 0000000..b2f04be
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0008.glibc.e500v2_lib_support.patch
@@ -0,0 +1,2542 @@
+# Problem Statement:
+  Optimized library functions for e500v2
+
+# Owned By:
+  Edmar Wienskoski
+
+diff -Naur libc/sysdeps/powerpc/powerpc32/e500/memcpy.S libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/memcpy.S
+--- libc/sysdeps/powerpc/powerpc32/e500/memcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/memcpy.S	2014-08-01 06:43:32.864371998 -0500
+@@ -0,0 +1,408 @@
++/*------------------------------------------------------------------
++ * memcpy.S
++ *
++ * Standard memcpy function optimized for e500 using SPE.  This
++ * function does not handle overlap, as per spec.  This file is
++ * identical to the memmove.S file.  To get a memmove out of it,
++ * specify -D__MEMMOVE__ to the compiler
++ *
++ *------------------------------------------------------------------
++ *      Copyright (c) 2005 Freescale Semiconductor, Inc
++ *      ALL RIGHTS RESERVED
++ *
++ *	Redistribution and use in source and binary forms, with or
++ *	without modification, are permitted provided that the following
++ *	conditions are met:
++ *	
++ *	
++ *	Redistributions of source code must retain the above copyright
++ *	notice, this list of conditions and the following disclaimer.
++ *	
++ *	Redistributions in binary form must reproduce the above copyright
++ *	notice, this list of conditions and the following disclaimer in
++ *	the documentation and/or other materials provided with the
++ *	distribution.
++ *	
++ *	Neither the name of Freescale Semiconductor, Inc nor the names of
++ *	its contributors may be used to endorse or promote products derived
++ *	from this software without specific prior written permission.
++ *	
++ *	
++ *	
++ *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *	CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *	MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *	DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
++ *	BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ *	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
++ *	TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ *	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *	ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
++ *	OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *	OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ *	POSSIBILITY OF SUCH DAMAGE.
++ *------------------------------------------------------------------
++ */
++
++#include <sysdep.h>
++
++/*------------------------------------------------------------------
++ * int memcpy(const unsigned char* dst,
++ *            const unsigned char* src,
++ *            long count);
++ * void * memmove(const unsigned char* dst,
++ *                const unsigned char* src,
++ *                long count);
++ * Returns:
++ *  dst
++ *------------------------------------------------------------------
++ */
++
++#ifdef __MEMMOVE__
++	.file	"memmove.S"
++#else /* memcpy */
++	.file	"memcpy.S"
++#endif /* __MEMMOVE */
++	.section	".text"
++	.align 4
++#ifdef __MEMMOVE__
++	#define FUNCTION memmove
++#else /* memcpy */
++	#define FUNCTION memcpy
++#endif /* __MEMMOVE__ */
++EALIGN (FUNCTION, 5, 1)
++
++/* Prologs are different for memcpy and memmove.  memmove needs
++ * to handle the case where the buffers overlap correctly.
++ * memcpy does not.  In order to make the implementation simple,
++ * memmove ONLY copies backwards if it needs to, and only for as 
++ * much as is necessary to remove the overlap.
++ */
++#ifdef __MEMMOVE__
++        or r0,r4,r3
++        subf r9,r4,r3
++        mr r6,r3
++        subf r11,r9,r5
++        andi. r0,r0,7
++        rlwinm r9,r9,0,0,0
++        xor r0,r4,r6
++        bne L(memcpy_unaligned)
++
++        or. r11,r9,r11
++        bgt L(Handle_Overlap)
++
++/* memcpy is simpler */
++#else /* memcpy */
++
++        or r0,r4,r3
++        mr r6,r3
++        andi. r0,r0,7
++        xor r0,r4,r6
++        bne L(memcpy_unaligned)
++
++#endif /* __MEMMOVE__ */
++
++L(aligned_copy):
++        srwi. r12,r5,5
++        mtcrf 0x2,r5
++        mtcrf 0x1,r5
++        bne L(big_loop)
++
++L(try_two_doubles):
++        bf 27,L(try_one_double)
++        evldd r7,0(r4)
++        evstdd r7,0(r6)
++        evldd r8,8(r4)
++        addi r4,r4,16
++        evstdd r8,8(r6)
++        addi r6,r6,16
++
++L(try_one_double):
++        bf 28,L(try_word)
++        evldd r7,0(r4)
++        addi r4,r4,8
++        evstdd r7,0(r6)
++        addi r6,r6,8
++
++L(try_word):
++        bf 29,L(try_half)
++        lwz r7,0(r4)
++        addi r4,r4,4
++        stw r7,0(r6)
++        addi r6,r6,4
++
++L(try_half):
++        bf 30,L(try_byte)
++        lhz r7,0(r4)
++        addi r4,r4,2
++        sth r7,0(r6)
++        addi r6,r6,2
++
++L(try_byte):
++        bf 31,L(finish)
++        lbz r7,0(r4)
++        stb r7,0(r6)
++
++L(finish):
++        blr
++
++L(big_loop):
++        evldd r7,0(r4)
++        addic. r12,r12,-1
++        evldd r8,8(r4)
++        evldd r9,16(r4)
++        evldd r10,24(r4)
++        addi r4,r4,32
++        evstdd r7,0(r6)
++        evstdd r8,8(r6)
++        evstdd r9,16(r6)
++        evstdd r10,24(r6)
++        addi r6,r6,32
++        bne L(big_loop)
++
++        b L(try_two_doubles)
++
++L(align_dest_word):
++L(align_dest_double):
++        /* First make sure there are at least 8 bytes left to
++	 * copy.  Otherwise, realignment could go out of bounds
++	 */
++        cmpwi r5,8
++        neg r0,r6
++        blt L(small_copy)
++
++        andi. r7,r6,0x3
++        mtcrf 0x1,r0
++
++        bne L(more_alignment)
++
++/* Don't need to check if r6 needs another word to be aligned.
++ * We're here, therefore we must have only been off by a word.
++ * So we shorten the path a bit by taking 2 branches out from the
++ * more common path (ie things tend to be at least word-aligned)
++ */
++L(align_one_word):
++        lwz r7,0(r4)
++        addi r4,r4,4
++        stw r7,0(r6)
++        addi r6,r6,4
++        addi r5,r5,-4
++        bne cr6,L(unaligned_double_copy)
++        b L(aligned_copy)
++
++L(more_alignment):
++        bf 31, L(try_align_word)
++        lbz r7,0(r4)
++        addi r4,r4,1
++        stb r7,0(r6)
++        addi r6,r6,1
++        addi r5,r5,-1
++
++L(try_align_word):
++        bf 30, L(try_align_double)
++        lhz r7,0(r4)
++        addi r4,r4,2
++        sth r7,0(r6)
++        addi r6,r6,2
++        addi r5,r5,-2
++
++L(try_align_double):
++        bt 29, L(align_one_word)
++        beq cr6,L(aligned_copy)
++
++/* For each double word copied, we load the double words with
++ * each half from r4 (which starts at 0x*4 or 0x*c).  Then we
++ * use evmergelohi to take the halves and rejoin them.  Notice
++ * that any double load will necessarily be 4 bytes ahead.
++ * Invariant: at the start of any block (except the first) which
++ * loads a doubleword, r10 will hold the first half of the
++ * first doubleword
++ */
++L(unaligned_double_copy):
++        /* align r4 to a doubleword boundary */
++        rlwinm r4,r4,0,0,28
++        srwi. r12, r5,5
++
++        /* grab the first doubleword */
++        evldd r10,0(r4)
++
++	/* Set the CR to indicate how many bytes remain to be
++	 * copied after the big loop is done */
++        mtcrf 0x2,r5
++        mtcrf 0x1,r5
++        bne L(unaligned_big_loop)
++
++/* There are less than 4 double words left, so we take care of
++ * them
++ */
++L(try_unaligned_2_doubles):
++        bf 27, L(try_unaligned_double)
++        evldd r9,8(r4)
++        evmergelohi r10,r10,r9
++        evstdd r10,0(r6)
++        evldd r10,16(r4)
++        addi r4,r4,16
++        evmergelohi r9,r9,r10
++        evstdd r9,8(r6)
++        addi r6,r6,16
++
++L(try_unaligned_double):
++        bf 28, L(try_unaligned_word)
++        evldd r9,8(r4)
++        addi r4,r4,8
++        evmergelohi r10,r10,r9
++        evstdd r10,0(r6)
++        addi r6,r6,8
++        evmr r10,r9
++
++L(try_unaligned_word):
++        addi r4,r4,4
++        bf 29, L(try_unaligned_half)
++        stw r10,0(r6)
++        addi r4,r4,4
++        addi r6,r6,4
++
++L(try_unaligned_half):
++        bf 30, L(try_unaligned_byte)
++        lhz r10,0(r4)
++        addi r4,r4,2
++        sth r10,0(r6)
++        addi r6,r6,2
++
++L(try_unaligned_byte):
++        bf 31, L(finish)
++        lbz r10,0(r4)
++        stb r10,0(r6)
++        blr
++
++L(unaligned_big_loop):
++        evldd r7,8(r4)
++        evldd r8,16(r4)
++        addic. r12,r12,-1
++        evldd r9,24(r4)
++        addi r4,r4,32
++        evmergelohi r10,r10,r7
++        evstdd r10,0(r6)
++        evmergelohi r7,r7,r8
++        evldd r10,0(r4)
++        evmergelohi r8,r8,r9
++        evstdd r7,8(r6)
++        evmergelohi r9,r9,r10
++        evstdd r8,16(r6)
++        evstdd r9,24(r6)
++        addi r6,r6,32
++        bne L(unaligned_big_loop)
++        b L(try_unaligned_2_doubles)
++
++
++L(small_copy):
++        mtcrf 0x1,r5
++        bf 29,L(try_small_half)
++        lbz r7,0(r4)
++        lbz r8,1(r4)
++        lbz r9,2(r4)
++        lbz r10,3(r4)
++        addi r4,r4,4
++        stb r7,0(r6)
++        stb r8,1(r6)
++        stb r9,2(r6)
++        stb r10,3(r6)
++        addi r6,r6,4
++
++L(try_small_half):
++        bf 30,L(try_small_byte)
++        lbz r7,0(r4)
++        lbz r8,1(r4)
++        addi r4,r4,2
++        stb r7,0(r6)
++        stb r8,1(r6)
++        addi r6,r6,2
++
++L(try_small_byte):
++        bf 31, L(finish)
++        lbz r7,0(r4)
++        stb r7,0(r6)
++        blr
++
++L(memcpy_unaligned):
++#ifdef __MEMMOVE__
++
++        or. r11,r9,r11
++        bgt L(Handle_Overlap)
++
++L(choose_alignment):
++#endif /* __MEMMOVE */
++        /* If both pointers can be double-aligned, align r6,
++	 * setting eq6 to indicate "aligned
++	 */
++        rlwinm. r0,r0,0,29,31
++        cmpw cr6,r31,r31 /* set eq6 */
++
++        /* Look at r6 to see if we're aligned already (but not
++	 * both aligned, which is why we're here)
++	 */
++        rlwinm r7,r6,0,29,31
++        beq L(align_dest_double)
++
++        /* Compare to find out if r6 is already doublealigned
++	 * If both pointers can be word-aligned, align r6,
++	 * clearing eq6 to indicate unaligned
++	 */
++        rlwinm. r0,r0,0,30,31
++        cmpwi cr1,r7,0
++
++        /* Only skip to unaligned_double_copy if r6 is aligned,
++	 * AND r0 indicates word-alignment
++	 */
++        crand 6,6,2
++
++        crxor 26,26,26 /* clear eq6 */
++        beq cr1,L(unaligned_double_copy)
++        beq L(align_dest_word)
++
++        /* Before we hop into bytewise copying, make sure that
++	 * there are bytes to copy (don't want to loop 4 billion+
++	 * times!
++	 */
++        cmpwi r5,0
++        beqlr
++
++        /* Well, alignment is just icky, copy bytewise */
++        mtctr r5
++L(byte_copy):
++        lbz r7,0(r4)
++        addi r4,r4,1
++        stb r7,0(r6)
++        addi r6,r6,1
++        bdnz L(byte_copy)
++        blr
++
++#ifdef __MEMMOVE__
++
++
++        /* If the regions being copied overlap, and r4 is lower
++	 * in memory than r6, then we need to copy backward
++	 * until the overlap is gone, then just do the normal
++	 * copy
++	 */
++L(Handle_Overlap):
++        /* r11 has the size of the overlap */
++        add r8,r6,r5
++        add r10,r4,r5
++
++        mtctr r11
++
++L(bkw_fix_loop):
++        lbzu r9,-1(r10)
++        stbu r9,-1(r8)
++        bdnz L(bkw_fix_loop)
++
++        /* We're done, correct r5, and return */
++        subf r5,r11,r5
++
++        b FUNCTION@local
++#endif /* __MEMMOVE */
++
++END (FUNCTION)
++libc_hidden_builtin_def (FUNCTION)
+diff -Naur libc/sysdeps/powerpc/powerpc32/e500/memmove.S libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/memmove.S
+--- libc/sysdeps/powerpc/powerpc32/e500/memmove.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/memmove.S	2014-08-01 06:42:29.703372001 -0500
+@@ -0,0 +1,2 @@
++#define __MEMMOVE__ 1
++#include <memcpy.S>
+diff -Naur libc/sysdeps/powerpc/powerpc32/e500/memset.S libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/memset.S
+--- libc/sysdeps/powerpc/powerpc32/e500/memset.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/memset.S	2014-08-01 06:44:25.470371998 -0500
+@@ -0,0 +1,393 @@
++/*------------------------------------------------------------------
++ * memset.S
++ *
++ * Standard memset function optimized for e500 using SPE
++ *
++ * Copyright (c) 2005 Freescale Semiconductor, Inc
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ *     * Redistributions of source code must retain the above copyright
++ *       notice, this list of conditions and the following disclaimer.
++ *     * Redistributions in binary form must reproduce the above copyright
++ *       notice, this list of conditions and the following disclaimer in the
++ *       documentation and/or other materials provided with the distribution.
++ *     * Neither the name of Freescale Semiconductor nor the
++ *       names of its contributors may be used to endorse or promote products
++ *       derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *------------------------------------------------------------------
++ */
++
++#include <sysdep.h>
++
++/*------------------------------------------------------------------
++ * void * memset(void *origdest, int value, size_t len)
++ *
++ * returns dest
++ *
++ *------------------------------------------------------------------
++ */
++
++
++	.file	"memset.S"
++	.section	".text"
++EALIGN (memset, 5, 0)
++        /* Find out whether the destination buffer is already
++	 * aligned, and propagate the byte through the entire
++	 * word.
++	 */
++        andi. r0,r3,0x7
++        rlwimi r4,r4,8,16,23
++
++        /* Check if value (r4) is zero (most common case).  If it
++	 * is, we jump to bzero
++	 */
++        cmpwi cr1,r4,0
++
++        rlwimi r4,r4,16,0,15
++
++        /* If r4 is 0, then we will jump to bzero.  If so,
++	 * we want the count to be in the right place for bzero (r4)
++	 */
++        mr r11,r4
++        mr r4,r5
++
++        beq cr1, L(bzero_entry)
++
++        mr r6,r3
++        bne L(align_dest_double)
++
++L(aligned_set):
++        /* Get the number of doubles/4, since we write 4 at a
++	 * time in the big loop.
++	 */
++        srwi. r12,r5,5
++
++        /* Set the condition register so that each bit represents
++	 * some number of bytes to set.
++	 */
++        mtcrf 0x2,r5
++        mtcrf 0x1,r5
++
++        /* Copy r11 up into the hi word, so we can set 8 bytes
++	 * at a time.
++	 */
++        evmergelo r11,r11,r11
++
++        /* If there aren't at least 32 bytes to set, take care of
++	 * the last 0-31
++	 */
++        bne L(big_loop)
++
++/* We only store to memory that we are changing.  No extra loads
++ * or stores are done.
++ */
++L(try_two_doubles):
++        bf 27,L(try_one_double)
++        evstdd r11,0(r6)
++        evstdd r11,8(r6)
++        addi r6,r6,16
++
++L(try_one_double):
++        bf 28,L(try_word)
++        evstdd r11,0(r6)
++        addi r6,r6,8
++        nop
++
++L(try_word):
++        bf 29,L(try_half)
++        stw r11,0(r6)
++        addi r6,r6,4
++        nop
++
++L(try_half):
++        bf 30,L(try_byte)
++        sth r11,0(r6)
++        addi r6,r6,2
++        nop
++
++L(try_byte):
++        bf 31,L(finish)
++        stb r11,0(r6)
++
++L(finish):
++        blr
++
++/* Write 32 bytes at a time */
++L(big_loop):
++        /* adjust r6 back by 8.  We need to do this so we can
++	 * hoist the pointer update above the last store in the
++	 * loop.  This means that a store can be done every cycle
++	 */
++        addi r6,r6,-8
++L(loop):
++        evstdd r11,8(r6)
++        addic. r12,r12,-1
++        evstdd r11,16(r6)
++        evstdd r11,24(r6)
++        addi r6,r6,32
++        evstdd r11,0(r6)
++        bne L(loop)
++
++        /* Readjust r6 */
++        addi r6,r6,8
++        /* Jump back to take care of the last 0-31 bytes */
++        b L(try_two_doubles)
++
++L(align_dest_double):
++        /* First make sure there are at least 8 bytes left to
++	 * set.  Otherwise, realignment could go out of bounds
++	 */
++        cmpwi cr1, r5,8
++
++        /* Find out how many bytes we need to set in order to
++	 * align r6
++	 */
++        neg r0,r6
++        andi. r7,r6,0x3
++
++        blt cr1, L(small_set)
++
++        /* Set the condition register so that each bit in cr7
++	 * represents a number of bytes to write to align r6
++	 */
++        mtcrf 0x1,r0
++
++        /* The most common case is that r6 is at least
++	 * word-aligned, so that is the fall-through case.
++	 * Otherwise, we skip ahead to align a bit more.
++	 */
++        bne L(more_alignment)
++L(align_one_word):
++        addi r5,r5,-4
++        stw r11,0(r6)
++        addi r6,r6,4
++        b L(aligned_set)
++
++L(more_alignment):
++        bf 31, L(try_align_word)
++        addi r5,r5,-1
++        stb r11,0(r6)
++        addi r6,r6,1
++
++L(try_align_word):
++        bf 30, L(try_align_double)
++        addi r5,r5,-2
++        sth r11,0(r6)
++        addi r6,r6,2
++
++L(try_align_double):
++        bt 29, L(align_one_word)
++        b L(aligned_set)
++
++L(small_set):
++        mtcrf 0x1,r5
++        bf 29,L(try_small_half)
++        /* This may be better, but stw SHOULD do the same thing
++	 * as fast or faster.  It just has a chance of being
++	 * unaligned
++	 *	stb	r11,0(r6)
++	 *	stb	r11,1(r6)
++	 *	stb	r11,2(r6)
++	 *	stb	r11,3(r6)
++	 */
++
++        stw r11,0(r6)
++        addi r6,r6,4
++
++L(try_small_half):
++        bf 30,L(try_small_byte)
++
++        /* Storing half should take the same or less time than
++	 * two stb, so we do that
++	 */
++        sth r11,0(r6)
++        addi r6,r6,2
++
++L(try_small_byte):
++        bf 31, L(finish)
++        stb r11,0(r6)
++        blr
++
++END (memset)
++libc_hidden_builtin_def (memset)
++
++EALIGN (bzero, 5, 0)
++L(bzero_entry):
++        /* Check dest's alignment (within a cache-line) */
++        neg r8,r3
++
++        /* r12, here, is the number of 128 byte chunks to
++	 * zero out.
++	 */
++        srwi r12,r4,7
++
++        /* Find out the number of bytes needed to copy to align
++	 * dest to a cacheline boundary
++	 */
++        andi. r8, r8,0x1f
++        cmpwi cr1,r12,0
++
++        /* bzero can be called from memset, so we want it to
++	 * return the same value memset would.  This doesn't hurt
++	 * anything, so we keep the old value of r3, and copy it
++	 * into another register which we are free to change.
++	 */
++        mr r6,r3
++
++        /* Jump to align r6 if it isn't already aligned */
++        bne L(align_dest_32)
++
++        /* r6 is aligned to a cache-line, so we can zero
++	 * out using dcbz if the buffer is large enough
++	 */
++L(zero_aligned):
++        /* set the cr bits for the last 0-127 bytes remaining */
++        mtcrf 0x1,r4
++        mtcrf 0x2,r4
++
++        li r10,-32
++        li r9,32
++        beq cr1,L(try_two_lines)
++
++        li r11,64
++
++L(zero_loop):
++        dcbz 0,r6
++        addic. r12,r12,-1
++        dcbz r9,r6
++        dcbz r11,r6
++        addi r6,r6,128
++        dcbz r10,r6
++        bne L(zero_loop)
++
++L(try_two_lines):
++        /* Put 0 into r11 such that memset can handle the last
++	 * 0-31 bytes (yay, instruction savings!)
++	 */
++        evsplati r11,0
++
++        rlwinm. r0, r4,0,27,31
++
++        bf 25, L(try_one_line)
++        dcbz 0,r6
++        dcbz r9,r6
++        addi r6,r6,64
++
++L(try_one_line):
++        bf 26, L(try_two_doubles)
++        dcbz 0,r6
++        addi r6,r6,32
++
++        bne L(try_two_doubles)
++        /* there weren't any bytes left, so we return */
++        blr
++
++L(align_dest_32):
++        /* move r8 into the crfields so that we can align
++	 * easily
++	 */
++        mtcrf 0x1,r8
++        mtcrf 0x2,r8
++
++        /* update the counter */
++        subf. r4,r8,r4
++
++        /* if r4 is not great enough to align r6, then we
++	 * zero in small amounts
++	 */
++        blt L(zero_small)
++
++        /* zero out a register to store to memory */
++        evsplati r8,0
++
++        bf 31,L(zero_one_half)
++        stb r8,0(r6)
++        addi r6,r6,1
++        nop
++
++L(zero_one_half):
++        bf 30, L(zero_word)
++        sth r8,0(r6)
++        addi r6,r6,2
++        nop
++
++L(zero_word):
++        bf 29, L(zero_double)
++        stw r8,0(r6)
++        addi r6,r6,4
++        nop
++
++L(zero_double):
++        bf 28, L(zero_two)
++        evstdd r8,0(r6)
++        addi r6,r6,8
++        nop
++
++L(zero_two):
++        bf 27,L(zero_finish)
++        evstdd r8,0(r6)
++        evstdd r8,8(r6)
++        addi r6,r6,16
++
++L(zero_finish):
++        srwi. r12,r4,7
++        li r9,32
++        li r11,64
++        li r10,-32
++
++        mtcrf 0x1,r4
++        mtcrf 0x2,r4
++        bne L(zero_loop)
++        b L(try_two_lines)
++
++L(zero_small):
++        add r4,r8,r4
++        mtcrf 0x1,r4
++        mtcrf 0x2,r4
++
++        evsplati r8,0
++
++        bf 27,L(zero_one_small)
++        stw r8,0(r6)
++        stw r8,4(r6)
++        stw r8,8(r6)
++        stw r8,12(r6)
++        addi r6,r6,16
++
++L(zero_one_small):
++        bf 28,L(zero_word_small)
++        stw r8,0(r6)
++        stw r8,4(r6)
++        addi r6,r6,8
++
++L(zero_word_small):
++        bf 29,L(zero_half_small)
++        stw r8,0(r6)
++        addi r6,r6,4
++
++L(zero_half_small):
++        bf 30,L(zero_byte_small)
++        sth r8,0(r6)
++        addi r6,r6,2
++
++L(zero_byte_small):
++        bf 31,L(finish)
++        stb r8,0(r6)
++
++        blr
++
++END (bzero)
++libc_hidden_builtin_def (bzero)
+diff -Naur libc/sysdeps/powerpc/powerpc32/e500/strcmp.S libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/strcmp.S
+--- libc/sysdeps/powerpc/powerpc32/e500/strcmp.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/strcmp.S	2014-08-01 06:44:54.397372002 -0500
+@@ -0,0 +1,685 @@
++/*------------------------------------------------------------------
++ * strcmp.S
++ * 
++ * Standard strcmp function optimized for e500 using SPE
++ *
++ * Copyright (c) 2005 Freescale Semiconductor, Inc
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ *     * Redistributions of source code must retain the above copyright
++ *       notice, this list of conditions and the following disclaimer.
++ *     * Redistributions in binary form must reproduce the above copyright
++ *       notice, this list of conditions and the following disclaimer in the
++ *       documentation and/or other materials provided with the distribution.
++ *     * Neither the name of Freescale Semiconductor nor the
++ *       names of its contributors may be used to endorse or promote products
++ *       derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *------------------------------------------------------------------
++ */
++
++#include <sysdep.h>
++
++/*------------------------------------------------------------------
++ * int strcmp(const unsigned char* sourceA,
++ *            const unsigned char* sourceB);
++ * Returns:
++ *  value < 0  if source1 < source2
++ *  value = 0  if source1 = source2
++ *  value > 0  if source1 > source2
++ *------------------------------------------------------------------
++ */
++
++	.file   "strcmp.S"
++	.section        ".text"
++/* If sourceA and sourceB are aligned the same wrt doublewords,
++ * or aligned the same wrt words, we compare in doublewords.
++ * Otherwise, go byte by byte.
++ */
++EALIGN (strcmp, 5, 0)
++
++        /* Load constant 0x01010101 */
++        lis r11,0x0101
++        ori r11,r11,0x0101
++
++        /* r3 will be used for returning stuff, so lets move
++	 * sourceA out of there
++	 */
++        mr r10,r3
++
++        /* Load doubleword constant 0x01010101 */
++        evmergelo r12,r11,r11
++
++        /* generate a mask to set the unwanted bits to 1
++	 * take the alignment of r10 * 8
++	 */
++        rlwinm r6, r10, 3, 27,28
++
++        /* Load doubleword constant 0x80808080 */
++        evslwi r11,r12,7
++
++        /* start the mask with all Fs */
++        li r8, -1
++
++        or r0,r10,r4
++
++        subfic r6, r6, 32
++
++        andi. r0,r0,0x7
++
++        /* Shift r8 by r6 to mask off preceding bytes */
++        slw r8, r8, r6
++
++        /* Save the stack, cuz we need to save a reg */
++        stwu r1, -32(r1)
++
++        /* save r14 for counting.  This is cheaper than bdnz */
++        stw r14, 8(r1)
++
++        beq L(Aligned_Double)
++
++/* load the first words (on word boundaries) and process them,
++ * setting bits preceding the first byte to 1.
++ */
++
++        /* If r10 and r4 can't be aligned to words, then jump
++	 * to unaligned compare
++	 */
++        xor r0,r10,r4
++        rlwinm. r0,r0,0,30,31
++        bne L(unaligned_compare)
++
++        /* align r10 to word */
++        rlwinm r10, r10, 0,0,29
++
++        /* process the first word, and word align r4 */
++        lwz r5, 0(r10)
++        rlwinm r4, r4, 0,0,29
++
++        /* Check whether r10 and r4 are both aligned double or not.
++	 * Jump to Unaligned_Double if they are different.
++	 */
++        xor r0,r10,r4
++        addi r10, r10, 4
++
++        /* Load the other first word (B), and set all the bits
++	 * preceding the first real byte
++	 */
++        lwz r7, 0(r4)
++        or r5, r5, r8
++
++        /* This will be 0b100 if the ptrs are only word aligned
++	 * (not doubleword aligned)
++	 */
++        rlwinm r0,r0,0,29,29
++
++        /* Look for nulls in the first (partial) word */
++        subfc r3, r12, r5
++        andc r9, r11, r5
++
++        /* Update r4, and find out if there were any nulls */
++        addi r4,r4,4
++        and. r9, r3, r9
++
++        /* Find out if we are doubleword aligned, and set all the
++	 * bits preceding the first byte in word B
++	 */
++        cmpwi 6, r0,0
++        or r7,r7,r8
++
++        /* jump out if we found a null, otherwise compare the two words */
++        bne L(find_null1)
++        subfc. r0, r5, r7
++
++        /* Set a condition bit if r10 is not yet doubleword
++	 * aligned, and branch if the first words were different
++	 */
++        mtcrf 0x01,r10
++        bne L(found_diff_early)
++
++        /* process another word if necessary to align to a doubleword
++	 * boundary.
++	 */
++        bf 29, L(Check_Aligned_Double)
++
++        /* Load another word from each string, to align r10 to a
++	 * double word
++	 */
++        lwz r5, 0(r10)
++        addi r10, r10, 4
++        lwz r7, 0(r4)
++        addi r4,r4,4
++
++
++        /* Check for nulls and differences in the words */
++        subfc r3, r12, r5
++        andc r9, r11, r5
++        and. r9, r3, r9
++        bne L(find_null1)
++        subfc. r0, r5, r7
++        bne L(found_diff_early)
++
++        /* r10 is now aligned to a doubleword boundary, but it
++	 * may be that we are not both double aligned.  We set a
++	 * bit based on this earlier, so branch if it is set.
++	 */
++L(Check_Aligned_Double):
++        bne 6, L(Unaligned_Double)
++
++        /* loop through 2 doublewords at once in this page, until one of
++	 * these happens:
++	 * 1) A null byte is found in r10
++	 * 2) a byte is found which is different between r10 and r4
++	 * 3) the end of the page is reached
++	 * 
++	 * If 3 happens, then we finish processing the last doubleword in
++	 * the page, and if it checks out, we jump to the next one.  The
++	 * hope is that no small strings are going to cross page
++	 * boundaries.  For large strings, the hit should be minimal
++	 *
++	 * If 1 happens, some extra checking goes on to see whether the
++	 * strings are the same or not.
++	 */
++L(Aligned_Double):
++        /* Start figuring out how far to the next page */
++        not r6,r10
++        not r8,r4
++
++        rlwinm r6,r6,29,23,31
++        rlwinm r8,r8,29,23,31
++
++        subfc. r0,r6,r8
++        evldd r5, 0(r10)
++
++        /* zero out a reg for comparison (the result of the final
++	 * and is nonzero for any word with a null byte)
++	 */
++        evsplati r0,0
++        evldd r7, 0(r4)
++
++        /* Select the shortest distance to the page */
++        isellt r14,r8,r6
++
++        evsubfw r3, r12, r5
++        addic. r14,r14,-6
++
++        evandc r9, r11, r5
++
++        blt L(aligned_double_loop_end)
++
++        /* The loop */
++L(aligned_double_loop):
++        evldd r6, 8(r10)
++        evand r9, r9, r3
++        addi r10,r10,16
++        evcmpgtu 1, r9, r0
++        evldd r8, 8(r4)
++        evcmpeq 6, r5, r7
++        bt 6, L(found_null1)
++        evsubfw r3,r12, r6
++        bf 27, L(found_diff1)
++        evandc r9, r11, r6
++        evldd r5, 0(r10)
++        evand r9,r9,r3
++        addi r4,r4,16
++        evcmpgtu 5, r9, r0
++        evldd r7, 0(r4)
++        evcmpeq 7, r6, r8
++        bt 22, L(found_null2)
++        evsubfw r3, r12, r5
++        bf 31, L(found_diff2)
++        evandc r9, r11, r5
++
++        evldd r6, 8(r10)
++        evand r9, r9, r3
++        addi r10,r10,16
++        evcmpgtu 1, r9, r0
++        evldd r8, 8(r4)
++        evcmpeq 6, r5, r7
++        bt 6, L(found_null1)
++        evsubfw r3,r12, r6
++        bf 27, L(found_diff1)
++        evandc r9, r11, r6
++        evldd r5, 0(r10)
++        evand r9,r9,r3
++        addi r4,r4,16
++        evcmpgtu 5, r9, r0
++        evldd r7, 0(r4)
++        evcmpeq 7, r6, r8
++        bt 22, L(found_null2)
++        evsubfw r3, r12, r5
++        bf 31, L(found_diff2)
++        addic. r14,r14,-4
++        evandc r9, r11, r5
++        bge L(aligned_double_loop)
++
++        /* we exited the loop, we must be at the end of a page.
++	 * Finish the last one, and then see if we are done or
++	 * not.
++	 */
++L(aligned_double_loop_end):
++        evand r9, r9, r3
++        evcmpgtu 1, r9, r0
++        evcmpeq 6, r5, r7
++        bt 6, L(found_null1)
++        bf 27, L(found_diff1)
++        addi r10,r10,8
++        addi r4,r4,8
++
++        or r3, r10,r4
++        andi. r3, r3, 0xFFF
++        beq L(find_next_page)
++        /* We need to check the next doubleword, too.  It may be
++	 * in the next page, but it may be the last one in this
++	 * page.
++	 */
++        li r14,3
++L(find_page_end):
++        evldd r5, 0(r10)
++        addi r10,r10,8
++        evldd r7, 0(r4)
++        addi r4,r4,8
++        evsubfw r3, r12, r5
++        addic. r14,r14,-1
++        evandc r9, r11, r5
++        evand r9, r9, r3
++        evcmpgtu 1, r9, r0
++        evcmpeq 6, r5, r7
++        bt 6, L(found_null1)
++        bf 27, L(found_diff1)
++        bne L(find_page_end)
++
++
++        /* It is now safe to proceed to the next page.  load the
++	 * counter with the number of doublewords before the next
++	 * page
++	 */
++
++L(find_next_page):
++        not r6,r10
++        not r8,r4
++        rlwinm r6,r6,29,23,31
++        rlwinm r8,r8,29,23,31
++        subfc. r0,r6,r8
++        isellt r14,r8,r6
++        evldd r5, 0(r10)
++        addic. r14,r14,-6
++        evldd r7, 0(r4)
++        evsubfw r3, r12, r5
++        evandc r9, r11, r5
++        evsplati r0, 0
++        blt L(aligned_double_loop_end)
++        b L(aligned_double_loop)
++
++        /* The first doubleword had a null byte */
++L(found_unaligned_null1):
++        evmr r7,r15
++        evldd r15, 16(r1)
++L(found_null1):
++        /* If there was a null in the hi word, or if the hi words
++	 * were not equal, we want to check the hi word, so move
++	 * it down into the lo word
++	 */
++        crorc 4,4,24 
++        bf 4, L(find_null1)
++        evmergehi r5, r5, r5
++        evmergehi r7,r7,r7
++L(find_null1):
++        rlwinm. r11,r5,0,0,7
++        li r12,24
++        beq L(aligned_shift1)
++        rlwinm. r11,r5,0,8,15
++        li r12,16
++        beq L(aligned_shift1)
++        rlwinm. r11,r5,0,16,23
++        li r12,8
++        beq L(aligned_shift1)
++        li r12,0
++
++        /* If the signs are different for these words,
++	 * then overflow can occur
++	 */
++        xor. r0,r5,r7
++
++L(aligned_shift1):
++        srw r5,r5,r12
++        srw r7,r7,r12
++        lwz r14, 8(r1)
++        subfc r3,r7,r5
++        addi r1,r1,32
++
++        /* return now if the signs were the same (r3
++	 * has the appropriate value).  Otherwise, return
++	 * r7.  r7's sign matches that of the necessary
++	 * return value, since the comparison is actually
++	 * unsigned.  This means that a negative number is
++	 * actually large, and, if the signs are different,
++	 * guaranteed to be larger than r5. The same is true
++	 * for the opposite case.  We also make sure it is
++	 * non-zero.
++	 */
++        bgelr
++        ori r3,r7,1
++        blr
++
++L(found_unaligned_null2):
++        evmr r8,r15
++        evldd r15, 16(r1)
++L(found_null2):
++        /* If there was a null in the hi word, move that word
++	 * down into the lo word
++	 */
++        evmr r5,r6
++        crorc 20, 20, 28 
++        evmr r7,r8
++        bf 20, L(find_null1)
++        evmergehi r5, r5, r5
++        evmergehi r7, r7, r7
++        b L(find_null1)
++
++/* Now we know that there is a difference in one of the
++   two doublewords.  We find the first different bit within
++   each word, and then rotate each word of B so that the sign
++   bit is that bit.  When B is greater, that bit will be one, and
++   the sign of the return should be negative, and when B is less,
++   the bit will be zero, making the return positive.  Also,
++   we need to OR the r3 with 1 to make sure it is non-zero
++ */
++L(found_unaligned1):
++        evmr r7,r15
++        evldd r15, 16(r1)
++L(found_diff1):
++        evxor r0,r5,r7
++        lwz r14,8(r1)
++        evcntlzw r0,r0
++        addi r1,r1,32
++        evrlw r3,r7,r0
++        evmergehi r4,r3,r3
++        isel r3,r3,r4,24
++        ori r3,r3,1
++        blr
++
++/* See found_diff1 description for explanation of this code */
++L(found_unaligned2):
++        evmr r8,r15
++        evldd r15, 16(r1)
++L(found_diff2):
++        evxor r0,r6,r8
++        lwz r14,8(r1)
++        evcntlzw r0,r0
++        addi r1,r1,32
++        evrlw r3,r8,r0
++        evmergehi r4,r3,r3
++        isel r3,r3,r4,28
++        ori r3,r3,1
++        blr
++
++L(Unaligned_Double):
++        /* Invert the pointers so that the last 12 bits hold the
++	 * number of bytes to the end of the page (minus 1)
++	 */
++        not r6,r10
++        not r8,r4
++
++        /* remove all but the last 12 bits from the nots, and
++	 * shift the result right by 3, thus making it the number
++	 * of doubles to the end of the page
++	 */
++        rlwinm r6,r6,29,23,31
++        rlwinm r8,r8,29,23,31
++
++        /* align r4 to a doubleword boundary, and load the
++	 * first double of r10 (prologue for loop)
++	 */
++        rlwinm r4,r4,0,0,28
++        evldd r5, 0(r10)
++
++        /* subtract the distances from each other, setting the
++	 * condition code so we know which was shorter.
++	 * And load the first word of r4 into a doubleword
++	 */
++        subfc. r0,r6,r8
++        evldd r7, 0(r4)
++
++        /* zero out a reg for comparison (the result of the final
++	 * and is nonzero for any word with a null byte)
++	 * Save off a register for merging into
++	 */
++        evsplati r0,0
++        evstdd r15,16(r1)
++
++        /* And start looking for nulls in r10 */
++        evsubfw r3, r12, r5
++
++        /* Select the shortest distance to the page */
++        isellt r14,r8,r6
++
++        /* And continue looking for nulls */
++        evandc r9, r11, r5
++
++        /* We want to jump out early (before we load the next
++	 * double) if this is the last double.
++	 * Then update r14 so that it reflects the number of
++	 * doublewords that will have been loaded by the end
++	 * of the first iteration of the loop (4)
++	 */
++        cmpwi cr1,r14,1
++
++        addic. r14,r14,-4
++
++        /* Can't do this load until we know the previous one is
++	 * free of null bytes
++	 */
++        blt cr1,L(unaligned_last_was_first)
++        evldd r8, 8(r4)
++
++        /* Align the first double,  and branch over the loop if
++	 * we are less than 3 doubles from the end of the page
++	 */
++        evmergelohi r15,r7,r8
++        blt L(unaligned_double_loop_end)
++
++        /* And away we go!  Loop as many times as we can before
++	 * we hit the end of the page.  This code is scheduled
++	 * such that there are no stalls in execution.  Because
++	 * loads take 3 cycles, there could be stalls in
++	 * completion.
++	 * NOTE TO SELF:
++	 *
++	 * Issues:
++	 * 1) evmergelohi must be before any connected branch.
++	 *   the exit cases (found_null1, etc) assume that the
++	 *   values are all properly lined up.
++	 * 2) null case must branch before diff case.  diff
++	 *    assumes it to be so
++	 * 3) When near the end of the page, have to make sure
++	 *    that the hi word of r10, and the lo word of r4
++	 *    don't have any nulls before grabbing the next double
++	 *    for r4
++	 */
++L(unaligned_loop):
++        evcmpeq 6, r5,r15
++        evldd r6, 8(r10)
++        evand r9,r9,r3
++        addi r10,r10,16
++        evcmpgtu 1,r9, r0
++        evldd r7, 16(r4)
++        evsubfw r3,r12,r6
++        bt 6,L(found_unaligned_null1)
++        evandc r9,r11,r6
++        bf 27,L(found_unaligned1)
++        evmergelohi r15,r8,r7
++        addi r4,r4,16
++        evcmpeq 7,r6,r15
++        evldd r5,0(r10)
++        evand r9,r9,r3
++        addic. r14,r14,-2
++        evcmpgtu 5,r9, r0
++        evldd r8,8(r4)
++        evsubfw r3,r12,r5
++        bt 22,L(found_unaligned_null2)
++        evandc r9,r11,r5
++        bf 31,L(found_unaligned2)
++        evmergelohi r15,r7,r8
++        bge L(unaligned_loop)
++
++        /* we exited the loop, we must be at the end of a page.
++	 * Finish the last one, and then see if we are done or
++	 * not.
++	 */
++L(unaligned_double_loop_end):
++        evcmpeq 6, r5, r15
++        evand r9,r9,r3
++        evcmpgtu 1, r9, r0
++        addi r10,r10,8
++        bt 6, L(found_unaligned_null1)
++        addi r4,r4,8
++        bf 27, L(found_unaligned1)
++
++        /* We need to check the next doubleword, too.  It may be
++	 * in the next page, but it may be the last one in this
++	 * page.
++	 */
++L(unaligned_find_page_end):
++        evldd r6, 0(r10)
++        addi r10,r10,8
++        evsubfw r3, r12, r6
++        evandc r9, r11, r6
++        evand r9, r9, r3
++        evcmpgtu 5, r9, r0
++        bt 20,L(found_early_null2)
++
++        /* Check r8 */
++        evsubfw r3, r12,r8
++        evandc r9, r11,r8
++        evand r9,r9,r3
++        evcmpgtu 1,r9,r0
++        bt 6,L(found_early_null2)
++        evldd r7, 8(r4)
++        addi r4,r4,8
++        evmergelohi r15,r8,r7
++        evcmpeq 7, r6, r15
++        bt 22, L(found_unaligned_null2)
++        bf 31, L(found_unaligned2)
++
++
++        /* At this point, we will have crossed a page boundary in
++	 * one of the strings safely.  However, the other string
++	 * could be near the end of the page.  So we calculate
++	 * which string is closest to the end of the page again,
++	 * and redo the end of page code if it is less than 3
++	 * doublewords from the end.
++	 */
++L(unaligned_find_next_page):
++        not r6,r10
++        not r8,r4
++        rlwinm r6,r6,29,23,31
++        rlwinm r8,r8,29,23,31
++        subfc. r0,r6,r8
++        evldd r5, 0(r10)
++        evsplati r0,0
++        isellt r14,r8,r6
++        cmpwi cr1,r14,1
++        evsubfw r3, r12, r5
++        addic. r14,r14,-3
++        evandc r9, r11, r5
++        blt cr1,L(unaligned_last_was_first)
++        evldd r8, 8(r4)
++        evmergelohi r15,r7,r8
++        blt L(unaligned_double_loop_end)
++        b L(unaligned_loop)
++
++/* The end of the page happened so early, we couldn't load more
++ * than one doubleword safely.
++ * We need to make sure both CURRENTLY LOADED doublewords are
++ * null-free, since either one could be the one at the end of the
++ * page.
++ */
++L(unaligned_last_was_first):
++        evand r9,r9,r3
++        addi r10,r10,8
++        evcmpgtu 1,r9,r0
++        bt 4,L(found_early_null)
++
++        /* now check r7 */
++        evsubfw r3,r12,r7
++        evandc r9,r11,r7
++        evand r9,r3,r9
++        evcmpgtu 5,r9,r0
++        bt 22,L(found_early_null)
++
++        /* Now load the next 2 words of r4, and realign the
++	 * data to r10.  Then branch out if any of the bytes
++	 * were null.
++	 */
++        evldd r8,8(r4)
++        addi r4,r4,8
++        evmergelohi r15,r7,r8
++        evcmpeq 6,r5,r15
++        bt 6,L(found_unaligned_null1)
++        bf 27, L(found_unaligned1)
++
++        /* unaligned_find_next_page expects the previous
++	 * doubleword to be in r7, so move r8 there
++	 */
++        evmr r7,r8
++
++        /* find out where the next page is */
++        b L(unaligned_find_next_page)
++
++/* We found a null in the hi word of r5, near the end of the
++ * page.  r7 has the value we want to deal with, but we want
++ * the important word in A to be in the lo word.  So we merge
++ */
++L(found_early_null):
++        evmergehi r5,r5,r5
++        evldd r15,16(r1)
++        b L(find_null1)
++
++L(found_early_null2):
++        evmergehi r5,r6,r6
++        evldd r15,16(r1)
++        evmr r7,r8
++        b L(find_null1)
++
++L(unaligned_compare):
++        lbz r5, 0(r10)
++        lbz r7, 0(r4)
++        lwz r14, 8(r1)
++        addi r1,r1,32
++        subfc. r3, r7, r5
++        bnelr
++L(unaligned_byte_loop):
++        cmpwi cr1, r5,0
++        beq cr1, L(Null_Byte)
++        lbzu r5,1(r10)
++        lbzu r7,1(r4)
++        subfc. r3,r7,r5
++        beq L(unaligned_byte_loop)
++        blr
++L(Null_Byte):
++        li r3,0
++        blr
++
++L(found_diff_early):
++        subfe r3,r0,r0
++        not r3,r3
++        ori r3,r3,1
++        lwz r14, 8(r1)
++        addi r1,r1,32
++        blr
++
++END (strcmp)
++libc_hidden_builtin_def (strcmp)
+diff -Naur libc/sysdeps/powerpc/powerpc32/e500/strcpy.S libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/strcpy.S
+--- libc/sysdeps/powerpc/powerpc32/e500/strcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/strcpy.S	2014-08-01 06:45:17.052372002 -0500
+@@ -0,0 +1,665 @@
++/*------------------------------------------------------------------
++ * strcpy.S
++ * 
++ * Standard strcpy function optimized for e500 using SPE
++ *
++ * Copyright (c) 2005 Freescale Semiconductor, Inc
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ *     * Redistributions of source code must retain the above copyright
++ *       notice, this list of conditions and the following disclaimer.
++ *     * Redistributions in binary form must reproduce the above copyright
++ *       notice, this list of conditions and the following disclaimer in the
++ *       documentation and/or other materials provided with the distribution.
++ *     * Neither the name of Freescale Semiconductor nor the
++ *       names of its contributors may be used to endorse or promote products
++ *       derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *------------------------------------------------------------------
++ */
++
++#include <sysdep.h>
++
++/*------------------------------------------------------------------
++ * char * strcpy(char* dest, const char* src);
++ * Returns:
++ * dest
++ *------------------------------------------------------------------
++ */
++
++	.file   "strcpy.S"
++	.section        ".text"
++/* If dest and src are aligned the same wrt doublewords,
++ * or aligned the same wrt words, we copy in doublewords.
++ * Otherwise, go byte by byte.
++ */
++EALIGN (strcpy, 5, 0)
++
++        /* All of the string functions use an algorithm for null
++	 * detection taken from the original libmoto:
++	 *
++	 * 1) load in a word
++	 * 2a) subtract 0x01010101 from the word.  This will cause
++	 * all bytes with a null to be 0xff (unless it is right
++	 * before another null, in which case it will be 0xfe)
++	 *
++	 * 3b) AND 0x80808080 with the complement of the word.
++	 * The resulting bytes will only have their high bit set
++	 * if the corresponding bit was 0 in the original word
++	 *
++	 * So now we (basically) have a word with the high bit of
++	 * any byte set which was between 0x81 and 0xff, or 0x00.
++	 * We also have a mask which will only select the high
++	 * bits of bytes which were between 0x00 and 0x7f.  There
++	 * is only one overlap:  a null byte (0x00).  If we now:
++	 *
++	 * 4) and the two results
++	 *
++	 * The result will only have 1s in the high bits of bytes
++	 * which had nulls.  With one exception.  If there is a
++	 * byte with 0x01 before a byte with 0x00, then that
++	 * byte, too, will have a 1 in the high bit.  However,
++	 * since this only happens when a byte with 0x00 occurs
++	 * in the word, this technique is useful for detecting if
++	 * there are any nulls in the word.
++	 */
++
++        /* r3 needs to return the original dest, but r3 is used,
++	 * so move r3 into the upper half of r10
++	 */
++        evmergelo r10,r3,r3
++
++        /* Load constant 0x01010101 */
++        lis r11,0x0101
++        ori r11,r11,0x0101
++
++        /* Load doubleword constant 0x01010101 */
++        evmergelo r12,r11,r11
++
++        /* Determine whether r4 and r10 are doubleword-aligned */
++        or r0,r10,r4
++
++        /* Load doubleword constant 0x80808080 */
++        evslwi r11,r12,7
++
++        /* Save the stack, cuz we need to save a reg */
++        stwu r1, -16(r1)
++
++        andi. r0,r0,0x7
++
++        /* save r14.  This is cheaper than bdnz */
++        stw r14, 8(r1)
++
++        beq L(Aligned_Double)
++
++/* load the first words (on word boundaries) and process them,
++ * setting bits preceding the first byte to 1.
++ */
++
++        /* If r10 and r4 are off by 4, we can handle that almost
++	 * as fast as in the fully-aligned case, so we want to go
++	 * there as soon as possible.  If this is true, then
++	 * r0 will be 4.  The Unaligned_Double loop needs
++	 * r10 to be double-aligned, so we move bit 29 of r10
++	 * into bit 29 of r0, and if r0 is then zero,
++	 * r10 is already properly aligned, and we jump to
++	 * Unaligned_Double.
++	 */
++        rlwimi. r0,r10,0,29,29
++        not r6, r10
++        xor r0,r10,r4
++        beq L(Unaligned_Double)
++
++        /* If the last two bits of r4 and r10 are
++	 * different, then it is not efficient to copy
++	 * them in chunks larger than a byte
++	 */
++        andi. r14,r0,0x3
++        addi r6, r6, 1
++        bne L(unaligned_copy)
++
++        /* Check for double alignment */
++        rlwinm r0,r0,0,29,29
++
++        /* Move the alignment amount into the CR */
++        mtcrf 0x1, r6
++
++        /* Set the condition code for double alignment */
++        cmpwi 5, r0,0
++
++        /* Process a byte if r10 is only byte-aligned */
++        bf 31, L(try_halfword)
++        lbz r5, 0(r4)
++        addi r4,r4,1
++        cmpwi r5, 0
++        stb r5, 0(r10)
++        addi r10,r10,1
++        beq L(aligned_end1)
++
++        /* Process 2 bytes if r10 is only halfword aligned */
++L(try_halfword):
++        bf 30, L(try_word)
++        lbz r5, 0(r4)
++        lbz r6, 1(r4)
++        addi r4,r4,2
++        cmpwi r5, 0
++        stb r5, 0(r10)
++        beq L(aligned_end1)
++        cmpwi r6, 0
++        stb r6, 1(r10)
++        beq L(aligned_end1)
++        addi r10,r10,2
++
++        /* process another word if necessary to align to a doubleword
++	 * boundary.
++	 */
++L(try_word):
++        bf 29, L(Check_Aligned_Double)
++
++        /* Load the next word, to align r10 to a double word */
++        lwz r5, 0(r4)
++        addi r4,r4,4
++
++        /* Process it */
++        subfc r3, r12, r5
++        andc r9, r11, r5
++        and. r9, r3, r9
++
++        /* Need to have r5 in r0, because find_null1 assumes
++	 * that r0 will have the word in which the first null was
++	 * found.  (found_null1 assumes that condition codes have
++	 * been set by evcmpgtu, so we have to jump into that
++	 * block of code after the logic which figures out the
++	 * first word has been executed)
++	 */
++        mr r0,r5
++        bne L(find_null1)
++
++        /* Store the word */
++        stw r5,0(r10)
++        addi r10, r10, 4
++
++        /* r10 is now doubleword aligned, but both strings may
++	 * not be doubleword aligned.  We set a bit earlier for
++	 * this, so branch if it was set.
++	 */
++L(Check_Aligned_Double):
++        bne 5, L(Unaligned_Double)
++
++        /* loop through 2 doublewords at once in this page, until one of
++	 * these happens:
++	 * 1) A null byte is found in r4
++	 * 2) the end of the page is reached
++	 * 
++	 * If 2 happens, then we finish processing the last doubleword in
++	 * the page, and if it checks out, we jump to the next one.  The
++	 * hope is that no small strings are going to cross page
++	 * boundaries.  For large strings, the hit should be minimal
++	 *
++	 * If 1 happens, some extra checking goes on to see whether the
++	 * strings are the same or not.
++	 *
++	 * The primary loop is capable of 2 IPC (it issues
++	 * 2/cycle, but completion may stall).  If it gets 2 IPC,
++	 * then it is doing a load or store every other cycle.
++	 * This means that a doubleword is stored every fourth
++	 * cycle.  So the code will approach copying 2
++	 * bytes/cycle.  This is 2x what the optimized scalar
++	 * code can do.
++	 */
++L(Aligned_Double):
++        /* Start figuring out how far to the next page */
++        not r8,r4
++
++        evldd r5, 0(r4)
++
++        /* zero out a reg for comparison (the result of the final
++	 * and is nonzero for any word with a null byte)
++	 */
++        evsplati r0,0
++
++        rlwinm r8,r8,29,23,31
++
++        evsubfw r3, r12, r5
++
++        /* We will load 2 doublewords, but it could be that the
++	 * first null is in the the first double.
++	 * If this double is also the last in the page, then
++	 * loading the next double could cause a segmentation
++	 * fault.  So we check to see if this is the last, and if
++	 * so we jump to a special case.
++	 */
++        addic. r14, r8,-1
++        blt L(last_double_was_first)
++
++        evldd r6, 8(r4)
++        evandc r9, r11, r5
++
++        evand r9,r9,r3
++        addic. r14,r14,-5
++
++        evcmpgtu 1,r9,r0
++        evsubfw r3,r12, r6
++
++        blt L(aligned_double_loop_end)
++        /* The loop */
++L(aligned_double_loop):
++        evandc r9, r11, r6
++        evldd r7, 16(r4)
++        evand r9,r9,r3
++        bt 6, L(found_null1)
++        evcmpgtu 5, r9, r0
++        evstdd r5,0(r10)
++        evsubfw r3, r12, r7
++        evldd r8, 24(r4)
++        evandc r9, r11, r7
++        bt 22, L(found_null2)
++        evand r9, r9, r3
++        evstdd r6,8(r10)
++        evcmpgtu 6, r9, r0
++        addic. r14,r14,-4
++        evsubfw r3,r12, r8
++        addi r4,r4,32
++        evandc r9, r11, r8
++        evldd r5, 0(r4)
++        evand r9, r9, r3
++        bt 26, L(found_null3)
++        evcmpgtu 7, r9, r0
++        evstdd r7,16(r10)
++        evsubfw r3,r12, r5
++        evldd r6, 8(r4)
++        evandc r9, r11, r5
++        bt 30, L(found_null4)
++        evand r9, r9, r3
++        evstdd r8,24(r10)
++        evcmpgtu 1, r9, r0
++        addi r10,r10,32
++        evsubfw r3,r12, r6
++        bge L(aligned_double_loop)
++
++        /* we exited the loop, we must be at the end of a page.
++	 * Finish the last one, and then see if we are done or
++	 * not.
++	 */
++L(aligned_double_loop_end):
++        bt 6, L(found_null1)
++        evstdd r5, 0(r10)
++        evandc r9,r11,r6
++        evand r9,r9,r3
++        evcmpgtu 5,r9,r0
++        bt 22, L(found_null2)
++        evstdd r6, 8(r10)
++
++        addi r4,r4,16
++        addi r10,r10,16
++
++        andi. r3,r4,0xFFF
++        beq L(start_new_loop)
++
++L(find_page_end):
++        evldd r5,0(r4)
++        addi r4,r4,8
++        evsubfw r3, r12, r5
++        evandc r9, r11, r5
++        evand r9, r3, r9
++        andi. r3,r4,0xFFF
++        evcmpgtu 1, r9, r0
++        bt 6, L(found_null1)
++        evstdd r5, 0(r10)
++        addi r10,r10,8
++        bne L(find_page_end)
++
++L(start_new_loop):
++        /* It is now safe to proceed to the next page.  load the
++	 * r14 with the number of doublewords in a page 
++	 * (-6 to account for the first loop)
++	 */
++        evldd r5, 0(r4)
++        li r14, 505
++
++        /* Now we set up for the beginning of the loop */
++        evldd r6, 8(r4)
++        evsubfw r3, r12, r5
++        evandc r9, r11, r5
++        evand r9,r9,r3
++        evcmpgtu 1,r9,r0
++        evsubfw r3,r12,r6
++        b L(aligned_double_loop)
++
++L(last_double_was_first):
++        addi r4,r4,8
++        evandc r9,r11,r5
++        evand r9,r9,r3
++        evcmpgtu 1,r9,r0
++        bt 6, L(found_null1)
++        evstdd r5,0(r10)
++        addi r10,r10,8
++        b L(start_new_loop)
++
++
++        /* The first doubleword had a null byte */
++L(found_null1):
++        /* If there was a null in the hi word, move that word
++	 * down into the lo word
++	 */
++        evmergehi r0, r5, r5
++        bt 4, L(find_null1)
++        stw r0,0(r10)
++        addi r10,r10,4
++        mr r0,r5
++L(find_null1):
++        rlwinm. r11,r0,8,24,31
++        stb r11, 0(r10)
++        beq L(aligned_end1)
++        rlwinm. r11,r0,16,24,31
++        stb r11, 1(r10)
++        beq L(aligned_end1)
++        rlwinm. r11,r0,24,24,31
++        stb r11, 2(r10)
++        beq L(aligned_end1)
++        stb r0, 3(r10)
++
++L(aligned_end1):
++        evmergehi r3,r10,r10
++        lwz r14, 8(r1)
++        addi r1,r1,16
++        blr
++
++        /* The second doubleword had a null byte */
++L(found_null2):
++        /* If there was a null in the hi word, move that word
++	 * down into the lo word
++	 */
++        evmergehi r0, r6, r6
++        bt 20, L(find_null2)
++        stw r0,8(r10)
++        addi r10,r10,4
++        mr r0,r6
++L(find_null2):
++        rlwinm. r11,r0,8,24,31
++        stb r11, 8(r10)
++        beq L(aligned_end2)
++        rlwinm. r11,r0,16,24,31
++        stb r11, 9(r10)
++        beq L(aligned_end2)
++        rlwinm. r11,r0,24,24,31
++        stb r11, 10(r10)
++        beq L(aligned_end2)
++        stb r0, 11(r10)
++
++L(aligned_end2):
++        evmergehi r3,r10,r10
++        lwz r14, 8(r1)
++        addi r1,r1,16
++        blr
++
++        /* The third doubleword had a null byte */
++L(found_null3):
++        /* If there was a null in the hi word, move that word
++	 * down into the lo word
++	 */
++        evmergehi r0, r7, r7
++        bt 24, L(find_null3)
++        stw r0,16(r10)
++        addi r10,r10,4
++        mr r0,r7
++L(find_null3):
++        rlwinm. r11,r0,8,24,31
++        stb r11,16(r10)
++        beq L(aligned_shift3)
++        rlwinm. r11,r0,16,24,31
++        stb r11,17(r10)
++        beq L(aligned_shift3)
++        rlwinm. r11,r0,24,24,31
++        stb r11,18(r10)
++        beq L(aligned_shift3)
++        stb r0,19(r10)
++
++L(aligned_shift3):
++        evmergehi r3,r10,r10
++        lwz r14, 8(r1)
++        addi r1,r1,16
++        blr
++
++
++        /* The fourth doubleword had a null byte */
++L(found_null4):
++        /* If there was a null in the hi word, move that word
++	 * down into the lo word
++	 */
++        evmergehi r0, r8, r8
++        bt 28, L(find_null4)
++        stw r0,24(r10)
++        addi r10,r10,4
++        mr r0,r8
++L(find_null4):
++        rlwinm. r11,r0,8,24,31
++        stb r11,24(r10)
++        beq L(aligned_shift4)
++        rlwinm. r11,r0,16,24,31
++        stb r11,25(r10)
++        beq L(aligned_shift4)
++        rlwinm. r11,r0,24,24,31
++        stb r11,26(r10)
++        beq L(aligned_shift4)
++        stb r0,27(r10)
++
++L(aligned_shift4):
++        evmergehi r3,r10,r10
++        lwz r14, 8(r1)
++        addi r1,r1,16
++        blr
++
++L(found_unaligned_null1):
++        evmergehi r0,r7,r7
++        bt 24, L(find_unaligned_null1)
++        stw r0,0(r10)
++        addi r10,r10,4
++        mr r0,r7
++L(find_unaligned_null1):
++        rlwinm. r11,r0,8,24,31
++        stb r11, 0(r10)
++        beq L(unaligned_end1)
++        rlwinm. r11,r0,16,24,31
++        stb r11, 1(r10)
++        beq L(unaligned_end1)
++        rlwinm. r11,r0,24,24,31
++        stb r11, 2(r10)
++        beq L(unaligned_end1)
++        stb r0, 3(r10)
++
++L(unaligned_end1):
++        evmergehi r3,r10,r10
++        lwz r14, 8(r1)
++        addi r1,r1,16
++        blr
++
++L(found_unaligned_null2):
++        evmergehi r0,r8,r8
++        bt 28, L(find_unaligned_null2)
++        stw r0,8(r10)
++        addi r10,r10,4
++        mr r0,r8
++L(find_unaligned_null2):
++        rlwinm. r11,r0,8,24,31
++        stb r11, 8(r10)
++        beq L(unaligned_end2)
++        rlwinm. r11,r0,16,24,31
++        stb r11, 9(r10)
++        beq L(unaligned_end2)
++        rlwinm. r11,r0,24,24,31
++        stb r11, 10(r10)
++        beq L(unaligned_end2)
++        stb r0, 11(r10)
++
++L(unaligned_end2):
++        evmergehi r3,r10,r10
++        lwz r14, 8(r1)
++        addi r1,r1,16
++        blr
++
++L(Unaligned_Double):
++        /* Align r4 to doubleword.
++	 * Get number of bytes before end of page
++	 */
++        not r8,r4
++        rlwinm r4,r4,0,0,28
++
++        /* Load the first doubleword (only half of which is good) */
++        rlwinm r8,r8,29,23,31
++        evldd r6,0(r4)
++
++        /* We will load 2 doublewords, but it could be that the
++	 * first null is in the lower word of the first double.
++	 * If this double is also the last in the page, then
++	 * loading the next double could cause a segmentation
++	 * fault.  So we check to see if the word has any
++	 * nulls, and if so, we jump to a special case
++	 * And zero a register for comparison
++	 */
++        addic. r14,r8,-1
++        evsplati r0,0
++        addi r10,r10,-16 /* predecrement r10 */
++        blt L(unaligned_first_was_last)
++
++        evldd r5,8(r4)
++        addic. r14,r14,-5
++        evmergelohi r7,r6,r5
++        evsubfw r3,r12,r7
++        blt L(unaligned_loop_end)
++
++L(unaligned_double_loop):
++        evandc r9,r11,r7
++        evldd r6,16(r4)
++        evand r9,r9,r3
++        addi r4,r4,16
++        evcmpgtu 6,r9,r0
++        addi r10,r10,16
++        evmergelohi r8,r5,r6
++        bt 26, L(found_unaligned_null1)
++        evsubfw r3,r12,r8
++        evstdd r7,0(r10)
++        evandc r9,r11,r8
++        evldd r5,8(r4)
++        evand r9,r9,r3
++        addic. r14,r14,-4
++        evcmpgtu 7,r9,r0
++        evmergelohi r7,r6,r5
++        bt 30,L(found_unaligned_null2)
++        evsubfw r3,r12,r7
++        evstdd r8,8(r10)
++
++        evandc r9,r11,r7
++        evldd r6,16(r4)
++        evand r9,r9,r3
++        addi r4,r4,16
++        evcmpgtu 6,r9,r0
++        addi r10,r10,16
++        evmergelohi r8,r5,r6
++        bt 26,L(found_unaligned_null1)
++        evsubfw r3,r12,r8
++        evstdd r7,0(r10)
++        evandc r9,r11,r8
++        evldd r5,8(r4)
++        evand r9,r9,r3
++        evcmpgtu 7,r9,r0
++        bt 30,L(found_unaligned_null2)
++        evmergelohi r7,r6,r5
++        evstdd r8,8(r10)
++        evsubfw r3,r12,r7
++        bge L(unaligned_double_loop)
++
++/* Hit the end of the page, finish up the epilog of the loop, and
++ * then run the process without any special scheduling to get
++ * into the next page
++ */
++L(unaligned_loop_end):
++        evandc r9,r11,r7
++        addi r4,r4,16
++        evand r9,r9,r3
++        addi r10,r10,16
++        evcmpgtu 6,r9,r0
++        bt 26,L(found_unaligned_null1)
++        evstdd r7,0(r10)
++        addi r10,r10,8
++
++/* At this point, r4 and r10 point to the next place to load
++ * and store.  We move forward, one word at a time, until r4
++ * has passed over into a new page.
++ */
++L(unaligned_find_next_page):
++        /* Check this word for null bytes */
++        subf r3,r12,r5
++        andc r9,r11,r5
++        and. r9,r9,r3
++        mr r0,r5
++        bne L(find_null1)
++        stw r5,0(r10)
++        addi r10,r10,4
++
++        lwz r0,0(r4)
++        addi r4,r4,4
++        subf r3,r12,r0
++        andc r9,r11,r0
++        and. r9,r9,r3
++        bne L(find_null1)
++
++        /* Calculate if r4 is on a new page */
++        andi. r6,r4,0x0f00
++
++        /* Store the 2nd word */
++        stw r0,0(r10)
++        addi r10,r10,4
++
++        beq L(Unaligned_Double)
++        lwz r5,0(r4)
++        addi r4,r4,4
++        b L(unaligned_find_next_page)
++
++L(unaligned_first_was_last):
++        addi r10,r10,16
++        addi r4,r4,8
++        mr r5,r6
++        b L(unaligned_find_next_page)
++
++L(unaligned_copy):
++        lbz r5, 0(r4)
++        addi r10, r10, -1
++        cmpwi cr1,r5,0
++        beq cr1,L(Null_Byte1)
++L(unaligned_byte_loop):
++        lbzu r6,1(r4)
++        stbu r5,1(r10)
++        cmpwi cr1,r6,0
++        beq cr1,L(Null_Byte2)
++        lbzu r5,1(r4)
++        stbu r6,1(r10)
++        cmpwi cr1,r5,0
++        bne cr1, L(unaligned_byte_loop)
++
++L(Null_Byte1):
++        stb r5,1(r10)
++        b L(Byte_End)
++L(Null_Byte2):
++        stb r6, 1(r10)
++
++L(Byte_End):
++        /* r3 still has original r10 value */
++        lwz r14, 8(r1)
++        addi r1,r1,16
++        blr
++
++END (strcpy)
++libc_hidden_builtin_def (strcpy)
+diff -Naur libc/sysdeps/powerpc/powerpc32/e500/strlen.S libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/strlen.S
+--- libc/sysdeps/powerpc/powerpc32/e500/strlen.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-e500v2-lib/sysdeps/powerpc/powerpc32/e500/strlen.S	2014-08-01 06:45:39.755371998 -0500
+@@ -0,0 +1,342 @@
++/*------------------------------------------------------------------
++ * strlen.S
++ *
++ * Standard strlen function optimized for e500 using SPE
++ *
++ * Copyright (c) 2005 Freescale Semiconductor, Inc
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ *     * Redistributions of source code must retain the above copyright
++ *       notice, this list of conditions and the following disclaimer.
++ *     * Redistributions in binary form must reproduce the above copyright
++ *       notice, this list of conditions and the following disclaimer in the
++ *       documentation and/or other materials provided with the distribution.
++ *     * Neither the name of Freescale Semiconductor nor the
++ *       names of its contributors may be used to endorse or promote products
++ *       derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *------------------------------------------------------------------
++ */
++
++#include <sysdep.h>
++
++/*------------------------------------------------------------------
++ * int strlen(const char *src)
++ *
++ * Returns:
++ * length of string up to first null byte
++ *------------------------------------------------------------------
++ */
++
++	.file   "strlen.S"
++	.section        ".text"
++        /* check enough bytes to align the src pointer to a
++	 * doubleword boundary, and then run through the bytes
++	 * until a null is detected, adding up the length as we
++	 * go.
++	 */
++EALIGN (strlen, 5, 0)
++
++        /* All of the string functions use an algorithm for null
++	 * detection taken from the original libmoto:
++	 *
++	 * 1) load in a word
++	 * 2a) subtract 0x01010101 from the word.  This will cause
++	 * all bytes with a null to be 0xff (unless it is right
++	 * before another null, in which case it will be 0xfe)
++	 *
++	 * 3b) AND 0x80808080 with the complement of the word.
++	 * The resulting bytes will only have their high bit set
++	 * if the corresponding bit was 0 in the original word
++	 *
++	 * So now we (basically) have a word with the high bit of
++	 * any byte set which was between 0x81 and 0xff, or 0x00.
++	 * We also have a mask which will only select the high
++	 * bits of bytes which were between 0x00 and 0x7f.  There
++	 * is only one overlap:  a null byte (0x00).  If we now:
++	 *
++	 * 4) and the two results
++	 *
++	 * The result will only have 1s in the high bits of bytes
++	 * which had nulls.  With one exception.  If there is a
++	 * byte with 0x01 before a byte with 0x00, then that
++	 * byte, too, will have a 1 in the high bit.  However,
++	 * since this only happens when a byte with 0x00 occurs
++	 * in the word, this technique is useful for detecting if
++	 * there are any nulls in the word.
++	 */
++
++        /* Load constant 0x01010101 */
++        lis r11,0x0101
++        ori r11,r11,0x0101
++
++        /* r3 will be used for returning length, so lets move src
++	 * out of there to r10
++	 */
++        mr r10,r3
++
++        /* Get src's alignment (within a doubleword), and check
++	 * if it's zero
++	 */
++        andi. r3,r3,0x7
++
++        /* Load doubleword constant 0x01010101 */
++        evmergelo r12,r11,r11
++
++        /* Clear r0 out */
++        evsplati r0,0
++
++        /* get (the word alignment of r10) * 8 to shift a mask by the
++	 * number of bytes which are unused by r10
++	 * This is: clrlslwi r6,r10,30,3
++	 */
++        rlwinm r6, r10, 3, 27,28
++
++        /* Load doubleword constant 0x80808080 */
++        evslwi r11,r12,7
++
++        /* Skip out now if r10 was aligned. */
++        beq L(Aligned_Double)
++
++        subfic r6, r6, 32
++
++        /* start the mask with all Fs */
++        li r5, -1
++
++        /* Shift r8 by r6 to mask off preceding bytes */
++        slw r8, r5, r6
++
++        /* We want the result of r3+r10 to be a
++	 * doubleword-aligned value, so r3 will be -1*(r10)
++	 * alignment)
++	 */
++        neg r3,r3
++
++/* load the first words (on word boundaries) and process them,
++ * setting bits preceding the first byte to 1.
++ */
++
++        /* Grab the first doubleword of r10 */
++        evlddx r4,r3,r10
++
++        /* The loop is usually ahead by 16, and if we detect a
++	 * null, the exit code assumes that r3 is ahead by
++	 * 16, so we add 16 now, and can subtract 8 if there was
++	 * no null
++	 */
++        addi r3,r3,16
++
++        mtcrf 0x01,r10
++
++        evmergelo r0,r8,r0
++        cror 28,29,29
++
++        evmergelo r5,r5,r8
++
++        evsel r8,r5,r0,cr7
++
++        evsplati r0,0
++
++        /* Set the unwanted bytes of the source */
++        evor r4, r4, r8
++
++        /* Process fist doubleword with fun algorithm */
++        evsubfw r7, r12, r4
++        evandc r9, r11, r4
++        evand r9, r7, r9
++        evcmpgtu 1,r9,r0
++
++        /* Skip out if there was a null */
++        bt 6, L(found_null1)
++
++        /* There was no null; correct the length */
++        addi r3,r3,-8
++
++        /* loop through 2 doublewords at once in this page, until one of
++	 * these happens:
++	 * 1) A null byte is found in src
++	 * 2) the end of the page is reached
++	 * 
++	 * If 2 happens, then we finish processing the last doubleword in
++	 * the page, and if it checks out, we jump to the next one.  The
++	 * hope is that no small strings are going to cross page
++	 * boundaries.  For large strings, the hit should be minimal
++	 */
++
++        /* The main loop is unrolled, and software pipelined to
++	 * get as close to 2 IPC as possible.  This means it has
++	 * a prolog and epilog that need to be executed.  Prolog
++	 * is:
++	 * load, subtract
++	 */
++L(Aligned_Double):
++        /* Start figuring out how far to the next page */
++        not r8,r10
++        evlddx r4,r3,r10
++
++        /* Find the distance (in doublewords) from r10 to the end
++	 * of the page
++	 */
++        rlwinm r8,r8,29,23,31
++
++        /* Find out if this is the last double on the page */
++        addic. r6, r8,-1
++        addi r3,r3,8 /* increment the length */
++
++        /* start calculating now, since the loop needs this at
++	 * the beginning.
++	 */
++        evsubfw r7, r12, r4
++        beq L(aligned_double_loop_end)
++
++        /* decrement the counter to account for the first
++	 * iteration of the loop, and skip to the end if it turns
++	 * out we don't have enough doubles left for 1 iter.
++	 */
++        addic. r6,r6,-2
++        blt L(aligned_double_loop_end)
++        /* The loop */
++L(aligned_double_loop):
++        evandc r9, r11, r4
++        evlddx r5,r3,r10
++        evand r9,r9,r7
++        addi r3,r3,8
++        evcmpgtu 1, r9, r0
++        addic. r6,r6,-2
++        evsubfw r7,r12,r5
++        bt 6, L(found_null1)
++        evandc r9, r11, r5
++        evlddx r4,r3,r10
++        evand r9, r9, r7
++        addi r3,r3,8
++        evcmpgtu 5, r9, r0
++        bt 22, L(found_null2)
++        evsubfw r7,r12, r4
++        bge L(aligned_double_loop)
++
++        /* we exited the loop, we must be at the end of a page.
++	 * Finish the last one, and then see if we are done or
++	 * not.
++	 */
++L(aligned_double_loop_end):
++        evandc r9,r11,r4
++        evand r9,r9,r7
++        evcmpgtu 1,r9,r0
++
++        /* r3 has to be ahead by 16 in found_null, and is
++	 * only ahead by 8 right now, so we add 8 here
++	 */
++        addi r3,r3,8
++        bt 6, L(found_null1)
++
++        /* However, r3 needed to be only 8 ahead to load the
++	 * next doubleword, so take 8 away again
++	 */
++        addi r3,r3,-8
++
++        /* To make things nice, we finish off the remaining
++	 * doublewords here, so that the next loop has exactly
++	 * 512 iterations
++	 */
++        addi r7, r10, r3
++        andi. r7,r7,0xFFF
++        beq L(start_new_loop)
++L(find_page_end):
++        evlddx r4,r3,r10
++        addi r3,r3,16 /* overadjust */
++        evsubfw r7, r12, r4
++        evandc r9, r11, r4
++        evand r9, r7, r9
++        evcmpgtu 1, r9, r0
++        bt 6, L(found_null1)
++        addi r3,r3,-8 /* readjust */
++        addi r7,r10,r3
++        andi. r7,r7,0xFFF
++        bne L(find_page_end)
++
++L(start_new_loop):
++        /* It is now safe to proceed to the next page.  load the
++	 * counter with the number of doublewords in a page
++	 * (minus 4 to account for the first iteration)
++	 */
++        evlddx r4,r3,r10
++        li r6, 508
++
++        evsubfw r7, r12, r4
++        addi r3,r3,8
++        b L(aligned_double_loop)
++
++L(last_double_was_first):
++        evandc r9,r11,r4
++        evand r9,r9,r7
++        evcmpgtu 1,r9,r0
++        addi r3,r3,8 /* adjust */
++        bt 6,L(found_null1)
++        addi r3,r3,-8 /*readjust */
++        b L(start_new_loop)
++
++
++        /* The first doubleword had a null byte */
++L(found_null1):
++        /* Compensate for the fact that r3 is 16 ahead */
++        addi r3,r3,-12
++
++        /* If there was a null in the hi word, move that word
++	 * down into the lo word, and subtract 4 from r3
++	 */
++        bf 4, L(find_null1)
++        evmergehi r4, r4, r4
++        addi r3,r3,-4
++L(find_null1):
++        rlwinm. r11,r4,0,0,7
++        beq L(finish1)
++        addi r3,r3,1
++        rlwinm. r11,r4,0,8,15
++        beq L(finish1)
++        addi r3,r3,1
++        rlwinm. r11,r4,0,16,23
++        beq L(finish1)
++        addi r3,r3,1
++
++L(finish1):
++        blr
++
++        /* The second doubleword had a null byte */
++L(found_null2):
++        /* Compensate for the fact that r3 is 16 ahead */
++        addi r3,r3,-12
++
++        /* If there was a null in the hi word, move that word
++	 * down into the lo word, and subtract 4 from r3
++	 */
++        bf 20, L(find_null2)
++        evmergehi r5, r5, r5
++        addi r3,r3,-4
++L(find_null2):
++        rlwinm. r11,r5,0,0,7
++        beq L(finish2)
++        addi r3,r3,1
++        rlwinm. r11,r5,0,8,15
++        beq L(finish2)
++        addi r3,r3,1
++        rlwinm. r11,r5,0,16,23
++        beq L(finish2)
++        addi r3,r3,1
++
++L(finish2):
++        blr
++
++END (strlen)
++libc_hidden_builtin_def (strlen)
+diff -Naur glibc-2.20/sysdeps/powerpc/powerpc32/e500/strcmp.S glibc-2.20-stcmp/sysdeps/powerpc/powerpc32/e500/strcmp.S
+--- glibc-2.20/sysdeps/powerpc/powerpc32/e500/strcmp.S	2015-08-27 04:27:44.436000785 -0500
++++ glibc-2.20-stcmp/sysdeps/powerpc/powerpc32/e500/strcmp.S	2015-08-27 04:33:45.417000790 -0500
+@@ -618,7 +618,7 @@
+         evandc r9,r11,r7
+         evand r9,r3,r9
+         evcmpgtu 5,r9,r0
+-        bt 22,L(found_early_null)
++        bt 21,L(found_early_null)
+ 
+         /* Now load the next 2 words of r4, and realign the
+ 	 * data to r10.  Then branch out if any of the bytes
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc32/e500/memcopy.h glibc-2.20-new/sysdeps/powerpc/powerpc32/e500/memcopy.h
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc32/e500/memcopy.h	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-new/sysdeps/powerpc/powerpc32/e500/memcopy.h	2015-09-10 11:06:13.243187000 -0500
+@@ -0,0 +1 @@
++#include "../../powerpc32/power4/memcopy.h"
diff --git a/recipes-core/glibc/glibc-fsl/0009.glibc.fsl-mcpy-e500mc-e5500-e6500.patch b/recipes-core/glibc/glibc-fsl/0009.glibc.fsl-mcpy-e500mc-e5500-e6500.patch
new file mode 100644
index 0000000..97fc606
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0009.glibc.fsl-mcpy-e500mc-e5500-e6500.patch
@@ -0,0 +1,1191 @@
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc32/e500mc/memcopy.h glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e500mc/memcopy.h
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc32/e500mc/memcopy.h	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e500mc/memcopy.h	2015-09-23 14:26:35.273121001 -0500
+@@ -0,0 +1 @@
++#include "../../powerpc32/power4/memcopy.h"
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc32/e500mc/memcpy.S glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e500mc/memcpy.S
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc32/e500mc/memcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e500mc/memcpy.S	2015-09-23 14:26:35.275121002 -0500
+@@ -0,0 +1,285 @@
++/* Optimized memcpy implementation for e500mc PowerPC.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
++   Returns 'dst'.
++
++	 r3 = destination
++	 r4 = source
++	 r5 = byte count
++
++	 volatile fixed point registers usable:
++	 r0, r3-r12
++
++	 volatile floating point registers usable:
++	 f0-f13.  */
++
++EALIGN (memcpy, 5, 0)
++	cmplw	cr0, r4, r3		/* if source==destination, return.  */
++	beqlr	cr0
++	/* if number of bytes is less than 8, (optimal value TBD),
++	   but greater than zero copy byte-by-byte.  */
++	cmplwi	r5, 8
++	mr	r6, r3
++	blt	L(copy_bytes)
++	neg	r0, r4
++	andi.	r11, r0, 7
++	beq	L(src_aligned)
++	/* We have to align the src pointer by r11 bytes */
++	cmplwi	cr1, r11, 4
++	cmplwi	cr0, r11, 1
++	bgt	cr1, L(src_567)
++	ble	cr0, L(src_1)
++	/* 2, 3 or 4 bytes */
++	addi	r0, r11, -2
++	lhz	r9, 0(r4)
++	lhzx	r12, r4, r0
++	sth	r9, 0(r6)
++	sthx	r12, r6, r0
++	b	L(src_0)
++L(src_567):
++	addi	r0, r11, -4
++	lwz	r9, 0(r4)
++	lwzx	r12, r4, r0
++	stw	r9, 0(r6)
++	stwx	r12, r6, r0
++	b	L(src_0)
++L(src_1):
++	lbz	r0, 0(r4)
++	stb	r0, 0(r6)
++L(src_0):
++	subf	r5, r11, r5
++	add	r4, r4, r11
++	add	r6, r6, r11
++L(src_aligned):
++	cmplwi	7, r5, 63
++	ble	7, L(copy_remaining)
++	srwi	r11, r5, 6		/* No of 64 byte copy count.  */
++	rlwinm	r5, r5, 0, 26, 31	/* remaining bytes.  */
++	rlwinm.	r0, r6, 0, 29, 31
++	mtctr	r11
++	bne	0, L(dst_naligned)
++L(copy_dalign):
++#ifndef _SOFT_FLOAT
++	lfd	0, 0(r4)
++	lfd	1, 8(r4)
++	lfd	2, 16(r4)
++	lfd	3, 24(r4)
++	stfd	0, 0(r6)
++	stfd	1, 8(r6)
++	stfd	2, 16(r6)
++	stfd	3, 24(r6)
++	lfd	0, 32(r4)
++	lfd	1, 40(r4)
++	lfd	2, 48(r4)
++	lfd	3, 56(r4)
++	addi	r4, r4, 64
++	stfd	0, 32(r6)
++	stfd	1, 40(r6)
++	stfd	2, 48(r6)
++	stfd	3, 56(r6)
++#else
++	lwz	r0, 0(r4)
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++#endif
++	addi	r6, r6, 64
++	bdnz	L(copy_dalign)
++L(copy_remaining):
++	srwi.	r11, r5, 3		/* No of 8 byte copy count.  */
++	rlwinm	r5, r5, 0, 29, 31	/* remaining bytes.  */
++	beq	0, L(copy_bytes)
++	mtcrf	0x01, r11
++	bf	cr7*4+1, L(cp16b)
++	lwz	r0, 0(r4)		/* copy 32 bytes.  */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	lwz	r0, 16(r4)
++	lwz	r7, 20(r4)
++	lwz	r8, 24(r4)
++	lwz	r9, 28(r4)
++	addi	r4, r4, 32
++	stw	r0, 16(r6)
++	stw	r7, 20(r6)
++	stw	r8, 24(r6)
++	stw	r9, 28(r6)
++	addi	r6, r6, 32
++L(cp16b):
++	bf	cr7*4+2, L(cp8b)
++	lwz	r0, 0(r4)		/* copy 16 bytes.  */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	addi	r4, r4, 16
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	addi	r6, r6, 16
++L(cp8b):
++	bf	cr7*4+3, L(copy_bytes)
++	lwz	r0, 0(r4)		/* copy 8 bytes.  */
++	lwz	r7, 4(r4)
++	addi	r4, r4, 8
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	addi	r6, r6, 8
++L(copy_bytes):
++	cmplwi	cr1, r5, 4
++	cmplwi	cr0, r5, 1
++	bgt	cr1, L(gt4b)		/* nb > 4?  (5, 6, 7 bytes).  */
++	ble	cr0, L(lt1b)		/* nb <= 1? (0, 1 bytes).  */
++	addi	r0, r5, -2		/* 2, 3, 4 bytes.  */
++	lhz	r9, 0(r4)
++	lhzx	r11, r4, r0
++	sth	r9, 0(r6)
++	sthx	r11, r6, r0
++	blr
++L(gt4b):
++	addi	r0, r5, -4		/* 5, 6, 7 bytes.  */
++	lwz	r9, 0(r4)
++	lwzx	r11, r4, r0
++	stw	r9, 0(r6)
++	stwx	r11, r6, r0
++	blr
++L(lt1b):
++	mtocrf	0x1, r5			/* nb == 0 ? return.  */
++	bflr	31
++	lbz	r0, 0(r4)		/* nb == 1.  */
++	stb	r0, 0(r6)
++	blr
++
++L(dst_naligned):
++	rlwinm.	r0, r6, 0, 30, 31
++	beq	0, L(copy_dalign4)
++L(copy_dnalign):
++	lwz	r0, 0(r4)		/* copy 64 bytes.  */
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_dnalign)
++	b	L(copy_remaining)
++
++L(copy_dalign4):
++	lwz	r0, 0(r4)
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	lwz	r0, 16(r4)
++	lwz	r7, 20(r4)
++	lwz	r8, 24(r4)
++	lwz	r9, 28(r4)
++	stw	r0, 16(r6)
++	stw	r7, 20(r6)
++	stw	r8, 24(r6)
++	stw	r9, 28(r6)
++	lwz	r0, 32(r4)
++	lwz	r7, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 32(r6)
++	stw	r7, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r7, 52(r4)
++	lwz	r8, 56(r4)
++	lwz	r9, 60(r4)
++	addi	r4, r4, 64
++	stw	r0, 48(r6)
++	stw	r7, 52(r6)
++	stw	r8, 56(r6)
++	stw	r9, 60(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_dalign4)
++	b	L(copy_remaining)
++
++END (memcpy)
++libc_hidden_builtin_def (memcpy)
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc32/e5500/memcopy.h glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e5500/memcopy.h
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc32/e5500/memcopy.h	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e5500/memcopy.h	2015-09-23 14:26:35.275121002 -0500
+@@ -0,0 +1 @@
++#include "../../powerpc32/power4/memcopy.h"
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc32/e5500/memcpy.S glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e5500/memcpy.S
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc32/e5500/memcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e5500/memcpy.S	2015-09-23 14:26:35.275121002 -0500
+@@ -0,0 +1,252 @@
++/* Optimized memcpy implementation for e5500 32-bit PowerPC.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
++   Returns 'dst'.
++
++	 r3 = destination
++	 r4 = source
++	 r5 = byte count
++
++	 volatile fixed point registers usable:
++	 r0, r3-r12
++
++	 volatile floating point registers usable:
++	 f0-f13.  */
++
++EALIGN (memcpy, 5, 0)
++	cmplw	cr0, r4, r3		/* if source==destination, return.  */
++	beqlr	cr0
++	/* if number of bytes is less than 8, (optimal value TBD),
++	   but greater than zero copy byte-by-byte.  */
++	cmplwi	r5, 8
++	mr	r6, r3
++	blt	L(copy_bytes)
++	neg	r0, r4
++	andi.	r11, r0, 3
++	beq	L(src_align4)
++	/* We have to align the src pointer by r11 bytes */
++	cmplwi	cr0, r11, 1
++	ble	L(src_1)
++	/* 2 or 3 bytes */
++	addi	r8, r11, -2
++	lhz	r9, 0(r4)
++	lhzx	r12, r4, r8
++	sth	r9, 0(r6)
++	sthx	r12, r6, r8
++	b	L(src_0)
++L(src_1):
++	lbz	r8, 0(r4)
++	stb	r8, 0(r6)
++L(src_0):
++	subf	r5, r11, r5
++	add	r4, r4, r11
++	add	r6, r6, r11
++L(src_align4):
++	/* Aligned by 4, now extend it to 16 */
++	cmplwi	7, r5, 63
++	ble	7, L(copy_remaining)
++	andi.	r10, r0, 15
++	beq	L(src_aligned16)
++	subf.	r10, r11, r10
++	beq	0, L(src_aligned16)
++	srwi	r11, r10, 2
++	subf	r5, r10, r5
++	mtctr	r11
++L(copy_salign16):
++	lwz	0, 0(r4)
++	addi	r4, r4, 4
++	stw	0, 0(r6)
++	addi	r6, r6, 4
++	bdnz	L(copy_salign16)
++L(src_aligned16):
++	srwi.	r11, r5, 6		/* No of 64 byte copy count.  */
++	beq	0, L(copy_remaining)
++	rlwinm	r5, r5, 0, 26, 31	/* remaining bytes.  */
++	rlwinm.	r0, r6, 0, 29, 31
++	mtctr	r11
++	bne	0, L(copy_dnalign)
++L(copy_dalign):
++#ifndef _SOFT_FLOAT
++	lfd	0, 0(r4)		/* copy 64 bytes.  */
++	lfd	1, 8(r4)
++	lfd	2, 16(r4)
++	lfd	3, 24(r4)
++	stfd	0, 0(r6)
++	stfd	1, 8(r6)
++	stfd	2, 16(r6)
++	stfd	3, 24(r6)
++	lfd	0, 32(r4)
++	lfd	1, 40(r4)
++	lfd	2, 48(r4)
++	lfd	3, 56(r4)
++	addi	r4, r4, 64
++	stfd	0, 32(r6)
++	stfd	1, 40(r6)
++	stfd	2, 48(r6)
++	stfd	3, 56(r6)
++	addi	r6, r6, 64
++#else
++	lwz	r0, 0(r4)
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	lwz	r0, 16(r4)
++	lwz	r7, 20(r4)
++	lwz	r8, 24(r4)
++	lwz	r9, 28(r4)
++	stw	r0, 16(r6)
++	stw	r7, 20(r6)
++	stw	r8, 24(r6)
++	stw	r9, 28(r6)
++	lwz	r0, 32(r4)
++	lwz	r7, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 32(r6)
++	stw	r7, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r7, 52(r4)
++	lwz	r8, 56(r4)
++	lwz	r9, 60(r4)
++	addi	r4, r4, 64
++	stw	r0, 48(r6)
++	stw	r7, 52(r6)
++	stw	r8, 56(r6)
++	stw	r9, 60(r6)
++	addi	r6, r6, 64
++#endif
++	bdnz	L(copy_dalign)
++L(copy_remaining):
++	srwi.	r11, r5, 3		/* No of 8 byte copy count.  */
++	rlwinm	r5, r5, 0, 29, 31	/* remaining bytes.  */
++	beq	0, L(copy_bytes)
++	mtcrf	0x01, r11
++	bf	cr7*4+1, L(cp16b)
++	lwz	r0, 0(r4)		/* copy 32 bytes.  */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	lwz	r0, 16(r4)
++	lwz	r7, 20(r4)
++	lwz	r8, 24(r4)
++	lwz	r9, 28(r4)
++	addi	r4, r4, 32
++	stw	r0, 16(r6)
++	stw	r7, 20(r6)
++	stw	r8, 24(r6)
++	stw	r9, 28(r6)
++	addi	r6, r6, 32
++L(cp16b):
++	bf	cr7*4+2, L(cp8b)
++	lwz	r0, 0(r4)		/* copy 16 bytes.  */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	addi	r4, r4, 16
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	addi	r6, r6, 16
++L(cp8b):
++	bf	cr7*4+3, L(copy_bytes)
++	lwz	r0, 0(r4)		/* copy 8 bytes.  */
++	lwz	r7, 4(r4)
++	addi	r4, r4, 8
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	addi	r6, r6, 8
++L(copy_bytes):
++	cmplwi	cr1, r5, 4
++	cmplwi	cr0, r5, 1
++	bgt	cr1, L(gt4b)		/* nb > 4?  (5, 6, 7 bytes).  */
++	ble	cr0, L(lt1b)		/* nb <= 1? (0, 1 bytes).  */
++	addi	r0, r5, -2		/* 2, 3, 4 bytes.  */
++	lhz	r9, 0(r4)
++	lhzx	r11, r4, r0
++	sth	r9, 0(r6)
++	sthx	r11, r6, r0
++	blr
++L(gt4b):
++	addi	r0, r5, -4		/* 5, 6, 7 bytes.  */
++	lwz	r9, 0(r4)
++	lwzx	r11, r4, r0
++	stw	r9, 0(r6)
++	stwx	r11, r6, r0
++	blr
++L(lt1b):
++	mtocrf	0x1, r5			/* nb == 0 ? return.  */
++	bflr	31
++	lbz	r0, 0(r4)		/* nb == 1.  */
++	stb	r0, 0(r6)
++	blr
++
++L(copy_dnalign):
++	lwz	r0, 0(r4)		/* copy 64 bytes.  */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	lwz	r0, 16(r4)
++	lwz	r7, 20(r4)
++	lwz	r8, 24(r4)
++	lwz	r9, 28(r4)
++	stw	r0, 16(r6)
++	stw	r7, 20(r6)
++	stw	r8, 24(r6)
++	stw	r9, 28(r6)
++	lwz	r0, 32(r4)
++	lwz	r7, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 32(r6)
++	stw	r7, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r7, 52(r4)
++	lwz	r8, 56(r4)
++	lwz	r9, 60(r4)
++	addi	r4, r4, 64
++	stw	r0, 48(r6)
++	stw	r7, 52(r6)
++	stw	r8, 56(r6)
++	stw	r9, 60(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_dnalign)
++	b	L(copy_remaining)
++
++END (memcpy)
++libc_hidden_builtin_def (memcpy)
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc32/e6500/memcopy.h glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e6500/memcopy.h
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc32/e6500/memcopy.h	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e6500/memcopy.h	2015-09-23 14:26:35.275121002 -0500
+@@ -0,0 +1 @@
++#include "../../powerpc32/power4/memcopy.h"
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc32/e6500/memcpy.S glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e6500/memcpy.S
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc32/e6500/memcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc32/e6500/memcpy.S	2015-09-25 19:05:12.776925259 -0500
+@@ -0,0 +1,241 @@
++/* Optimized memcpy implementation for e6500 32-bit PowerPC.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
++   Returns 'dst'.
++
++	 r3 = destination
++	 r4 = source
++	 r5 = byte count
++
++	 volatile fixed point registers usable:
++	 r0, r3-r12
++
++	 volatile floating point registers usable:
++	 f0-f13.  */
++
++EALIGN (memcpy, 5, 0)
++	cmplw	cr0, r4, r3		/* if source==destination, return.  */
++	beqlr	cr0
++	/* if number of bytes is less than 16, (optimal value TBD),
++	   but greater than zero copy byte-by-byte.  */
++	cmplwi	r5, 16
++	mr	r6, r3
++	blt	L(copy_remaining)
++	neg	r0, r3
++	andi.	r11, r0, 15
++	beq	L(dst_align16)
++	cmplwi	cr1, r11, 8
++	ble	cr1, L(src_1_8)
++	addi	r0, r11, -8
++	addi	r10, r11, -4
++	lwz	r9, 0(r4)
++	lwz	r8, 4(r4)
++	lwzx	r7, r4, r0
++	lwzx	r6, r4, r10
++	stw	r9, 0(r3)
++	stw	r8, 4(r3)
++	stwx	r7, r3, r0
++	stwx	r6, r3, r10
++	mr	r6, r3
++	b	L(src_0)
++L(src_1_8):
++	cmplwi	cr1, r11, 4
++	cmplwi	cr0, r11, 1
++	bgt	cr1, L(src_567)
++	ble	cr0, L(src_1)
++	/* 2, 3 or 4 bytes */
++	addi	r0, r11, -2
++	lhz	r9, 0(r4)
++	lhzx	r8, r4, r0
++	sth	r9, 0(r6)
++	sthx	r8, r6, r0
++	b	L(src_0)
++L(src_567):
++	addi	r0, r11, -4
++	lwz	r9, 0(r4)
++	lwzx	r8, r4, r0
++	stw	r9, 0(r6)
++	stwx	r8, r6, r0
++	b	L(src_0)
++L(src_1):
++	lbz	r0, 0(r4)
++	stb	r0, 0(r6)
++L(src_0):
++	subf	r5, r11, r5
++	add	r4, r4, r11
++	add	r6, r6, r11
++L(dst_align16):
++	cmplwi	7, r5, 63
++	ble	7, L(copy_remaining)
++	srwi	r11, r5, 6		/* No of 64 byte copy count.  */
++	rlwinm	r5, r5, 0, 26, 31	/* remaining bytes.  */
++	rlwinm.	r0, r4, 0, 28, 31
++	mtctr	r11
++	li	r7, 16
++	li	r8, 32
++	li	r9, 48
++	bne	0, L(src_naligned)
++L(copy_salign16):
++	lvx	v14, 0, r4		/* copy 64 bytes.  */
++	lvx	v15, r7, r4
++	lvx	v16, r8, r4
++	lvx	v17, r9, r4
++	addi	r4, r4, 64
++	stvx	v14, 0, r6
++	stvx	v15, r7, r6
++	stvx	v16, r8, r6
++	stvx	v17, r9, r6
++	addi	r6, r6, 64
++	bdnz	L(copy_salign16)
++L(copy_remaining):
++	srwi.	r11, r5, 3		/* No of 8 byte copy count.  */
++	rlwinm	r5, r5, 0, 29, 31	/* remaining bytes.  */
++	beq	0, L(copy_bytes)
++	mtcrf	0x01, r11
++	bf	cr7*4+1, L(cp16b)
++
++	lwz	r0, 0(r4)		/* copy 32 bytes */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++
++	lwz	r0, 16(r4)
++	lwz	r7, 20(r4)
++	lwz	r8, 24(r4)
++	lwz	r9, 28(r4)
++	addi	r4, r4, 32
++
++	stw	r0, 16(r6)
++	stw	r7, 20(r6)
++	stw	r8, 24(r6)
++	stw	r9, 28(r6)
++	addi r6, r6, 32
++L(cp16b):
++	bf	cr7*4+2, L(cp8b)
++	lwz	r0, 0(r4)		/* copy 16 bytes */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++
++	addi	r4, r4, 16
++
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	addi	r6, r6, 16
++L(cp8b):
++	bf	cr7*4+3, L(copy_bytes)
++	lwz	r0, 0(r4)		/* copy 8 bytes */
++	lwz	r7, 4(r4)
++	addi	r4, r4, 8
++
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	addi	r6, r6, 8
++L(copy_bytes):
++	cmplwi	cr1, r5, 4
++	cmplwi	cr0, r5, 1
++	bgt	cr1, L(gt4b)		/* nb > 4?  (5, 6, 7 bytes).  */
++	ble	cr0, L(lt1b)		/* nb <= 1? (0, 1 bytes).  */
++	addi	r0, r5, -2		/* 2, 3, 4 bytes.  */
++	lhz	r9, 0(r4)
++	lhzx	r11, r4, r0
++	sth	r9, 0(r6)
++	sthx	r11, r6, r0
++	blr
++L(gt4b):
++	addi	r0, r5, -4		/* 5, 6, 7 bytes.  */
++	lwz	r9, 0(r4)
++	lwzx	r11, r4, r0
++	stw	r9, 0(r6)
++	stwx	r11, r6, r0
++	blr
++L(lt1b):
++	mtocrf	0x1, r5			/* nb == 0 ? return.  */
++	bflr	31
++	lbz	r0, 0(r4)		/* nb == 1.  */
++	stb	r0, 0(r6)
++	blr
++
++L(src_naligned):
++#ifndef _SOFT_FLOAT
++	rlwinm.	r0, r4, 0, 29, 31
++	beq	0, L(copy_salign8)
++#endif
++L(copy_snalign):			/* copy 64 bytes.  */
++	lvx	v0, 0, r4		/* load MSQ.  */
++	lvsl	v18, 0, r4		/* set permute control vector.  */
++	lvx	v19, r7, r4		/* load LSQ.  */
++	vperm	v14, v0, v19, v18	/* align the data.  */
++	lvx	v0, r7, r4		/* load MSQ.  */
++	lvsl	v18, r7, r4		/* set permute control vector.  */
++	lvx	v19, r8, r4		/* load LSQ.  */
++	vperm	v15, v0, v19, v18	/* align the data.  */
++	lvx	v0, r8, r4		/* load MSQ.  */
++	lvsl	v18, r8, r4		/* set permute control vector.  */
++	lvx	v19, r9, r4		/* load LSQ.  */
++	vperm	v16, v0, v19, v18	/* align the data.  */
++	lvx	v0, r9, r4		/* load MSQ.  */
++	lvsl	v18, r9, r4		/* set permute control vector.  */
++	addi	r4, r4, 64
++	lvx	v19, 0, r4		/* load LSQ.  */
++	vperm	v17, v0, v19, v18	/* align the data.  */
++	stvx	v14, 0, r6
++	stvx	v15, r7, r6
++	stvx	v16, r8, r6
++	stvx	v17, r9, r6
++	addi	r6, r6, 64
++	bdnz	L(copy_snalign)
++	b	L(copy_remaining)
++
++#ifndef _SOFT_FLOAT
++L(copy_salign8):
++	lfd	0, 0(r4)		/* copy 64 bytes.  */
++	lfd	1, 8(r4)
++	lfd	2, 16(r4)
++	lfd	3, 24(r4)
++	stfd	0, 0(r6)
++	stfd	1, 8(r6)
++	stfd	2, 16(r6)
++	stfd	3, 24(r6)
++	lfd	0, 32(r4)
++	lfd	1, 40(r4)
++	lfd	2, 48(r4)
++	lfd	3, 56(r4)
++	addi	r4, r4, 64
++	stfd	0, 32(r6)
++	stfd	1, 40(r6)
++	stfd	2, 48(r6)
++	stfd	3, 56(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_salign8)
++	b	L(copy_remaining)
++#endif
++
++END (memcpy)
++libc_hidden_builtin_def (memcpy)
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc64/e5500/memcopy.h glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e5500/memcopy.h
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc64/e5500/memcopy.h	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e5500/memcopy.h	2015-09-23 14:26:35.275121002 -0500
+@@ -0,0 +1 @@
++#include "../../powerpc32/power4/memcopy.h"
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc64/e5500/memcpy.S glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e5500/memcpy.S
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc64/e5500/memcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e5500/memcpy.S	2015-09-23 14:26:35.276121001 -0500
+@@ -0,0 +1,155 @@
++/* Optimized memcpy implementation for e5500 64-bit PowerPC.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
++   Returns 'dst'.
++
++	 r3 = destination
++	 r4 = source
++	 r5 = byte count
++
++	 volatile fixed point registers usable:
++	 r0, r3-r12
++
++	 volatile floating point registers usable:
++	 f0-f13.  */
++
++EALIGN (memcpy, 5, 0)
++	CALL_MCOUNT 3
++	cmpld	cr0, r4, r3		/* if source==destination, return.  */
++	beqlr	cr0
++	/* if number of bytes is less than 8 but greater than zero,
++	   copy byte-by-byte.  */
++	cmpldi	r5, 8
++	mr	r6, r3
++	blt	L(copy_bytes)
++	neg	r0, r4
++	andi.	r11, r0, 7
++	beq	L(src_aligned)
++	/* We have to align the src pointer by r11 bytes */
++	cmplwi	cr1, r11, 4
++	cmplwi	cr0, r11, 1
++	bgt	cr1, L(src_567)
++	ble	cr0, L(src_1)
++	/* 2, 3 or 4 bytes */
++	addi	r0, r11, -2
++	lhz	r9, 0(r4)
++	lhzx	r12, r4, r0
++	sth	r9, 0(r6)
++	sthx	r12, r6, r0
++	b	L(src_0)
++L(src_567):
++	addi	r0, r11, -4
++	lwz	r9, 0(r4)
++	lwzx	r12, r4, r0
++	stw	r9, 0(r6)
++	stwx	r12, r6, r0
++	b	L(src_0)
++L(src_1):
++	lbz	r0, 0(r4)
++	stb	r0, 0(r6)
++L(src_0):
++	subf	r5, r11, r5
++	add	r4, r4, r11
++	add	r6, r6, r11
++L(src_aligned):
++	cmpldi	7, r5, 63
++	ble	7, L(copy_remaining)
++	srwi	r11, r5, 6		/* No of 64 byte copy count.  */
++	rlwinm.	r5, r5, 0, 26, 31	/* remaining bytes.  */
++	mtctr	r11
++L(copy_salign):
++	ld	r0, 0(r4)		/* 64-byte copy.  */
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	ld	r0, 32(r4)
++	ld	r7, 40(r4)
++	ld	r8, 48(r4)
++	ld	r9, 56(r4)
++	addi	r4, r4, 64
++	std	r0, 32(r6)
++	std	r7, 40(r6)
++	std	r8, 48(r6)
++	std	r9, 56(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_salign)
++L(copy_remaining):
++	srwi.	r11, r5, 3		/* No of 8 byte copy count.  */
++	rlwinm	r5, r5, 0, 29, 31	/* remaining bytes.  */
++	beq	0, L(copy_bytes)
++	mtcrf	0x01, r11
++	bf	cr7*4+1, L(cp16b)
++	ld	r0, 0(r4)		/* copy 32 bytes.  */
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	addi	r4, r4, 32
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	addi	r6, r6, 32
++L(cp16b):
++	bf	cr7*4+2, L(cp8b)
++	ld	r7, 0(r4)		/* copy 16 bytes.  */
++	ld	r8, 8(r4)
++	addi	r4, r4, 16
++	std	r7, 0(r6)
++	std	r8, 8(r6)
++	addi	r6, r6, 16
++L(cp8b):
++	bf	cr7*4+3, L(copy_bytes)
++	ld	r7, 0(r4)		/* copy 8 bytes.  */
++	addi	r4, r4, 8
++	std	r7, 0(r6)
++	addi	r6, r6, 8
++L(copy_bytes):
++	cmpldi	cr1, r5, 4
++	cmpldi	cr0, r5, 1
++	bgt	cr1, L(gt4b)		/* nb > 4?  (5, 6, 7 bytes).  */
++	ble	cr0, L(lt1b)		/* nb <= 1? (0, 1 bytes).  */
++	addi	r0, r5, -2		/* 2, 3, 4 bytes.  */
++	lhz	r9, 0(r4)
++	lhzx	r11, r4, r0
++	sth	r9, 0(r6)
++	sthx	r11, r6, r0
++	blr
++L(gt4b):
++	addi	r0, r5, -4		/* 5, 6, 7 bytes.  */
++	lwz	r9, 0(r4)
++	lwzx	r11, r4, r0
++	stw	r9, 0(r6)
++	stwx	r11, r6, r0
++	blr
++L(lt1b):
++	mtocrf	0x1, r5			/* nb == 0 ? return.  */
++	bflr	31
++	lbz	r0, 0(r4)		/* nb == 1.  */
++	stb	r0, 0(r6)
++	blr
++
++END_GEN_TB (memcpy,TB_TOCLESS)
++libc_hidden_builtin_def (memcpy)
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc64/e6500/memcopy.h glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e6500/memcopy.h
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc64/e6500/memcopy.h	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e6500/memcopy.h	2015-09-23 14:26:35.276121001 -0500
+@@ -0,0 +1 @@
++#include "../../powerpc32/power4/memcopy.h"
+diff -ruN glibc-2.20-orig/sysdeps/powerpc/powerpc64/e6500/memcpy.S glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e6500/memcpy.S
+--- glibc-2.20-orig/sysdeps/powerpc/powerpc64/e6500/memcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-memcpy-fixed/sysdeps/powerpc/powerpc64/e6500/memcpy.S	2015-09-25 19:05:35.132924985 -0500
+@@ -0,0 +1,213 @@
++/* Optimized memcpy implementation for e6500 64-bit PowerPC.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
++   Returns 'dst'.
++
++	 r3 = destination
++	 r4 = source
++	 r5 = byte count
++
++	 volatile fixed point registers usable:
++	 r0, r3-r12
++
++	 volatile floating point registers usable:
++	 f0-f13.  */
++
++EALIGN (memcpy, 5, 0)
++	CALL_MCOUNT 3
++	cmpld	cr0, r4, r3		/* if source==destination, return.  */
++	beqlr	cr0
++	/* if number of bytes is less than 16 but greater than zero,
++	   copy byte-by-byte.  */
++	cmpldi	r5, 16
++	mr	r6, r3
++	ble	L(copy_remaining)
++	neg	r0, r3
++	andi.	r11, r0, 15
++	beq	L(dst_align)
++ 	/* We have to align the src pointer by r11 bytes */
++	cmpldi	cr1, r11, 8
++	ble	cr1, L(src_1_8)
++	/* Take care of 8 bytes at once */
++	addi	r0, r11, -8
++	ld	r9, 0(r4)
++	ldx	r8, r4, r0
++	std	r9, 0(r6)
++	stdx	r8, r6, r0
++	b	L(src_0)
++L(src_1_8):
++	cmpldi	cr1, r11, 4
++	cmpldi	cr0, r11, 1
++	bgt	cr1, L(src_567)
++	ble	cr0, L(src_1)
++	/* 2, 3 or 4 bytes */
++	addi	r0, r11, -2
++	lhz	r9, 0(r4)
++	lhzx	r8, r4, r0
++	sth	r9, 0(r6)
++	sthx	r8, r6, r0
++	b	L(src_0)
++L(src_567):
++	addi	r0, r11, -4
++	lwz	r9, 0(r4)
++	lwzx	r8, r4, r0
++	stw	r9, 0(r6)
++	stwx	r8, r6, r0
++	b	L(src_0)
++L(src_1):
++	lbz	r0, 0(r4)
++	stb	r0, 0(r6)
++L(src_0):
++	subf	r5, r11, r5
++	add	r4, r4, r11
++	add	r6, r6, r11
++L(dst_align):
++	cmpldi	7, r5, 63
++	ble	7, L(copy_remaining)
++	srwi	r11, r5, 6		/* No of 64 byte copy count.  */
++	rlwinm	r5, r5, 0, 26, 31	/* remaining bytes.  */
++	rlwinm.	r0, r4, 0, 28, 31
++	mtctr	r11
++	li	r7, 16
++	li	r8, 32
++	li	r9, 48
++	bne	0, L(src_naligned)
++L(copy_salign):
++	lvx	v14, 0, r4
++	lvx	v15, r7, r4
++	lvx	v16, r8, r4
++	lvx	v17, r9, r4
++	addi	r4, r4, 64
++	stvx	v14, 0, r6
++	stvx	v15, r7, r6
++	stvx	v16, r8, r6
++	stvx	v17, r9, r6
++	addi	r6, r6, 64
++	bdnz	L(copy_salign)
++L(copy_remaining):
++	srwi.	r11, r5, 3		/* No of 8 byte copy count.  */
++	rlwinm	r5, r5, 0, 29, 31	/* remaining bytes.  */
++	beq	0, L(copy_bytes)
++	mtcrf	0x01, r11
++	bf	cr7*4+1, L(cp16b)
++	ld	r0, 0(r4)		/* copy 32 bytes.  */
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	addi	r4, r4, 32
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	addi	r6, r6, 32
++L(cp16b):
++	bf	cr7*4+2, L(cp8b)
++	ld	r7, 0(r4)		/* copy 16 bytes.  */
++	ld	r8, 8(r4)
++	addi	r4, r4, 16
++	std	r7, 0(r6)
++	std	r8, 8(r6)
++	addi	r6, r6, 16
++L(cp8b):
++	bf	cr7*4+3, L(copy_bytes)
++	ld	r7, 0(r4)		/* copy 8 bytes.  */
++	addi	r4, r4, 8
++	std	r7, 0(r6)
++	addi	r6, r6, 8
++L(copy_bytes):
++	cmpldi	cr1, r5, 4
++	cmpldi	cr0, r5, 1
++	bgt	cr1, L(gt4b)		/* nb > 4?  (5, 6, 7 bytes).  */
++	ble	cr0, L(lt1b)		/* nb <= 1? (0, 1 bytes).  */
++	addi	r0, r5, -2		/* 2, 3, 4 bytes.  */
++	lhz	r9, 0(r4)
++	lhzx	r11, r4, r0
++	sth	r9, 0(r6)
++	sthx	r11, r6, r0
++	blr
++L(gt4b):
++	addi	r0, r5, -4		/* 5, 6, 7 bytes.  */
++	lwz	r9, 0(r4)
++	lwzx	r11, r4, r0
++	stw	r9, 0(r6)
++	stwx	r11, r6, r0
++	blr
++L(lt1b):
++	mtocrf	0x1, r5			/* nb == 0 ? return.  */
++	bflr	31
++	lbz	r0, 0(r4)		/* nb == 1.  */
++	stb	r0, 0(r6)
++	blr
++
++L(src_naligned):
++	rlwinm.	r0, r4, 0, 29, 31
++	beq	0, L(copy_salign8)
++L(copy_snalign):
++	lvx	v0, 0, r4		/* load MSQ.  */
++	lvsl	v18, 0, r4		/* set permute control vector.  */
++	lvx	v19, r7, r4		/* load LSQ.  */
++	vperm	v14, v0, v19, v18	/* align the data.  */
++	lvx	v0, r7, r4		/* load MSQ.  */
++	lvsl	v18, r7, r4		/* set permute control vector.  */
++	lvx	v19, r8, r4		/* load LSQ.  */
++	vperm	v15, v0, v19, v18	/* align the data.  */
++	lvx	v0, r8, r4		/* load MSQ.  */
++	lvsl	v18, r8, r4		/* set permute control vector.  */
++	lvx	v19, r9, r4		/* load LSQ.  */
++	vperm	v16, v0, v19, v18	/* align the data.  */
++	lvx	v0, r9, r4		/* load MSQ.  */
++	lvsl	v18, r9, r4		/* set permute control vector.  */
++	addi	r4, r4, 64
++	lvx	v19, 0, r4		/* load LSQ.  */
++	vperm	v17, v0, v19, v18	/* align the data.  */
++	stvx	v14, 0, r6
++	stvx	v15, r7, r6
++	stvx	v16, r8, r6
++	stvx	v17, r9, r6
++	addi	r6, r6, 64
++	bdnz	L(copy_snalign)
++	b	L(copy_remaining)
++
++L(copy_salign8):
++	ld	r0, 0(r4)
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	ld	r0, 32(r4)
++	ld	r7, 40(r4)
++	ld	r8, 48(r4)
++	ld	r9, 56(r4)
++	addi	r4, r4, 64
++	std	r0, 32(r6)
++	std	r7, 40(r6)
++	std	r8, 48(r6)
++	std	r9, 56(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_salign8)
++	b	L(copy_remaining)
++
++END_GEN_TB (memcpy,TB_TOCLESS)
++libc_hidden_builtin_def (memcpy)
diff --git a/recipes-core/glibc/glibc-fsl/0010.glibc.fsl-e500mc-e5500-mset.patch b/recipes-core/glibc/glibc-fsl/0010.glibc.fsl-e500mc-e5500-mset.patch
new file mode 100755
index 0000000..477c93a
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0010.glibc.fsl-e500mc-e5500-mset.patch
@@ -0,0 +1,1337 @@
+# Problem Statement:
+  Implement target specific optimized memset routine for e500mc,
+  e5500 32 bit & 64-bit target
+
+# Owned by:
+  Ram
+
+# Actions:
+  * For memset of non zero values, cache line size [64] bytes are
+    set at one go per iteration and along with this 'dcbzl' cache
+    management instruction is used to generate higher performance.
+
+  * For memset of zero value, cache management instruction 'dcbzl'
+    is used to generate higher performance.
+
+
+diff -Naur libc/sysdeps/powerpc/powerpc32/e500mc/memset.S libc_release/sysdeps/powerpc/powerpc32/e500mc/memset.S
+--- libc/sysdeps/powerpc/powerpc32/e500mc/memset.S	1969-12-31 18:00:00.000000000 -0600
++++ libc_release/sysdeps/powerpc/powerpc32/e500mc/memset.S	2015-06-29 07:31:28.885952000 -0500
+@@ -0,0 +1,415 @@
++/* Optimized memset implementation for PowerPC e500mc target.
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This implementation is based on 'powerpc/powerpc32/memset.S'.  */
++
++/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
++   Returns 's'.
++
++   The memset is done in three sizes: byte (8 bits), word (32 bits),
++   32-byte blocks (256 bits) and __cache_line_size (512 bits).  There
++   is a special case for setting whole cache lines to 0, which takes
++   advantage of the dcbzl instruction.  */
++
++#include <sysdep.h>
++
++	.section ".text"
++EALIGN (memset, 6, 1)
++
++#define rTMP	r0
++#define rMEMP0	r3	/* original value of 1st arg.  */
++#define rCHR	r4	/* char to set in each byte.  */
++#define rLEN	r5	/* length of region to set.  */
++#define rMEMP	r6	/* address at which we are storing.  */
++#define rALIGN	r7	/* number of bytes we are setting
++			   now (when aligning).  */
++#define rTMP2	r8
++#define rMEMP2	r9
++#define rCNT	r0
++
++#define rPOS64	r10	/* constant +64 for clearing with dcbz.  */
++#define rCLS	r11
++#define rGOT	r12
++
++#ifndef _SOFT_FLOAT
++#define rFLD	fp0	/* float double register with char(s) to set
++			   in each byte.  */
++#endif
++
++	/* For sizes <= 4 bytes, do byte by byte set.  */
++	cmplwi	cr1, rLEN, 4
++	mr	rMEMP, rMEMP0
++	ble	cr1, L(le_4bytes)
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	andi.	rALIGN, rMEMP, 3
++	rlwimi	rCHR, rCHR, 16, 0, 15
++	beq	L(4b_aligned)
++	/* By now, we know that there are at least 5 bytes to memset
++	   and the destination address is not word aligned.  Do not bother
++	   about non-alignment and do a one word store at once and word
++	   align the destination address.  The penalty for non-aligned
++	   store is less compared to the if-else checks and related code.  */
++	subfic	rALIGN, rALIGN, 4
++	stw	rCHR, 0(rMEMP0)
++	sub	rLEN, rLEN, rALIGN
++	add	rMEMP, rMEMP, rALIGN
++L(4b_aligned):
++	/* For sizes < 32 bytes, do it in a combination of word/half word/byte
++	   stores.  */
++	srwi.	rALIGN, rLEN, 5
++	beq	L(lt_32bytes)
++	/* For sizes where 128 > size >= 32, do the memset in a loop where
++	   32 bytes are set per each iteration.  For this size range, the
++	   overhead in getting the destination address cache aligned is more
++	   compared to the advantage of setting cache line size (64) bytes
++	   per iteration.  */
++	srwi.	rTMP2, rALIGN, 2
++	bne	L(set_cache_lines)
++	mtctr	rALIGN
++	/* By now, we know that there are at least 32 bytes to memset.  Hence
++	   no need to check for zero loop count.  */
++L(32b_loop):
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	addi	rMEMP, rMEMP, 32
++	bdnz	L(32b_loop)
++	rlwinm.	rLEN, rLEN, 0, 27, 31
++	beqlr
++	b	L(lt_32bytes)
++
++L(set_cache_lines):
++	neg	rTMP2, rMEMP
++	andi.	rALIGN, rTMP2, 60
++	beq	L(cache_aligned)
++	add	rMEMP, rMEMP, rALIGN
++	/* The cr6 and cr7 fields together will hold the number of bytes to
++	   set to make the destination address cache line aligned.  */
++	mtcrf	0x03, rALIGN
++	sub	rLEN, rLEN, rALIGN
++	cmplwi	cr1, rALIGN, 32
++	mr	rMEMP2, rMEMP
++	bf	cr6*4+3, L(a1)
++	stw	rCHR, -4(rMEMP2)
++	stw	rCHR, -8(rMEMP2)
++	stw	rCHR, -12(rMEMP2)
++	stwu	rCHR, -16(rMEMP2)
++L(a1):
++	blt	cr1, L(a2)
++	stw	rCHR, -4(rMEMP2)
++	stw	rCHR, -8(rMEMP2)
++	stw	rCHR, -12(rMEMP2)
++	stw	rCHR, -16(rMEMP2)
++	stw	rCHR, -20(rMEMP2)
++	stw	rCHR, -24(rMEMP2)
++	stw	rCHR, -28(rMEMP2)
++	stwu	rCHR, -32(rMEMP2)
++L(a2):
++	bf	cr7*4, L(a3)
++	stw	rCHR, -4(rMEMP2)
++	stwu	rCHR, -8(rMEMP2)
++L(a3):
++	bf	cr7*4+1, L(cache_aligned)
++	stw	rCHR, -4(rMEMP2)
++
++L(cache_aligned):
++#ifdef SHARED
++	mflr	rTMP
++	/* Establishes GOT addressability so we can load
++	   __cache_line_size from static.  This value was set from the aux
++	   vector during startup.  */
++	SETUP_GOT_ACCESS(rGOT, got_label_1)
++	addis	rGOT, rGOT, __cache_line_size-got_label_1@ha
++	lwz	rCLS, __cache_line_size-got_label_1@l(rGOT)
++	mtlr	rTMP
++#else
++	/* Load __cache_line_size from static.  This value was set from the
++	   aux vector during startup.  */
++	lis	rCLS, __cache_line_size@ha
++	lwz	rCLS, __cache_line_size@l(rCLS)
++#endif
++	/* If the cache line size is set and is 64 bytes, do the memset using
++	   data cache block instructions i.e. dcbz etc.  Otherwise do not use
++	   the dcb* instructions.  */
++	cmplwi	cr5, rCLS, 64
++	cmplwi	cr1, rCHR, 0
++	bne	cr5, L(nondcbz_loop_start)
++	beq	cr1, L(z_loop_start)
++L(nz_loop_start):
++#ifndef _SOFT_FLOAT
++	stw	rCHR, 0(rMEMP)
++	srwi	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	stw	rCHR, 4(rMEMP)
++	rlwinm	rLEN, rLEN, 0, 26, 31	/* n = n % CACHE_LINE_SIZE.  */
++	subic.	rCNT, rALIGN, 4
++	lfd	rFLD, 0(rMEMP)
++#else
++	srwi	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	rlwinm	rLEN, rLEN, 0, 26, 31	/* n = n % CACHE_LINE_SIZE.  */
++	subic.	rCNT, rALIGN, 4
++#endif
++	li	rPOS64, 64
++	ble	L(nz_loop_big_done)
++	mtctr	rCNT
++L(nz_loop_big):
++	dcbzl	rPOS64, rMEMP
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, 0(rMEMP)
++	stfd	rFLD, 8(rMEMP)
++	stfd	rFLD, 16(rMEMP)
++	stfd	rFLD, 24(rMEMP)
++	stfd	rFLD, 32(rMEMP)
++	stfd	rFLD, 40(rMEMP)
++	stfd	rFLD, 48(rMEMP)
++	stfd	rFLD, 56(rMEMP)
++#else
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	stw	rCHR, 32(rMEMP)
++	stw	rCHR, 36(rMEMP)
++	stw	rCHR, 40(rMEMP)
++	stw	rCHR, 44(rMEMP)
++	stw	rCHR, 48(rMEMP)
++	stw	rCHR, 52(rMEMP)
++	stw	rCHR, 56(rMEMP)
++	stw	rCHR, 60(rMEMP)
++#endif
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(nz_loop_big)
++	li	rALIGN, 4
++L(nz_loop_big_done):
++	cmplwi	cr1, rALIGN, 0
++	beq	cr1, L(nz_loop_small_done)
++	mtctr	rALIGN
++L(nz_loop_small):
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, 0(rMEMP)
++	stfd	rFLD, 8(rMEMP)
++	stfd	rFLD, 16(rMEMP)
++	stfd	rFLD, 24(rMEMP)
++	stfd	rFLD, 32(rMEMP)
++	stfd	rFLD, 40(rMEMP)
++	stfd	rFLD, 48(rMEMP)
++	stfd	rFLD, 56(rMEMP)
++#else
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	stw	rCHR, 32(rMEMP)
++	stw	rCHR, 36(rMEMP)
++	stw	rCHR, 40(rMEMP)
++	stw	rCHR, 44(rMEMP)
++	stw	rCHR, 48(rMEMP)
++	stw	rCHR, 52(rMEMP)
++	stw	rCHR, 56(rMEMP)
++	stw	rCHR, 60(rMEMP)
++#endif
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(nz_loop_small)
++L(nz_loop_small_done):
++	srwi.	rTMP2, rLEN, 5
++	beq	L(lt_32bytes)
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, 0(rMEMP)
++	stfd	rFLD, 8(rMEMP)
++	stfd	rFLD, 16(rMEMP)
++	stfd	rFLD, 24(rMEMP)
++#else
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++#endif
++	andi.	rLEN, rLEN, 31
++	addi	rMEMP, rMEMP, 32
++	beqlr
++	b	L(lt_32bytes)
++
++	.p2align 6
++L(nondcbz_loop_start):
++	srwi.	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	beq	L(nondcbz_loop_done)
++#ifndef _SOFT_FLOAT
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	rlwinm	rLEN, rLEN, 0, 26, 31	/* n = n % CACHE_LINE_SIZE.  */
++	lfd	rFLD, 0(rMEMP)
++#else
++	rlwinm	rLEN, rLEN, 0, 26, 31	/* n = n % CACHE_LINE_SIZE.  */
++#endif
++	mtctr	rALIGN
++L(nondcbz_loop):
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, 0(rMEMP)
++	stfd	rFLD, 8(rMEMP)
++	stfd	rFLD, 16(rMEMP)
++	stfd	rFLD, 24(rMEMP)
++	stfd	rFLD, 32(rMEMP)
++	stfd	rFLD, 40(rMEMP)
++	stfd	rFLD, 48(rMEMP)
++	stfd	rFLD, 56(rMEMP)
++#else
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	stw	rCHR, 32(rMEMP)
++	stw	rCHR, 36(rMEMP)
++	stw	rCHR, 40(rMEMP)
++	stw	rCHR, 44(rMEMP)
++	stw	rCHR, 48(rMEMP)
++	stw	rCHR, 52(rMEMP)
++	stw	rCHR, 56(rMEMP)
++	stw	rCHR, 60(rMEMP)
++#endif
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(nondcbz_loop)
++L(nondcbz_loop_done):
++	srwi.	rTMP2, rLEN, 5
++	beq	L(lt_32bytes)
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	andi.	rLEN, rLEN, 31
++	addi	rMEMP, rMEMP, 32
++	beqlr
++	b	L(lt_32bytes)
++
++	/* Memset of 4 bytes or less.  */
++	.p2align 6
++L(le_4bytes):
++	cmplwi	cr5, rLEN, 0
++	beqlr	cr5
++	cmplwi	cr1, rLEN, 1
++	stb	rCHR, 0(rMEMP)
++	beqlr	cr1
++	cmplwi	cr5, rLEN, 2
++	stb	rCHR, 1(rMEMP)
++	beqlr	cr5
++	cmplwi	cr1, rLEN, 4
++	stb	rCHR, 2(rMEMP)
++	bnelr	cr1
++	stb	rCHR, 3(rMEMP)
++	blr
++
++	/* Clear cache lines of memory in 128-byte chunks per iteration
++	   using the data cache block zero line instruction.  */
++	.p2align 6
++L(z_loop_start):
++	cmplwi	cr1, rLEN, 128
++	li	rPOS64, 64
++L(z_loop):
++	blt	cr1, L(z_loop_done)
++	addi	rLEN, rLEN, -128
++	dcbzl	0, rMEMP
++	dcbzl	rPOS64, rMEMP
++	cmplwi	cr1, rLEN, 128
++	addi	rMEMP, rMEMP, 128
++	b	L(z_loop)
++L(z_loop_done):
++	cmplwi	cr5, rLEN, 64
++	andi.	rTMP2, rLEN, 32
++	blt	cr5, L(z0)
++	dcbzl	0, rMEMP
++	addi	rLEN, rLEN, -64
++	addi	rMEMP, rMEMP, 64
++L(z0):
++	beq	L(lt_32bytes)
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	andi.	rLEN, rLEN, 31
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	addi	rMEMP, rMEMP, 32
++	beqlr
++
++	/* Memset of 0-31 bytes.  */
++L(lt_32bytes):
++	mtcrf	0x01, rLEN
++	cmplwi	cr1, rLEN, 16
++	add	rMEMP, rMEMP, rLEN
++	bt	31, L(b31t)
++	bt	30, L(b30t)
++L(b30f):
++	bt	29, L(b29t)
++L(b29f):
++	bge	cr1, L(b27t)
++	bflr	28
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	blr
++L(b31t):
++	stbu	rCHR, -1(rMEMP)
++	bf	30, L(b30f)
++L(b30t):
++	sthu	rCHR, -2(rMEMP)
++	bf	29, L(b29f)
++L(b29t):
++	stwu	rCHR, -4(rMEMP)
++	blt	cr1, L(b27f)
++L(b27t):
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	stw	rCHR, -12(rMEMP)
++	stwu	rCHR, -16(rMEMP)
++L(b27f):
++	bflr	28
++L(b28t):
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	blr
++
++END (memset)
++libc_hidden_builtin_def (memset)
++
+diff -Naur libc/sysdeps/powerpc/powerpc32/e5500/memset.S libc_release/sysdeps/powerpc/powerpc32/e5500/memset.S
+--- libc/sysdeps/powerpc/powerpc32/e5500/memset.S	1969-12-31 18:00:00.000000000 -0600
++++ libc_release/sysdeps/powerpc/powerpc32/e5500/memset.S	2015-06-29 09:33:17.564951999 -0500
+@@ -0,0 +1,477 @@
++/* Optimized memset implementation for PowerPC e5500 32-bit target.
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This implementation is based on 'powerpc/powerpc32/memset.S'.  */
++
++/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
++   Returns 's'.
++
++   The memset is done in different sizes: byte (8 bits), word (32 bits),
++   32-byte blocks (256 bits) and __cache_line_size (512 bits).  There
++   is a special case for setting whole cache lines to 0, which takes
++   advantage of the dcbzl instruction.  */
++
++#include <sysdep.h>
++
++	.section ".text"
++EALIGN (memset, 6, 1)
++
++#define rTMP	r0
++#define rMEMP0	r3	/* original value of 1st arg.  */
++#define rCHR	r4	/* char to set in each byte.  */
++#define rLEN	r5	/* length of region to set.  */
++#define rMEMP	r6	/* address at which we are storing.  */
++#define rALIGN	r7	/* number of bytes we are setting
++			   now (when aligning).  */
++#define rTMP2	r8
++#define rMEMP2	r9
++#define rCNT	r0
++#define rNEG128	r10	/* constant -128 for clearing with dcbzl.  */
++#define rNEG64	r11	/* constant -64 for clearing with dcbzl.  */
++#define rCLS	r11
++#define rGOT	r12
++#ifndef _SOFT_FLOAT
++#define rFLD	fp0	/* float double register with char(s) to set
++			   in each byte.  */
++#endif
++
++	cmplwi	cr1, rLEN, 7
++	mtcrf	0x1, rLEN
++	add	rMEMP2, rMEMP0, rLEN
++	ble	cr1, L(Upto7Bytes)
++	cmplwi	cr5, rLEN, 31
++	rlwimi	rCHR, rCHR, 8, 16, 23	/* Replicate byte to halfword.  */
++	rlwimi	rCHR, rCHR, 16, 0, 15	/* Replicate half word to word.  */
++	ble	cr5, L(Upto31Bytes)
++	andi.	rALIGN, rMEMP0, 3
++	cmplwi	cr1, rCHR, 0
++	beq	L(wAligned)
++	/* By now, we know that there are at least 4 bytes to memset
++	   and the destination address is not word aligned.  Do not bother
++	   about non-alignment and do a one word store at once and word
++	   align the destination address.  The penalty for non-aligned
++	   store is less compared to the if-else checks and related code.  */
++	subfic	rALIGN, rALIGN, 4
++	sub	rLEN, rLEN, rALIGN
++	stw	rCHR, 0(rMEMP0)
++L(wAligned):
++	/* For '128 > n >= 32' for zero fill value and for '256 > n >= 32'
++	   for non-zero fill value, the overhead in getting the destination
++	   address cache line aligned is more compared to the advantage of
++	   caching data and/or using the dcbzl instruction.  Hence, for
++	   those sizes, do it without using any explicit cache mechanism.  */
++	srwi.	rTMP, rLEN, 7
++	add	rMEMP, rMEMP0, rALIGN
++	beq	L(Upto255Bytes)
++	srwi.	rTMP, rLEN, 8
++	beq	cr1, L(SetCacheLines)
++	bne	L(SetCacheLines)
++L(Upto255Bytes):
++	mtcrf	0x2, rLEN
++	bf	cr6*4+2, L(wA64b)
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	addi	rMEMP, rMEMP, 32
++L(wA64b):
++	rlwinm.	rLEN, rLEN, 0, 27, 31
++	bf	cr6*4+1, L(wA128b)
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	stw	rCHR, 32(rMEMP)
++	stw	rCHR, 36(rMEMP)
++	stw	rCHR, 40(rMEMP)
++	stw	rCHR, 44(rMEMP)
++	stw	rCHR, 48(rMEMP)
++	stw	rCHR, 52(rMEMP)
++	stw	rCHR, 56(rMEMP)
++	stw	rCHR, 60(rMEMP)
++	addi	rMEMP, rMEMP, 64
++L(wA128b):
++	bf	cr6*4, L(tail31Bytes)
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	stw	rCHR, 32(rMEMP)
++	stw	rCHR, 36(rMEMP)
++	stw	rCHR, 40(rMEMP)
++	stw	rCHR, 44(rMEMP)
++	stw	rCHR, 48(rMEMP)
++	stw	rCHR, 52(rMEMP)
++	stw	rCHR, 56(rMEMP)
++	stw	rCHR, 60(rMEMP)
++	stw	rCHR, 64(rMEMP)
++	stw	rCHR, 68(rMEMP)
++	stw	rCHR, 72(rMEMP)
++	stw	rCHR, 76(rMEMP)
++	stw	rCHR, 80(rMEMP)
++	stw	rCHR, 84(rMEMP)
++	stw	rCHR, 88(rMEMP)
++	stw	rCHR, 92(rMEMP)
++	stw	rCHR, 96(rMEMP)
++	stw	rCHR, 100(rMEMP)
++	stw	rCHR, 104(rMEMP)
++	stw	rCHR, 108(rMEMP)
++	stw	rCHR, 112(rMEMP)
++	stw	rCHR, 116(rMEMP)
++	stw	rCHR, 120(rMEMP)
++	stw	rCHR, 124(rMEMP)
++	b	L(tail31Bytes)
++
++L(SetCacheLines):
++	neg	rTMP2, rMEMP
++	andi.	rALIGN, rTMP2, 60
++	beq	L(cAligned)
++	mtcrf	0x02, rALIGN
++	add	rTMP2, rMEMP, rALIGN
++	rlwinm	rTMP, rALIGN, 0, 0, 29
++	bf	cr6*4+3, L(a1)
++	stw	rCHR, -4(rTMP2)
++	stw	rCHR, -8(rTMP2)
++	stw	rCHR, -12(rTMP2)
++	stwu	rCHR, -16(rTMP2)
++L(a1):
++	mtcrf	0x1, rALIGN
++	bf	cr6*4+2, L(a2)
++	stw	rCHR, -4(rTMP2)
++	stw	rCHR, -8(rTMP2)
++	stw	rCHR, -12(rTMP2)
++	stw	rCHR, -16(rTMP2)
++	stw	rCHR, -20(rTMP2)
++	stw	rCHR, -24(rTMP2)
++	stw	rCHR, -28(rTMP2)
++	stwu	rCHR, -32(rTMP2)
++L(a2):
++	sub	rLEN, rLEN, rTMP
++	bf	cr7*4, L(a3)
++	stw	rCHR, -4(rTMP2)
++	stwu	rCHR, -8(rTMP2)
++L(a3):
++	bf	cr7*4+1, L(cAligned)
++	stw	rCHR, -4(rTMP2)
++
++L(cAligned):
++#ifdef SHARED
++	mflr	rTMP
++	/* Establishes GOT addressability so we can load
++	   __cache_line_size from static.  This value was set from the aux
++	   vector during startup.  */
++	SETUP_GOT_ACCESS(rGOT, got_label_1)
++	addis	rGOT, rGOT, __cache_line_size-got_label_1@ha
++	lwz	rCLS, __cache_line_size-got_label_1@l(rGOT)
++	mtlr	rTMP
++#else
++	/* Load __cache_line_size from static.  This value was set from the
++	   aux vector during startup.  */
++	lis	rCLS, __cache_line_size@ha
++	lwz	rCLS, __cache_line_size@l(rCLS)
++#endif
++	/* If the cache line size is set and is 64 bytes, do the memset using
++	   data cache block instructions i.e. dcbzl etc.  Otherwise do not use
++	   the dcb* instructions.  */
++	cmplwi	cr5, rCLS, 64
++	add	rMEMP, rMEMP, rALIGN
++	rlwinm	rTMP2, rLEN, 0, 0, 25
++	bne	cr5, L(nondcbzLoopStart)
++	add	rMEMP, rMEMP, rTMP2
++	beq	cr1, L(zLoopStart)
++L(nzLoopStart):
++#ifndef _SOFT_FLOAT
++	srwi	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	subic.	rCNT, rALIGN, 32
++	mtcrf	0x2, rLEN
++	lfd	rFLD, -8(rMEMP)
++	ble	L(nzLoopBigDone)
++	li	rNEG128, -128
++	mtctr	rCNT
++#else
++	srwi	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	subic.	rCNT, rALIGN, 32
++	mtcrf	0x2, rLEN
++	ble	L(nzLoopBigDone)
++	li	rNEG128, -128
++	mtctr	rCNT
++#endif
++L(nzLoopBig):
++	dcbzl	rNEG128, rMEMP
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, -8(rMEMP)
++	stfd	rFLD, -16(rMEMP)
++	stfd	rFLD, -24(rMEMP)
++	stfd	rFLD, -32(rMEMP)
++	stfd	rFLD, -40(rMEMP)
++	stfd	rFLD, -48(rMEMP)
++	stfd	rFLD, -56(rMEMP)
++	stfdu	rFLD, -64(rMEMP)
++#else
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	stw	rCHR, -12(rMEMP)
++	stw	rCHR, -16(rMEMP)
++	stw	rCHR, -20(rMEMP)
++	stw	rCHR, -24(rMEMP)
++	stw	rCHR, -28(rMEMP)
++	stw	rCHR, -32(rMEMP)
++	stw	rCHR, -36(rMEMP)
++	stw	rCHR, -40(rMEMP)
++	stw	rCHR, -44(rMEMP)
++	stw	rCHR, -48(rMEMP)
++	stw	rCHR, -52(rMEMP)
++	stw	rCHR, -56(rMEMP)
++	stw	rCHR, -60(rMEMP)
++	stwu	rCHR, -64(rMEMP)
++#endif
++	bdnz	L(nzLoopBig)
++	li	rALIGN, 32
++L(nzLoopBigDone):
++	cmplwi	cr1, rALIGN, 0
++	beq	cr1, L(nzLoopSmallDone)
++	mtctr	rALIGN
++L(nzLoopSmall):
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, -8(rMEMP)
++	stfd	rFLD, -16(rMEMP)
++	stfd	rFLD, -24(rMEMP)
++	stfd	rFLD, -32(rMEMP)
++	stfd	rFLD, -40(rMEMP)
++	stfd	rFLD, -48(rMEMP)
++	stfd	rFLD, -56(rMEMP)
++	stfdu	rFLD, -64(rMEMP)
++#else
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	stw	rCHR, -12(rMEMP)
++	stw	rCHR, -16(rMEMP)
++	stw	rCHR, -20(rMEMP)
++	stw	rCHR, -24(rMEMP)
++	stw	rCHR, -28(rMEMP)
++	stw	rCHR, -32(rMEMP)
++	stw	rCHR, -36(rMEMP)
++	stw	rCHR, -40(rMEMP)
++	stw	rCHR, -44(rMEMP)
++	stw	rCHR, -48(rMEMP)
++	stw	rCHR, -52(rMEMP)
++	stw	rCHR, -56(rMEMP)
++	stw	rCHR, -60(rMEMP)
++	stwu	rCHR, -64(rMEMP)
++#endif
++	bdnz	L(nzLoopSmall)
++L(nzLoopSmallDone):
++	rlwinm.	rLEN, rLEN, 0, 27, 31
++	bf	cr6*4+2, L(tail31Bytes)
++	add	rMEMP, rMEMP, rTMP2
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, 0(rMEMP)
++	stfd	rFLD, 8(rMEMP)
++	stfd	rFLD, 16(rMEMP)
++	stfd	rFLD, 24(rMEMP)
++#else
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++#endif
++	b	L(tail31Bytes)
++
++	.p2align 6
++L(nondcbzLoopStart):
++	srwi.	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	mtcrf	0x2, rLEN
++	beq	L(nondcbzLoopDone)
++#ifndef _SOFT_FLOAT
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	lfd	rFLD, 0(rMEMP)
++#endif
++	mtctr	rALIGN
++L(nondcbzLoop):
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, 0(rMEMP)
++	stfd	rFLD, 8(rMEMP)
++	stfd	rFLD, 16(rMEMP)
++	stfd	rFLD, 24(rMEMP)
++	stfd	rFLD, 32(rMEMP)
++	stfd	rFLD, 40(rMEMP)
++	stfd	rFLD, 48(rMEMP)
++	stfd	rFLD, 56(rMEMP)
++#else
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	stw	rCHR, 32(rMEMP)
++	stw	rCHR, 36(rMEMP)
++	stw	rCHR, 40(rMEMP)
++	stw	rCHR, 44(rMEMP)
++	stw	rCHR, 48(rMEMP)
++	stw	rCHR, 52(rMEMP)
++	stw	rCHR, 56(rMEMP)
++	stw	rCHR, 60(rMEMP)
++#endif
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(nondcbzLoop)
++L(nondcbzLoopDone):
++	rlwinm.	rLEN, rLEN, 0, 27, 31
++	bf	cr6*4+2, L(tail31Bytes)
++#ifndef _SOFT_FLOAT
++	stfd	rFLD, 0(rMEMP)
++	stfd	rFLD, 8(rMEMP)
++	stfd	rFLD, 16(rMEMP)
++	stfd	rFLD, 24(rMEMP)
++#else
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++#endif
++	b	L(tail31Bytes)
++
++	/* Memset of 7 bytes or less.  */
++	.p2align 6
++L(Upto7Bytes):
++	bf	cr7*4+3, L(b1)
++	stbu	rCHR, -1(rMEMP2)
++L(b1):
++	rlwimi	rCHR, rCHR, 8, 16, 23	/* Replicate byte to halfword.  */
++	bf	cr7*4+2, L(b2)
++	sthu	rCHR, -2(rMEMP2)
++L(b2):
++	bflr	cr7*4+1
++	rlwimi	rCHR, rCHR, 16, 0, 15	/* Replicate half word to word.  */
++	stw	rCHR, -4(rMEMP2)
++	blr
++
++	/* Memset of 31 bytes or less.  By now we know that there are at
++	   least 8 bytes to memset.  */
++	.p2align 6
++L(Upto31Bytes):
++	cmplwi	cr1, rLEN, 16
++	bf	cr7*4+3, L(c1)
++	stbu	rCHR, -1(rMEMP2)
++L(c1):
++	bf	cr7*4+2, L(c2)
++	sthu	rCHR, -2(rMEMP2)
++L(c2):
++	bf	cr7*4+1, L(c3)
++	stwu	rCHR, -4(rMEMP2)
++L(c3):
++	stw	rCHR, -4(rMEMP2)
++	stw	rCHR, -8(rMEMP2)
++	bltlr	cr1
++	stw	rCHR, -12(rMEMP2)
++	stw	rCHR, -16(rMEMP2)
++	bflr	cr7*4
++	stw	rCHR, -20(rMEMP2)
++	stw	rCHR, -24(rMEMP2)
++	blr
++
++	/* Memset of tail bytes upto 31 bytes or less.  */
++	.p2align 6
++L(tail31Bytes):
++	beqlr
++	mtcrf	0x1, rLEN
++	bf	cr7*4+3, L(tb2)
++	stbu	rCHR, -1(rMEMP2)
++L(tb2):
++	bf	cr7*4+2, L(tb4)
++	sthu	rCHR, -2(rMEMP2)
++L(tb4):
++	bf	cr7*4+1, L(tb8)
++	stwu	rCHR, -4(rMEMP2)
++L(tb8):
++	bf	cr7*4, L(tb16)
++	stw	rCHR, -4(rMEMP2)
++	stwu	rCHR, -8(rMEMP2)
++L(tb16):
++	bflr	cr6*4+3
++	stw	rCHR, -4(rMEMP2)
++	stw	rCHR, -8(rMEMP2)
++	stw	rCHR, -12(rMEMP2)
++	stw	rCHR, -16(rMEMP2)
++	blr
++
++
++	/* Clear cache lines of memory in 128-byte chunks per iteration
++	   using the data cache block zero line instruction.  */
++	.p2align 6
++L(zLoopStart):
++	mtcrf	0x2, rLEN
++	srwi.	rCNT, rLEN, 7
++	li	rNEG64, -64
++	bf	cr6*4+1, L(z1)
++	dcbzl	rNEG64, rMEMP
++	addi	rMEMP, rMEMP, -64
++L(z1):
++	beq	L(zLoopDone)
++	mtctr	rCNT
++	li	rNEG128, -128
++L(zLoop):
++	dcbzl	rNEG64, rMEMP
++	dcbzl	rNEG128, rMEMP
++	addi	rMEMP, rMEMP, -128
++	bdnz	L(zLoop)
++L(zLoopDone):
++	rlwinm.	rLEN, rLEN, 0, 27, 31
++	bf	cr6*4+2, L(tail31Bytes)
++	add	rMEMP, rMEMP, rTMP2
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	b	L(tail31Bytes)
++	
++END (memset)
++libc_hidden_builtin_def (memset)
++
+diff -Naur libc/sysdeps/powerpc/powerpc64/e5500/memset.S libc_release/sysdeps/powerpc/powerpc64/e5500/memset.S
+--- libc/sysdeps/powerpc/powerpc64/e5500/memset.S	1969-12-31 18:00:00.000000000 -0600
++++ libc_release/sysdeps/powerpc/powerpc64/e5500/memset.S	2015-06-29 07:31:28.886952000 -0500
+@@ -0,0 +1,417 @@
++/* Optimized memset implementation for PowerPC e5500 64-bit target
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++/* This implementation is based on 'powerpc/powerpc64/memset.S'.  */
++
++/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
++   Returns 's'.
++
++   The memset is done in four sizes: byte (8 bits), word (32 bits),
++   32-byte blocks (256 bits) and __cache_line_size (512 bits).
++   There is a special case for setting whole cache lines to 0, which
++   takes advantage of the dcbz instruction.  */
++
++#include <sysdep.h>
++
++	.section ".toc","aw"
++.LC0:
++	.tc __cache_line_size[TC],__cache_line_size
++	.section ".text"
++	.align 2
++
++	.section ".text"
++EALIGN (memset, 6, 0)
++	CALL_MCOUNT 3
++
++#define rTMP	r0
++#define rCNT	r0
++#define rMEMP0	r3	/* original value of 1st arg.  */
++#define rCHR	r4	/* char to set in each byte.  */
++#define rLEN	r5	/* length of region to set.  */
++#define rMEMP	r6	/* address at which we are storing.  */
++#define rALIGN	r7	/* number of bytes we are setting now
++			   (when aligning).  */
++#define rTMP2	r8
++#define rMEMP2	r9
++#define rPOS64	r10	/* constant +64 for clearing with dcbzl.  */
++#define rPOS128	r11	/* constant +128 for clearing with dcbzl.  */
++#define rNEG128	r11	/* constant -128 for clearing with dcbzl.  */
++#define rPOS192	r12	/* constant +192 for clearing with dcbzl.  */
++#define rNEG192	r12	/* constant -192 for clearing with dcbzl.  */
++#define rCLS	r11
++#define rGOT	r12
++
++L(_memset):
++	/* For sizes < 8 bytes, do it in a combination of
++	   word/half word/byte stores.  */
++	cmpldi	cr1, rLEN, 7
++	mtcrf	0x01, rLEN
++	add	rMEMP2, rMEMP0, rLEN
++	ble	cr1, L(upTo7Bytes)
++	/* For sizes < 32 bytes, do it in a combination of double word,
++	   word, half word and byte stores.  */
++	cmpldi	cr5, rLEN, 31
++	rlwimi	rCHR, rCHR, 8, 16, 23	/* Replicate byte to halfword.  */
++	rlwimi	rCHR, rCHR, 16, 0, 15	/* Replicate half word to word.  */
++	ble	cr5, L(nAupTo31Bytes)
++	/* Get the destination address double word aligned.  */
++	mr	rMEMP, rMEMP0
++	andi.	rALIGN, rMEMP, 7
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word.  */
++	beq	L(DwAligned)
++	andi.	rTMP, rMEMP, 4
++	subfic	rALIGN, rALIGN, 8
++	/* By now, we know that there are at least 7 bytes to memset and
++	   the destination address is not double word aligned.  Do not
++	   bother about non-alignment and do a one word store at once and
++	   word align the destination address.  The penalty for non-aligned
++	   store is less compared to the if-else checks and related code.  */
++	stw	rCHR, 0(rMEMP0)
++	sub	rLEN, rLEN, rALIGN
++	add	rMEMP, rMEMP, rALIGN
++	bne	L(DwAligned)
++	stw	rCHR, -4(rMEMP)
++L(DwAligned):
++	/* Now the destination address is double word aligned.  For sizes
++	   512 > size >= 32, do the memset in a combination of
++	   64 bytes/32 bytes.  For this size range, the overhead in getting
++	   the destination address cache aligned is more compared to the
++	   advantage of setting cache line size (64) bytes per iteration.
++	   But for the memset of zero value case, since we use 'dcbzl'
++	   instruction to clear entire cache line, we can set cache lines for
++	   sizes >= 128 bytes.  */
++	cmpldi	cr5, rLEN, 128
++	cmpldi	cr1, rCHR, 0
++	blt	cr5, L(Upto511Bytes)
++	srdi.	rTMP, rLEN, 10
++	beq	cr1, L(SetCacheLines)
++	bne	L(SetCacheLines)
++L(Upto511Bytes):
++	srdi.	rTMP2, rLEN, 6
++	mtcrf	0x02, rLEN
++	beq	L(DwA8WordSet)
++	mtctr	rTMP2
++	/* Store 64 bytes at one go.  */
++L(DwA16WordSet):
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	std	rCHR, 16(rMEMP)
++	std	rCHR, 24(rMEMP)
++	std	rCHR, 32(rMEMP)
++	std	rCHR, 40(rMEMP)
++	std	rCHR, 48(rMEMP)
++	std	rCHR, 56(rMEMP)
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(DwA16WordSet)
++	/* Store 32 bytes at one go.  */
++L(DwA8WordSet):
++	rldicl.	rLEN, rLEN, 0, 59
++	bf	cr6*4+2, L(Upto31Bytes)
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	std	rCHR, 16(rMEMP)
++	std	rCHR, 24(rMEMP)
++	addi	rMEMP, rMEMP, 32
++	beqlr
++	b	L(Upto31Bytes)
++
++L(SetCacheLines):
++	neg	rTMP2, rMEMP
++	andi.	rALIGN, rTMP2, 60
++	beq	L(CacheAligned)
++	add	rMEMP, rMEMP, rALIGN
++	/* The cr6 and cr7 fields together will hold the number of bytes
++	   to set to make the destination address cache line aligned.  */
++	mtcrf	0x03, rALIGN
++	sub	rLEN, rLEN, rALIGN
++	cmpldi	cr1, rALIGN, 32
++	mr	rMEMP2, rMEMP
++	bf	cr6*4+3, L(a1)
++	std	rCHR, -8(rMEMP2)
++	stdu	rCHR, -16(rMEMP2)
++L(a1):
++	blt	cr1, L(a2)
++	std	rCHR, -8(rMEMP2)
++	std	rCHR, -16(rMEMP2)
++	std	rCHR, -24(rMEMP2)
++	stdu	rCHR, -32(rMEMP2)
++L(a2):
++	bf	cr7*4, L(CacheAligned)
++	std	rCHR, -8(rMEMP2)
++	/* Now the address is aligned to cache line boundary.  */
++L(CacheAligned):
++	ld	rCLS, .LC0@toc(r2)
++	lwz	rCLS, 0(rCLS)
++	/* The data cache instructions should be used only if the cache
++	   line size is 64 bytes.  This check is required to not to break
++	   the memset when this code is being verified on machines having
++	   cache line size other than 64 bytes.  */
++	cmpldi	cr5, rCLS, 64
++	cmpldi	cr1, rCHR, 0
++	bne	cr5, L(NonDcbzLoopStart)
++	beq	cr1, L(zLoopStart)
++L(nzLoopStart):
++	srdi	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	rldicl	rLEN, rLEN, 0, 58	/* n = n % CACHE_LINE_SIZE.  */
++	sldi	rMEMP2, rALIGN, 6
++	cmplwi	cr1, rALIGN, 8192
++	add	rMEMP, rMEMP, rMEMP2
++	li	rNEG192, -0xc0
++	subic	rCNT, rALIGN, 1024
++	ble	cr1, L(nzLoopBigDone)
++	mtctr	rCNT
++	b	L(nzLoopBig)
++	.align 6
++	/* Memset 64 bytes per iteration.  */
++L(nzLoopBig):
++	/* The 'dcbzl' here clears the entire cache line and hints the core
++	   that the data in the <rNEG192+rMEMP> cache block is new and hence
++	   no need to fetch the block from either L2 cache or main memory
++	   and that will save us some cycles.  */
++	dcbzl	rNEG192, rMEMP
++	std	rCHR, -8(rMEMP)
++	std	rCHR, -16(rMEMP)
++	std	rCHR, -24(rMEMP)
++	std	rCHR, -32(rMEMP)
++	std	rCHR, -40(rMEMP)
++	std	rCHR, -48(rMEMP)
++	std	rCHR, -56(rMEMP)
++	stdu	rCHR, -64(rMEMP)
++	bdnz	L(nzLoopBig)
++	li	rALIGN, 1024
++L(nzLoopBigDone):
++	cmpldi	cr5, rALIGN, 768
++	subic	rCNT, rALIGN, 32
++	cmpldi	cr1, rALIGN, 0
++	ble	cr5, L(nzLoopMediumDone)
++	li	rNEG128, -0x80
++	mtctr	rCNT
++L(nzLoopMedium):
++	dcbtst	rNEG128, rMEMP
++	std	rCHR, -8(rMEMP)
++	std	rCHR, -16(rMEMP)
++	std	rCHR, -24(rMEMP)
++	std	rCHR, -32(rMEMP)
++	std	rCHR, -40(rMEMP)
++	std	rCHR, -48(rMEMP)
++	std	rCHR, -56(rMEMP)
++	stdu	rCHR, -64(rMEMP)
++	bdnz	L(nzLoopMedium)
++	li	rALIGN, 32
++L(nzLoopMediumDone):
++	srdi.	rTMP2, rLEN, 5
++	beq	cr1, L(nzLoopSmallDone)
++	mtctr	rALIGN
++	/* Like above, memset 64 bytes per iteration but do not use the
++	   'dcbzl' instruction because using it will cost more than cache
++	   prefetching for small number of cache blocks.  */
++L(nzLoopSmall):
++	std	rCHR, -8(rMEMP)
++	std	rCHR, -16(rMEMP)
++	std	rCHR, -24(rMEMP)
++	std	rCHR, -32(rMEMP)
++	std	rCHR, -40(rMEMP)
++	std	rCHR, -48(rMEMP)
++	std	rCHR, -56(rMEMP)
++	stdu	rCHR, -64(rMEMP)
++	bdnz	L(nzLoopSmall)
++L(nzLoopSmallDone):
++	/* Memset the residual bytes.  */
++	add	rMEMP, rMEMP, rMEMP2
++	beq	L(Upto31Bytes)
++	andi.	rLEN, rLEN, 31
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	std	rCHR, 16(rMEMP)
++	std	rCHR, 24(rMEMP)
++	addi	rMEMP, rMEMP, 32
++	beqlr
++	b	L(Upto31Bytes)
++
++	/* We are here because the cache line size is not 64 bytes.  Memset
++	   64 bytes per each iteration without using the data cache
++	   instructions.  */
++	.align 6
++L(NonDcbzLoopStart):
++	srdi.	rALIGN, rLEN, 6		/* Number of cache line size
++					   blocks = n / CACHE_LINE_SIZE.  */
++	beq	L(NonDcbzLoopDone)
++	rldicl	rLEN, rLEN, 0, 58	/* n = n % CACHE_LINE_SIZE.  */
++	mtctr	rALIGN
++L(NonDcbzLoop):
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	std	rCHR, 16(rMEMP)
++	std	rCHR, 24(rMEMP)
++	std	rCHR, 32(rMEMP)
++	std	rCHR, 40(rMEMP)
++	std	rCHR, 48(rMEMP)
++	std	rCHR, 56(rMEMP)
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(NonDcbzLoop)
++L(NonDcbzLoopDone):
++	/* Memset the residual bytes.  */
++	srdi.	rTMP2, rLEN, 5
++	beq	L(Upto31Bytes)
++	andi.	rLEN, rLEN, 31
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	std	rCHR, 16(rMEMP)
++	std	rCHR, 24(rMEMP)
++	addi	rMEMP, rMEMP, 32
++	beqlr
++	b	L(Upto31Bytes)
++
++	.align 6
++	/* Memset of 7 bytes or less.  */
++L(upTo7Bytes):
++	cmpldi	cr5, rLEN, 2
++	bf	cr7*4+3, L(b1)
++	stbu	rCHR, -1(rMEMP2)
++	bltlr	cr5
++L(b1):
++	rlwimi	rCHR, rCHR, 8, 16, 23	/* Replicate byte to halfword.  */
++	bf	cr7*4+2, L(b2)
++	sthu	rCHR, -2(rMEMP2)
++	bflr	cr7*4+1
++L(b2):
++	rlwimi	rCHR, rCHR, 16, 0, 15	/* Replicate half word to word.  */
++	bflr	cr7*4+1
++	stw	rCHR, -4(rMEMP2)
++	blr
++
++	.align 6
++	/* Memset of 0-31 bytes.  This code gets invoked only when the
++	   size, which is not the tail bytes size, is less than 32 bytes.  */
++L(nAupTo31Bytes):
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word.  */
++	cmplwi	cr1, rLEN, 16
++	bf	cr7*4+3, L(nA2)
++	stbu	rCHR, -1(rMEMP2)
++L(nA2):
++	bf	30, L(nA4)
++	sthu	rCHR, -2(rMEMP2)
++L(nA4):
++	bf	29, L(nA8)
++	stwu	rCHR, -4(rMEMP2)
++L(nA8):
++	std	rCHR, -8(rMEMP2)
++	bltlr	cr1
++	std	rCHR, -16(rMEMP2)
++	bflr	28
++	std	rCHR, -24(rMEMP2)
++	blr
++
++	/* Clear cache lines of memory in 256-byte chunks per iteration
++	   using the data cache block zero line instruction.  */
++	.align 6
++L(zLoopStart):
++	cmpldi	cr5, rLEN, 256
++	andi.	rTMP, rLEN, 128
++	li	rPOS64, 64
++	blt	cr5, L(zLoopDone)
++	li	rPOS128, 128
++	li	rPOS192, 192
++L(zLoop):
++	subic	rLEN, rLEN, 256
++	dcbzl	0, rMEMP
++	cmpldi	cr1, rLEN, 256
++	dcbzl	rPOS64, rMEMP
++	dcbzl	rPOS128, rMEMP
++	dcbzl	rPOS192, rMEMP
++	addi	rMEMP, rMEMP, 256
++	bge	cr1, L(zLoop)
++L(zLoopDone):
++	beq	L(z1)
++	dcbzl	0, rMEMP
++	dcbzl	rPOS64, rMEMP
++	addi	rMEMP, rMEMP, 128
++L(z1):
++	andi.	rTMP2, rLEN, 64
++	beq	L(z0)
++	dcbzl	0, rMEMP
++	addi	rMEMP, rMEMP, 64
++L(z0):
++	/* Memset the residual bytes.  */
++	andi.	rTMP2, rLEN, 32
++	rldicl	rLEN, rLEN, 0, 59
++	beq	L(Upto31Bytes)
++	rldicl.	rLEN, rLEN, 0, 59
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	std	rCHR, 16(rMEMP)
++	std	rCHR, 24(rMEMP)
++	beqlr
++	addi	rMEMP, rMEMP, 32
++	b	L(Upto31Bytes)
++
++	/* Memset of 0-31 bytes.  */
++	.align 6
++L(Upto31Bytes):
++	mtcrf	0x01, rLEN
++	cmpldi	cr1, rLEN, 16
++	add	rMEMP, rMEMP, rLEN
++	bt	cr7*4+3, L(b31t)
++	bt	cr7*4+2, L(b30t)
++L(b30f):
++	bt	cr7*4+1, L(b29t)
++L(b29f):
++	bge	cr1, L(b27t)
++	bflr	cr7*4
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	blr
++
++L(b31t):
++	stbu	rCHR, -1(rMEMP)
++	bf	cr7*4+2, L(b30f)
++L(b30t):
++	sthu	rCHR, -2(rMEMP)
++	bf	cr7*4+1, L(b29f)
++L(b29t):
++	stwu	rCHR, -4(rMEMP)
++	blt	cr1, L(b27f)
++L(b27t):
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	stw	rCHR, -12(rMEMP)
++	stwu	rCHR, -16(rMEMP)
++L(b27f):
++	bflr	cr7*4
++L(b28t):
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	blr
++
++END (memset)
++libc_hidden_builtin_def (memset)
++
++#ifndef NO_BZERO_IMPL
++	/* Copied from bzero.S to prevent the linker from inserting a stub
++	   between bzero and memset.  */
++ENTRY (__bzero)
++	CALL_MCOUNT 3
++	mr	r5, r4
++	li	r4, 0
++	b	L(_memset)
++
++END_GEN_TB (__bzero, TB_TOCLESS)
++weak_alias (__bzero, bzero)
++#endif
++
diff --git a/recipes-core/glibc/glibc-fsl/0011.glibc.fsl-mset-e6500.patch b/recipes-core/glibc/glibc-fsl/0011.glibc.fsl-mset-e6500.patch
new file mode 100755
index 0000000..51a0a0a
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0011.glibc.fsl-mset-e6500.patch
@@ -0,0 +1,537 @@
+# Problem Statement:
+  Implement target specific optimized memset for e6500 [32 & 64 bit]
+
+# Owned by:
+  Rohit
+
+# Actions:
+  * Used altivec instructions to generate optimized performance.
+  * for memset zero, made use of 'dcbzl' cache management instruction.
+
+diff -Naur glibc-2.20/sysdeps/powerpc/powerpc32/e6500/memset.S glibc-2.20-mset/sysdeps/powerpc/powerpc32/e6500/memset.S
+--- glibc-2.20/sysdeps/powerpc/powerpc32/e6500/memset.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mset/sysdeps/powerpc/powerpc32/e6500/memset.S	2015-07-08 04:33:07.395952006 -0500
+@@ -0,0 +1,257 @@
++/* Optimized memset implementation for e6500 32-bit PowerPC.
++
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
++   Returns 's'.  */
++
++#define rTMP	r0
++#define rRTN	r3	/* initial value of 1st argument.  */
++#define rMEMP0	r3	/* original value of 1st arg.  */
++#define rCHR	r4	/* char to set in each byte.  */
++#define rLEN	r5	/* length of region to set.  */
++#define rMEMP	r6	/* address at which we are storing.  */
++#define rALIGN	r7	/* no. of bytes we are setting now (when aligning).  */
++#define rPOS16	r7	/* constant +16.  */
++#define rPOS32	r8	/* constant +32.  */
++#define rPOS48	r9	/* constant +48.  */
++#define rGOT	r9	/* Address of the Global Offset Table.  */
++#define rCLS	r9	/* Cache line size obtained from static.  */
++#define rCTR2	r7
++#define rCTR1	r11
++#define rTMP1	r12
++#define vCHR	v14	/* char to set in each byte.  */
++#define vTMP1	v15
++#define vTMP2	v16
++
++	.section ".text"
++EALIGN (memset, 5, 1)
++	cmplwi	cr1, rLEN, 4
++	cmplwi	cr5, rLEN, 32
++	mr	rMEMP, rMEMP0
++	ble	cr1, L(small)
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	rlwimi	rCHR, rCHR, 16, 0, 15
++	blt	cr5, L(medium)
++	neg	rTMP, rMEMP
++	andi.	rTMP, rTMP, 15
++	bne	L(nalign16)
++L(align16):
++	cmplwi	7, rLEN, 63
++	rlwinm.	rTMP1, rCHR, 28, 28, 3
++	li	rPOS16, 16
++	ble	7, L(copy_remaining)
++	beq	L(check_cache_line_size)
++L(vec_nz):
++	srwi	rCTR1, rLEN, 6		/* No of 64 byte copy count.  */
++	rlwinm	rLEN, rLEN, 0, 26, 31	/* remaining bytes.  */
++	vxor	vCHR, vCHR, vCHR
++	mtctr	rCTR1			/* move count.  */
++	lvsl	vCHR, 0, rTMP1		/* LSU Move upper
++					   nibble to byte 0 of VR.  */
++	vspltisb	vTMP1, 4	/* VPU Splat 0x4 to every byte.  */
++	lvsl	vTMP2, 0, rCHR		/* LSU Move lower
++					   nibble to byte 0 of VR.  */
++	vslb	vCHR, vCHR, vTMP1	/* VIU Move upper nibble to VR[0:3].  */
++	vor	vCHR, vCHR, vTMP2	/* VIU Form FILL byte in VR[0:7].  */
++	vspltb	vCHR, vCHR, 0		/* VPU Splat the fill
++					   byte to all bytes.  */
++	li	rPOS32, 32
++	li	rPOS48, 48
++L(vnz_loop):
++	stvx	vCHR, 0, rMEMP
++	stvx	vCHR, rPOS16, rMEMP
++	stvx	vCHR, rPOS32, rMEMP
++	stvx	vCHR, rPOS48, rMEMP
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(vnz_loop)
++L(copy_remaining):
++	srwi.	rCTR1, rLEN, 3		/* No of 8 byte copy count.  */
++	rlwinm	rLEN, rLEN, 0, 29, 31	/* remaining bytes.  */
++	cmplwi	cr1, rLEN, 1
++	bne	0, L(copy_words)
++L(copy_bytes):
++	bltlr	cr1
++	cmplwi	cr0, rLEN, 4
++	beq	cr1, 2f			/* nb <= 1? (0, 1 bytes).  */
++	bgt	cr0, 1f			/* nb > 4?  (5, 6, 7 bytes).  */
++	addi	rTMP, rLEN, -2		/* 2, 3, 4 bytes.  */
++	sth	rCHR, 0(rMEMP)
++	sthx	rCHR, rMEMP, rTMP
++	blr
++1:
++	addi	rTMP, rLEN, -4		/* 5, 6, 7 bytes.  */
++	stw	rCHR, 0(rMEMP)
++	stwx	rCHR, rMEMP, rTMP
++	blr
++2:	stb	rCHR, 0(rMEMP)
++	blr
++
++L(copy_words):
++	mtcrf	0x01, rCTR1
++	bf	cr7*4+1, 16f
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	stw	rCHR, 16(rMEMP)
++	stw	rCHR, 20(rMEMP)
++	stw	rCHR, 24(rMEMP)
++	stw	rCHR, 28(rMEMP)
++	addi	rMEMP, rMEMP, 32
++16:
++	bf	cr7*4+2, 8f
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	addi	rMEMP, rMEMP, 16
++8:
++	bf	cr7*4+3, L(copy_bytes)
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	bltlr	cr1
++	addi	rMEMP, rMEMP, 8
++	b	L(copy_bytes)
++
++	.align 5
++L(check_cache_line_size):
++#ifdef	SHARED
++	mflr	rTMP
++/* Establishes GOT addressability so we can load __cache_line_size
++   from static.  This value was set from the aux vector during startup.  */
++	SETUP_GOT_ACCESS(rGOT,got_label_1)
++	addis	rGOT, rGOT, __cache_line_size-got_label_1@ha
++	lwz	rCLS, __cache_line_size-got_label_1@l(rGOT)
++	mtlr	rTMP
++#else
++/* Load __cache_line_size from static.  This value was set from the
++   aux vector during startup.  */
++	lis	rCLS, __cache_line_size@ha
++	lwz	rCLS, __cache_line_size@l(rCLS)
++#endif
++	cmplwi	5, rCLS, 64
++	neg	rTMP, rMEMP
++	bne	5, L(vec_nz)
++	andi.	rTMP, rTMP, 63
++	bne	L(nalign64)
++L(align64):
++	srwi	rCTR1, rLEN, 6
++	cmplwi	7, rCTR1, 32767
++	rlwinm	rLEN, rLEN, 0, 26, 31
++	mtctr	rCTR1
++	bgt	7, L(vec_zbig)
++L(vz_loop):
++	dcbzl	0, rMEMP
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(vz_loop)
++	b	L(copy_remaining)
++
++L(vec_zbig):
++	addi	rCTR2, rCTR1, -32767
++	mtctr	rCTR2
++L(vz_big_loop):
++	dcbzl	0, rMEMP
++	dcbf	0, rMEMP
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(vz_big_loop)
++	li	rCTR1, 32767
++	mtctr	rCTR1
++	b	L(vz_loop)
++
++L(nalign64):
++	vxor	vCHR, vCHR, vCHR
++	subf	rLEN, rTMP, rLEN
++	li	rPOS48, 48
++	li	rPOS32, 32
++	stvx	vCHR, 0, rMEMP
++	stvx	vCHR, rPOS16, rMEMP
++	cmplwi	7, rLEN, 64
++	stvx	vCHR, rPOS32, rMEMP
++	stvx	vCHR, rPOS48, rMEMP
++	add	rMEMP, rMEMP, rTMP
++	blt	7, L(copy_remaining)
++	b	L(align64)
++
++L(nalign16):
++	stw	rCHR, 0(rMEMP)
++	stw	rCHR, 4(rMEMP)
++	subf	rLEN, rTMP, rLEN
++	stw	rCHR, 8(rMEMP)
++	stw	rCHR, 12(rMEMP)
++	add	rMEMP, rMEMP, rTMP
++	b	L(align16)
++
++	.align 5
++	/* Memset of 0-4 bytes.  Taken from GLIBC default memset.  */
++L(small):
++	cmplwi	cr5, rLEN, 1
++	cmplwi	cr1, rLEN, 3
++	bltlr	cr5
++	stb	rCHR, 0(rMEMP)
++	beqlr	cr5
++	nop
++	stb	rCHR, 1(rMEMP)
++	bltlr	cr1
++	stb	rCHR, 2(rMEMP)
++	beqlr	cr1
++	nop
++	stb	rCHR, 3(rMEMP)
++	blr
++
++	/* Memset of 0-31 bytes.  Taken from GLIBC default memset.  */
++	.align 5
++L(medium):
++	mtcrf	0x01, rLEN
++	cmplwi	cr1, rLEN, 16
++	add	rMEMP, rMEMP, rLEN
++	bt	31, L(medium_31t)
++	bt	30, L(medium_30t)
++L(medium_30f):
++	bt	29, L(medium_29t)
++L(medium_29f):
++	bge	cr1, L(medium_27t)
++	bflr	28
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	blr
++L(medium_31t):
++	stbu	rCHR, -1(rMEMP)
++	bf	30, L(medium_30f)
++L(medium_30t):
++	sthu	rCHR, -2(rMEMP)
++	bf	29, L(medium_29f)
++L(medium_29t):
++	stwu	rCHR, -4(rMEMP)
++	blt	cr1, L(medium_27f)
++L(medium_27t):
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	stw	rCHR, -12(rMEMP)
++	stwu	rCHR, -16(rMEMP)
++L(medium_27f):
++	bflr	28
++L(medium_28t):
++	stw	rCHR, -4(rMEMP)
++	stw	rCHR, -8(rMEMP)
++	blr
++
++END (memset)
++libc_hidden_builtin_def (memset)
+diff -Naur glibc-2.20/sysdeps/powerpc/powerpc64/e6500/memset.S glibc-2.20-mset/sysdeps/powerpc/powerpc64/e6500/memset.S
+--- glibc-2.20/sysdeps/powerpc/powerpc64/e6500/memset.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mset/sysdeps/powerpc/powerpc64/e6500/memset.S	2015-07-08 04:28:48.089952006 -0500
+@@ -0,0 +1,262 @@
++/* Optimized memset implementation for e6500 64-bit PowerPC.
++
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#define rTMP	r0
++#define rRTN	r3	/* initial value of 1st argument.  */
++#define rMEMP0	r3	/* original value of 1st arg.  */
++#define rCHR	r4	/* char to set in each byte.  */
++#define rLEN	r5	/* length of region to set.  */
++#define rMEMP	r6	/* address at which we are storing.  */
++#define rALIGN	r7	/* no. of bytes we are setting now (when aligning).  */
++#define rPOS16	r7	/* constant +16.  */
++#define rPOS32	r8	/* constant +32.  */
++#define rPOS48	r9	/* constant +48.  */
++#define rGOT	r9	/* Address of the Global Offset Table.  */
++#define rCLS	r9	/* Cache line size obtained from static.  */
++#define rCTR2	r7
++#define rCTR1	r11
++#define rTMP1	r12
++#define vCHR	v14	/* char to set in each byte.  */
++#define vTMP1	v15
++#define vTMP2	v16
++
++#include <sysdep.h>
++
++	.section ".toc", "aw"
++.LC0:
++	.tc __cache_line_size[TC], __cache_line_size
++	.section ".text"
++	.align 2
++
++/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
++   Returns 's'.  */
++
++EALIGN (memset, 5, 0)
++	CALL_MCOUNT 3
++L(_memset):
++	cmpldi	cr1, rLEN, 8
++	cmpldi	cr5, rLEN, 32
++	mr	rMEMP, rMEMP0
++	ble	cr1, L(small)
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	rlwimi	rCHR, rCHR, 16, 0, 15
++	blt	cr5, L(medium)
++	neg	rTMP, rMEMP
++	andi.	rTMP, rTMP, 15
++	bne	L(nalign16)
++L(align16):
++	cmpldi	7, rLEN, 63
++	rlwinm.	rTMP1, rCHR, 28, 28, 3
++	li	rPOS16, 16
++	ble	7, L(copy_remaining)
++	beq	L(check_cache_line_size)
++L(vec_nz):
++	srwi	rCTR1, rLEN, 6		/* No of 64 byte copy count.  */
++	rlwinm	rLEN, rLEN, 0, 26, 31	/* remaining bytes.  */
++	vxor	vCHR, vCHR, vCHR
++	mtctr	rCTR1			/* move count.  */
++	lvsl	vCHR, 0, rTMP1		/* LSU Move upper nibble
++					   to byte 0 of VR.  */
++	vspltisb	vTMP1, 4	/* VPU Splat 0x4 to every byte.  */
++	lvsl	vTMP2, 0, rCHR		/* LSU Move lower nibble
++					   to byte 0 of VR.  */
++	vslb	vCHR, vCHR, vTMP1	/* VIU Move upper nibble to VR[0:3].  */
++	vor	vCHR, vCHR, vTMP2	/* VIU Form FILL byte in VR[0:7].  */
++	vspltb	vCHR, vCHR, 0		/* VPU Splat the fill
++					   byte to all bytes.  */
++	li	rPOS32, 32
++	li	rPOS48, 48
++L(vnz_loop):
++	stvx	vCHR, 0, rMEMP
++	stvx	vCHR, rPOS16, rMEMP
++	stvx	vCHR, rPOS32, rMEMP
++	stvx	vCHR, rPOS48, rMEMP
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(vnz_loop)
++L(copy_remaining):
++	srwi.	rCTR1, rLEN, 3		/* No of 8 byte copy count.  */
++	rlwinm	rLEN, rLEN, 0, 29, 31	/* remaining bytes.  */
++	cmpldi	cr1, rLEN, 1
++	bne	0, L(copy_words)
++L(copy_bytes):
++	bltlr	cr1
++	cmpldi	cr0, rLEN, 4
++	beq	cr1, 2f			/* nb <= 1? (0, 1 bytes).  */
++	bgt	cr0, 1f			/* nb > 4?  (5, 6, 7 bytes).  */
++	addi	rTMP, rLEN, -2		/* 2, 3, 4 bytes.  */
++	sth	rCHR, 0(rMEMP)
++	sthx	rCHR, rMEMP, rTMP
++	blr
++1:
++	addi	rTMP, rLEN, -4		/* 5, 6, 7 bytes.  */
++	stw	rCHR, 0(rMEMP)
++	stwx	rCHR, rMEMP, rTMP
++	blr
++2:	stb	rCHR, 0(rMEMP)
++	blr
++
++L(copy_words):
++	mtcrf	0x01, rCTR1
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word.  */
++	bf	cr7*4+1, 16f
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	std	rCHR, 16(rMEMP)
++	std	rCHR, 24(rMEMP)
++	addi	rMEMP, rMEMP, 32
++16:
++	bf	cr7*4+2, 8f
++	std	rCHR, 0(rMEMP)
++	std	rCHR, 8(rMEMP)
++	addi	rMEMP, rMEMP, 16
++8:
++	bf	cr7*4+3, L(copy_bytes)
++	std	rCHR, 0(rMEMP)
++	addi	rMEMP, rMEMP, 8
++	b	L(copy_bytes)
++
++	.align 5
++L(check_cache_line_size):
++	ld	rCLS, .LC0@toc(r2)
++	lwz	rCLS, 0(rCLS)
++	cmpldi	5, rCLS, 64
++	neg	rTMP, rMEMP
++	bne	5, L(vec_nz)
++	andi.	rTMP, rTMP, 63
++	bne	L(nalign64)
++L(align64):
++	srwi	rCTR1, rLEN, 6
++	cmpldi	7, rCTR1, 32767
++	rlwinm	rLEN, rLEN, 0, 26, 31
++	mtctr	rCTR1
++	bgt	7, L(vec_zbig)
++L(vz_loop):
++	dcbzl	0, rMEMP
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(vz_loop)
++	b	L(copy_remaining)
++
++L(vec_zbig):
++	addi	rCTR2, rCTR1, -32767
++	mtctr	rCTR2
++L(vz_big_loop):
++	dcbzl	0, rMEMP
++	dcbf	0, rMEMP
++	addi	rMEMP, rMEMP, 64
++	bdnz	L(vz_big_loop)
++	li	rCTR1, 32767
++	mtctr	rCTR1
++	b	L(vz_loop)
++
++L(nalign64):
++	vxor	vCHR, vCHR, vCHR
++	subf	rLEN, rTMP, rLEN
++	li	rPOS48, 48
++	li	rPOS32, 32
++	stvx	vCHR, 0, rMEMP
++	stvx	vCHR, rPOS16, rMEMP
++	cmpldi	7, rLEN, 64
++	stvx	vCHR, rPOS32, rMEMP
++	stvx	vCHR, rPOS48, rMEMP
++	add	rMEMP, rMEMP, rTMP
++	blt	7, L(copy_remaining)
++	b	L(align64)
++
++L(nalign16):
++	insrdi	rCHR, rCHR, 32, 0 	/* Replicate word to double word.  */
++	std	rCHR, 0(rMEMP)
++	subf	rLEN, rTMP, rLEN
++	std	rCHR, 8(rMEMP)
++	add	rMEMP, rMEMP, rTMP
++	b	L(align16)
++
++	/* Memset of 8 bytes or less.  Taken from GLIBC default memset.  */
++	.align 5
++L(small):
++	cmpldi	cr6, rLEN, 4
++	cmpldi	cr5, rLEN, 1
++	ble	cr6, L(le4)
++	subi	rLEN, rLEN, 4
++	stb	rCHR, 0(rMEMP)
++	stb	rCHR, 1(rMEMP)
++	stb	rCHR, 2(rMEMP)
++	stb	rCHR, 3(rMEMP)
++	addi	rMEMP, rMEMP, 4
++	cmpldi	cr5, rLEN, 1
++L(le4):
++	cmpldi	cr1, rLEN, 3
++	bltlr	cr5
++	stb	rCHR, 0(rMEMP)
++	beqlr	cr5
++	stb	rCHR, 1(rMEMP)
++	bltlr	cr1
++	stb	rCHR, 2(rMEMP)
++	beqlr	cr1
++	stb	rCHR, 3(rMEMP)
++	blr
++
++	/* Memset of 0-31 bytes.  Taken from GLIBC default memset.  */
++	.align 5
++L(medium):
++	mtcrf	0x01, rLEN
++	insrdi	rCHR, rCHR, 32, 0	/* Replicate word to double word.  */
++	cmpldi	cr1, rLEN, 16
++L(medium_tail2):
++	add	rMEMP, rMEMP, rLEN
++L(medium_tail):
++	bt	31, L(medium_31t)
++	bt	30, L(medium_30t)
++L(medium_30f):
++	bt	29, L(medium_29t)
++L(medium_29f):
++	bge	cr1, L(medium_27t)
++	bflr	28
++	std	rCHR, -8(rMEMP)
++	blr
++L(medium_31t):
++	stbu	rCHR, -1(rMEMP)
++	bf	30, L(medium_30f)
++L(medium_30t):
++	sthu	rCHR, -2(rMEMP)
++	bf	29, L(medium_29f)
++L(medium_29t):
++	stwu	rCHR, -4(rMEMP)
++	blt	cr1, L(medium_27f)
++L(medium_27t):
++	std	rCHR, -8(rMEMP)
++	stdu	rCHR, -16(rMEMP)
++L(medium_27f):
++	bflr	28
++L(medium_28t):
++	std	rCHR, -8(rMEMP)
++	blr
++END_GEN_TB (memset,TB_TOCLESS)
++libc_hidden_builtin_def (memset)
++
++#ifndef	NO_BZERO_IMPL
++/* Copied from bzero.S to prevent the linker from inserting a stub
++   between bzero and memset.  */
++ENTRY (__bzero)
++	mr	r5, r4
++	li	r4, 0
++	b	L(_memset)
++END_GEN_TB (__bzero,TB_TOCLESS)
++
++weak_alias (__bzero, bzero)
++#endif
diff --git a/recipes-core/glibc/glibc-fsl/0012.glibc.fsl-mcmp-e6500.patch b/recipes-core/glibc/glibc-fsl/0012.glibc.fsl-mcmp-e6500.patch
new file mode 100755
index 0000000..88e46e7
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0012.glibc.fsl-mcmp-e6500.patch
@@ -0,0 +1,832 @@
+# Problem Statement:
+  Implement target specific optimized memcmp for e6500 [32 & 64 bit]
+
+# Owned by:
+  Rohit
+
+# Actions:
+  * Use altivec instructions to generate optimized performance.
+
+diff -Naur glibc-2.20/sysdeps/powerpc/powerpc32/e6500/memcmp.S glibc-2.20-mcmp/sysdeps/powerpc/powerpc32/e6500/memcmp.S
+--- glibc-2.20/sysdeps/powerpc/powerpc32/e6500/memcmp.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mcmp/sysdeps/powerpc/powerpc32/e6500/memcmp.S	2015-03-12 17:10:38.572951270 -0500
+@@ -0,0 +1,387 @@
++/* Optimized memcmp implementation for 32-bit e6500 PowerPC.
++
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* int [r3] memcmp (const char *s1 [r3],
++		    const char *s2 [r4],
++		    size_t size [r5])
++	r3:source1 address, return equality
++	r4:source2 address
++	r5:byte count
++
++	volatile fixed point registers usable:
++	r0, r3-r12
++
++	volatile floating point registers usable:
++	f0-f13
++
++	v0-v1 General use Volatile (caller save)
++	v2-v13 Parameters, general volatile (caller save)
++	v14-v19 General Volatile (caller save)
++
++	CR0-CR1 Volatile condition code register fields
++	CR5-CR7 Volatile condition code register fields.  */
++
++#define rTMP	r0
++#define rRTN	r3
++#define rSTR1	r3	/* first string arg.  */
++#define rSTR2	r4	/* second string arg.  */
++#define rS2OFF	r7	/* second string arg + 16.  */
++#define rN	r5
++#define rWORD1	r6	/* current word in s1.  */
++#define rWORD2	r7	/* current word in s2.  */
++#define rWORD3	r8	/* next word in s1.  */
++#define rWORD4	r9	/* next word in s2.  */
++#define rWORD5	r10	/* next word in s1.  */
++#define rWORD6	r11	/* next word in s2.  */
++#define rWORD7	r5	/* next word in s1.  */
++#define rWORD8	r12	/* next word in s2.  */
++#define rCOUNT	r11
++#define rINDEX	r8
++#define rVR0	v0
++#define rVR1	v1
++#define rVR2	v2
++#define rVR3	v3
++#define rVR4	v4
++#define rVR5	v5
++#define rVR6	v6
++#define rVR7	v7
++#define rVR8	v8
++#define rVR9	v9
++#define rVR10	v10
++#define rVR11	v11
++#define rVR14	v14
++#define rVR15	v15
++#define rVR16	v16
++#define rVR17	v17
++#define rVR18	v18
++#define rVR19	v19
++
++EALIGN (memcmp, 5, 0)
++	cmplwi	rN, 0
++	cmplwi	cr1, rN, 32
++	beq	L(zero)
++	ble	cr1, L(medium)
++	neg	rTMP, rSTR1
++	andi.	rCOUNT, rTMP, 15	/* check src1 alignment.  */
++	bne	L(src1_nalign)
++L(src1align16):
++	rlwinm.	rTMP, r4, 0, 28, 31	/* check src2 alignment.  */
++	srwi	rCOUNT, rN, 4		/* no. of bytes / 16.  */
++	cmplwi	cr5, rCOUNT, 0xFFF0	/* check for large data compares.  */
++	rlwinm	rN, rN, 0, 28, 31	/* remaining bytes.  */
++	mtctr	rCOUNT
++	li	rINDEX, 0
++	bne	L(src2_nalign)
++	bgt	cr5, L(large_align)
++L(loop_align):
++	lvx	rVR14, rSTR1, rINDEX
++	lvx	rVR15, rSTR2, rINDEX
++	addi	rINDEX, rINDEX, 16
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(loop_align)
++	cmplwi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++L(small):
++	srwi.	rCOUNT, rN, 3
++	rlwinm	rN, rN, 0, 29, 31
++	beq	L(cmp_bytes)
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++	cmplw	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 8
++	cmplwi	cr5, rN, 0
++	bne	cr0, L(bLcr0)
++	cmplw	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 8
++	bne	cr1, L(bLcr1)
++	beq	cr5, L(zero)
++	.align 4
++L(cmp_bytes):
++	mtctr	rN
++	lbz	rWORD1, 0(rSTR1)
++	lbz	rWORD2, 0(rSTR2)
++	bdz	L(b11)
++	lbz	rWORD3, 1(rSTR1)
++	lbz	rWORD4, 1(rSTR2)
++	cmplw	cr0, rWORD1, rWORD2
++	bdz	L(b12)
++	lbz	rWORD5, 2(rSTR1)
++	lbz	rWORD6, 2(rSTR2)
++	cmplw	cr1, rWORD3, rWORD4
++	bdz	L(b13)
++	lbz	rWORD7, 3(rSTR1)
++	lbz	rWORD8, 3(rSTR2)
++	bne	cr0, L(bx11)
++	cmplw	cr5, rWORD5, rWORD6
++	bdz	L(b14)
++	cmplw	cr6, rWORD7, rWORD8
++	lbz	rWORD1, 4(rSTR1)
++	lbz	rWORD2, 4(rSTR2)
++	bne	cr1, L(bx12)
++	bdz	L(b15)
++	lbz	rWORD3, 5(rSTR1)
++	lbz	rWORD4, 5(rSTR2)
++	cmplw	cr0, rWORD1, rWORD2
++	bne	cr5, L(bx13)
++	bdz	L(b16)
++	lbz	rWORD5, 6(rSTR1)
++	lbz	rWORD6, 6(rSTR2)
++	cmplw	cr1, rWORD3, rWORD4
++	bne	cr6, L(bx14)
++	bne	cr0, L(bx15)
++	bne	cr1, L(bx16)
++	sub	rRTN, rWORD5, rWORD6
++	blr
++L(b16):
++	bne	cr6, L(bx14)
++	bne	cr0, L(bx15)
++L(bx16):
++	sub	rRTN, rWORD3, rWORD4
++	blr
++L(b15):
++	bne	cr5, L(bx13)
++	bne	cr6, L(bx14)
++L(bx15):
++	sub	rRTN, rWORD1, rWORD2
++	blr
++L(b14):
++	bne	cr1, L(bx12)
++	bne	cr5, L(bx13)
++L(bx14):
++	sub	rRTN, rWORD7, rWORD8
++	blr
++L(b13):
++	bne	cr0, L(bx11)
++	bne	cr1, L(bx12)
++L(bx13):
++	sub	rRTN, rWORD5, rWORD6
++	blr
++L(b12):
++	bne	cr0, L(bx11)
++L(bx12):
++	sub	rRTN, rWORD3, rWORD4
++	blr
++L(b11):
++L(bx11):
++	sub	rRTN, rWORD1, rWORD2
++	blr
++
++	.align 4
++L(medium):
++	srwi.	rCOUNT, rN, 3
++	rlwinm	rN, rN, 0, 29, 31
++	beq	L(cmp_bytes)
++	mtctr	rCOUNT
++	cmplwi	cr5, rN, 0
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++	cmplw	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 8
++	bne	cr0, L(bLcr0)
++	cmplw	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 8
++	bne	cr1, L(bLcr1)
++	bdz	L(check_small)
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++	cmplw	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 8
++	bne	cr0, L(bLcr0)
++	cmplw	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 8
++	bne	cr1, L(bLcr1)
++	bdz	L(check_small)
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++	cmplw	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 8
++	bne	cr0, L(bLcr0)
++	cmplw	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 8
++	bne	cr1, L(bLcr1)
++	bdz	L(check_small)
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++	cmplw	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 8
++	bne	cr0, L(bLcr0)
++	cmplw	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 8
++	bne	cr1, L(bLcr1)
++	li	rRTN, 0
++	blr
++
++	.align 4
++L(check_small):
++	beq	cr5, L(zero)
++	b	L(cmp_bytes)
++
++	.align 4
++L(src1_nalign):
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++	lwz	rWORD3, 4(rSTR1)
++	lwz	rWORD4, 4(rSTR2)
++	subfc.	rWORD1, rWORD1, rWORD2
++	bne	L(Words_Differ)
++	subfc.	rWORD1, rWORD3, rWORD4
++	bne	L(Words_Differ)
++	lwz	rWORD1, 8(rSTR1)
++	lwz	rWORD2, 8(rSTR2)
++	lwz	rWORD3, 12(rSTR1)
++	lwz	rWORD4, 12(rSTR2)
++	subfc.	rWORD1, rWORD1, rWORD2
++	bne	L(Words_Differ)
++	subfc.	rWORD1, rWORD3, rWORD4
++	bne	L(Words_Differ)
++	subf	rN, rCOUNT, rN
++	cmplwi	cr7, rN, 32
++	add	rSTR1, rSTR1, rCOUNT
++	add	rSTR2, rSTR2, rCOUNT
++	ble	cr7, L(medium)
++	b	L(src1align16)
++
++	.align 4
++L(bLcr0):
++	li	rRTN, 1
++	bgtlr	cr0
++	li	rRTN, -1
++	blr
++
++	.align 4
++L(bLcr1):
++	li	rRTN, 1
++	bgtlr	cr1
++	li	rRTN, -1
++	blr
++
++	.align 4
++L(src2_nalign):
++	addi	rS2OFF, rSTR2, 16
++	bgt	cr5, L(large_nalign)
++L(loop_nalign):
++	lvx	rVR14, rSTR1, rINDEX
++	lvsl	rVR3, 0, rSTR2		/* set permute control vector.  */
++	lvx	rVR4, rS2OFF, rINDEX	/* load LSQ.  */
++	lvx	rVR2, rSTR2, rINDEX	/* load MSQ.  */
++	addi	rINDEX, rINDEX, 16
++	vperm	rVR15, rVR2, rVR4, rVR3	/* align the data.  */
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(loop_nalign)
++	cmplwi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++	b	L(small)
++
++	.align 4
++L(large_nalign):
++	lvxl	rVR14, rSTR1, rINDEX
++	lvsl	rVR3, 0, rSTR2		/* set permute control vector.  */
++	lvxl	rVR4, rS2OFF, rINDEX	/* load LSQ.  */
++	lvxl	rVR2, rSTR2, rINDEX	/* load MSQ.  */
++	addi	rINDEX, rINDEX, 16
++	vperm	rVR15, rVR2, rVR4, rVR3	/* align the data.  */
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(large_nalign)
++	cmplwi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++	b	L(small)
++
++	.align 4
++L(large_align):
++	lvxl	rVR14, rSTR1, rINDEX
++	lvxl	rVR15, rSTR2, rINDEX
++	addi	rINDEX, rINDEX, 16
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(large_align)
++	cmplwi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++	b	L(small)
++
++	.align 4
++L(Words_Differ):
++	subfe	rRTN, rWORD1, rWORD1
++	nand	rRTN, rRTN, rRTN
++	ori	rRTN, rRTN, 1
++	blr
++
++	.align 4
++L(Vwords_Differ):
++	vspltisb	rVR18, 1
++	vspltisb	rVR1, 8
++	vslb	rVR0, rVR1, rVR18
++	vslb	rVR19, rVR0, rVR18
++	vslb	rVR18, rVR19, rVR18
++	vxor	rVR5, rVR5, rVR5
++	vsum4ubs	rVR2, rVR1, rVR18
++	vsro	rVR9, rVR17, rVR19
++	vsrw	rVR19, rVR17, rVR1
++	vsro	rVR10, rVR17, rVR18
++	vsrw	rVR18, rVR17, rVR0
++	vsro	rVR0, rVR17, rVR2
++	vor	rVR11, rVR9, rVR10
++	vsro	rVR2, rVR18, rVR1
++	vor	rVR11, rVR11, rVR0
++	vcmpgtuw	rVR11, rVR11, rVR5
++	vor	rVR11, rVR11, rVR19
++	vor	rVR11, rVR11, rVR18
++	vor	rVR11, rVR11, rVR2
++	vor	rVR15, rVR15, rVR11
++	vor	rVR14, rVR14, rVR11
++	li	rRTN, -1
++	vcmpgtub.	rVR8, rVR15, rVR14
++	bnelr	cr6
++	li	rRTN, 1
++	blr
++
++	.align 4
++L(zero):
++	li	rRTN, 0
++	blr
++
++END (memcmp)
++libc_hidden_builtin_def (memcmp)
++weak_alias (memcmp, bcmp)
+diff -Naur glibc-2.20/sysdeps/powerpc/powerpc64/e6500/memcmp.S glibc-2.20-mcmp/sysdeps/powerpc/powerpc64/e6500/memcmp.S
+--- glibc-2.20/sysdeps/powerpc/powerpc64/e6500/memcmp.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mcmp/sysdeps/powerpc/powerpc64/e6500/memcmp.S	2015-03-12 17:26:44.637951961 -0500
+@@ -0,0 +1,428 @@
++/* Optimized memcmp implementation for 64-bit e6500 PowerPC.
++
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* int [r3] memcmp (const char *s1 [r3],
++		    const char *s2 [r4],
++		    size_t size [r5])
++	r3:source1 address, return equality
++	r4:source2 address
++	r5:byte count
++
++	volatile fixed point registers usable:
++	r0, r3-r12
++
++	volatile floating point registers usable:
++	f0-f13
++
++	v0-v1 General use volatile (caller save)
++	v2-v13 Parameters, general volatile (caller save)
++	v14-v19 General Volatile (caller save)
++
++	CR0-CR1 Volatile condition code register fields
++	CR5-CR7 Volatile condition code register fields.  */
++
++#define rTMP	r0
++#define rRTN	r3
++#define rSTR1	r3	/* first string arg.  */
++#define rSTR2	r4	/* second string arg.  */
++#define rS2OFF	r7	/* second string arg + 16.  */
++#define rN	r5
++#define rWORD1	r6	/* current word in s1.  */
++#define rWORD2	r7	/* current word in s2.  */
++#define rWORD3	r8	/* next word in s1.  */
++#define rWORD4	r9	/* next word in s2.  */
++#define rWORD5	r10	/* next word in s1.  */
++#define rWORD6	r11	/* next word in s2.  */
++#define rWORD7	r5	/* next word in s1.  */
++#define rWORD8	r12	/* next word in s2.  */
++#define rCOUNT	r11
++#define rINDEX	r8
++#define rVR0	v0
++#define rVR1	v1
++#define rVR2	v2
++#define rVR3	v3
++#define rVR4	v4
++#define rVR5	v5
++#define rVR6	v6
++#define rVR7	v7
++#define rVR8	v8
++#define rVR9	v9
++#define rVR10	v10
++#define rVR11	v11
++#define rVR14	v14
++#define rVR15	v15
++#define rVR16	v16
++#define rVR17	v17
++#define rVR18	v18
++#define rVR19	v19
++
++EALIGN (memcmp, 5, 0)
++	CALL_MCOUNT 3
++	cmpldi	rN, 0
++	cmpldi	cr1, rN, 16
++	cmpldi	cr5, rN, 64
++	beq	L(zero)
++	blt	cr1, L(small)
++	ble	cr5, L(medium)
++	neg	rTMP, rSTR1
++	andi.	rCOUNT, rTMP, 15	/* check src1 alignment.  */
++	bne	L(src1_nalign)
++L(src1align16):
++	rlwinm.	rTMP, rSTR2, 0, 28, 31	/* check src2 alignment.  */
++	bne	L(src2_nalign)
++	srdi	rCOUNT, rN, 4		/* nb / 16.  */;
++	cmpldi	cr5, rCOUNT, 0xFFF0	/* check for large data compares.  */
++	rlwinm	rN, rN, 0, 28, 31	/* remaining bytes.  */
++	mtctr	rCOUNT
++	li	rINDEX, 0
++	bgt	cr5, L(large_align)
++	.align 4
++L(loop_align):
++	lvx	rVR14, rSTR1, rINDEX
++	lvx	rVR15, rSTR2, rINDEX
++	addi	rINDEX, rINDEX, 16
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(loop_align)
++	cmpldi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++	.align 4
++L(small):
++	srdi.	rCOUNT, rN, 3
++	rlwinm	rN, rN, 0, 29, 31
++	beq	L(cmp_bytes)
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	cmpldi	cr1, rN, 0
++	addi	rSTR1, rSTR1, 8
++	addi	rSTR2, rSTR2, 8
++	bne	cr0, L(bLcr0)
++	beq	cr1, L(zero)
++	.align 4
++L(cmp_bytes):
++	mtctr	rN
++	lbz	rWORD1, 0(rSTR1)
++	lbz	rWORD2, 0(rSTR2)
++	bdz	L(b11)
++	lbz	rWORD3, 1(rSTR1)
++	lbz	rWORD4, 1(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	bdz	L(b12)
++	lbz	rWORD5, 2(rSTR1)
++	lbz	rWORD6, 2(rSTR2)
++	cmpld	cr1, rWORD3, rWORD4
++	bdz	L(b13)
++	lbz	rWORD7, 3(rSTR1)
++	lbz	rWORD8, 3(rSTR2)
++	bne	cr0, L(bx11)
++	cmpld	cr5, rWORD5, rWORD6
++	bdz	L(b14)
++	cmpld	cr6, rWORD7, rWORD8
++	lbz	rWORD1, 4(rSTR1)
++	lbz	rWORD2, 4(rSTR2)
++	bne	cr1, L(bx12)
++	bdz	L(b15)
++	lbz	rWORD3, 5(rSTR1)
++	lbz	rWORD4, 5(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	bne	cr5, L(bx13)
++	bdz	L(b16)
++	lbz	rWORD5, 6(rSTR1)
++	lbz	rWORD6, 6(rSTR2)
++	cmpld	cr1, rWORD3, rWORD4
++	bne	cr6, L(bx14)
++	bne	cr0, L(bx15)
++	bne	cr1, L(bx16)
++	sub	rRTN, rWORD5, rWORD6
++	blr
++L(b16):
++	bne	cr6, L(bx14)
++	bne	cr0, L(bx15)
++L(bx16):
++	sub	rRTN, rWORD3, rWORD4
++	blr
++L(b15):
++	bne	cr5, L(bx13)
++	bne	cr6, L(bx14)
++L(bx15):
++	sub	rRTN, rWORD1, rWORD2
++	blr
++L(b14):
++	bne	cr1, L(bx12)
++	bne	cr5, L(bx13)
++L(bx14):
++	sub	rRTN, rWORD7, rWORD8
++	blr
++L(b13):
++	bne	cr0, L(bx11)
++	bne	cr1, L(bx12)
++L(bx13):
++	sub	rRTN, rWORD5, rWORD6
++	blr
++L(b12):
++	bne	cr0, L(bx11)
++L(bx12):
++	sub	rRTN, rWORD3, rWORD4
++	blr
++L(b11):
++L(bx11):
++	sub	rRTN, rWORD1, rWORD2
++	blr
++
++	.align 4
++L(medium):
++	srwi	rCOUNT, rN, 4
++	rlwinm	rN, rN, 0, 28, 31
++	mtctr	rCOUNT
++	cmpldi	cr5, rN, 0
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 16
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 16
++	bne	cr1, L(bLcr1)
++	bdz	L(check_small)
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 16
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 16
++	bne	cr1, L(bLcr1)
++	bdz	L(check_small)
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 16
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 16
++	bne	cr1, L(bLcr1)
++	bdz	L(check_small)
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 16
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 16
++	bne	cr1, L(bLcr1)
++	li	rRTN, 0
++	blr
++
++	.align 4
++L(check_small):
++	beq	cr5, L(zero)
++	b	L(small)
++
++	.align 4
++L(src1_nalign):
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	add	rSTR1, rSTR1, rCOUNT
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	add	rSTR2, rSTR2, rCOUNT
++	bne	cr1, L(bLcr1)
++	subf	rN, rCOUNT, rN
++	cmpldi	cr7, rN, 64
++	ble	cr7, L(medium)
++	b	L(src1align16)
++
++	.align 4
++L(src2_nalign):
++	rlwinm.	rTMP, rSTR2, 0, 29, 31
++	beq	cr0, L(src2_dwalign)
++	srdi	rCOUNT, rN, 4		/* n / 16.  */;
++	cmpldi	cr5, rCOUNT, 0xFFF0	/* check for large data compares.  */
++	rlwinm	rN, rN, 0, 28, 31	/* remaining bytes.  */
++	mtctr	rCOUNT
++	li	rINDEX, 0
++	addi	rS2OFF, rSTR2, 16
++	bgt	cr5, L(large_nalign)
++	.align 4
++L(loop_nalign):
++	lvx	rVR14, rSTR1, rINDEX
++	lvsl	rVR3, 0, rSTR2		/* set permute control vector.  */
++	lvx	rVR4, rS2OFF, rINDEX	/* load LSQ.  */
++	lvx	rVR2, rSTR2, rINDEX	/* load MSQ.  */
++	addi	rINDEX, rINDEX, 16
++	vperm	rVR15, rVR2, rVR4, rVR3	/* align the data.  */
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(loop_nalign)
++	cmpldi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++	b	L(small)
++
++	.align 4
++L(src2_dwalign):
++	srdi	rCOUNT, rN, 6
++	rlwinm	rN, rN, 0, 26, 31
++	mtctr	rCOUNT
++	li	rINDEX, 0
++	cmpldi	cr5, rN, 0
++	cmpldi	cr6, rN, 16
++L(dw_loop):
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	ld	rWORD3, 8(rSTR1)
++	ld	rWORD4, 8(rSTR2)
++	cmpld	cr0, rWORD1, rWORD2
++	ld	rWORD1, 16(rSTR1)
++	ld	rWORD2, 16(rSTR2)
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	ld	rWORD3, 24(rSTR1)
++	ld	rWORD4, 24(rSTR2)
++	bne	cr1, L(bLcr1)
++	cmpld	cr0, rWORD1, rWORD2
++	ld	rWORD1, 32(rSTR1)
++	ld	rWORD2, 32(rSTR2)
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	ld	rWORD3, 40(rSTR1)
++	ld	rWORD4, 40(rSTR2)
++	bne	cr1, L(bLcr1)
++	cmpld	cr0, rWORD1, rWORD2
++	ld	rWORD1, 48(rSTR1)
++	ld	rWORD2, 48(rSTR2)
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	ld	rWORD3, 56(rSTR1)
++	ld	rWORD4, 56(rSTR2)
++	bne	cr1, L(bLcr1)
++	cmpld	cr0, rWORD1, rWORD2
++	addi	rSTR1, rSTR1, 64
++	bne	cr0, L(bLcr0)
++	cmpld	cr1, rWORD3, rWORD4
++	addi	rSTR2, rSTR2, 64
++	bne	cr1, L(bLcr1)
++	bdnz	L(dw_loop)
++	beq	cr5, L(zero)
++	blt	cr6, L(small)
++	b	L(medium)
++
++	.align 4
++L(bLcr0):
++	li	rRTN, 1
++	bgtlr	cr0
++	li	rRTN, -1
++	blr
++
++	.align 4
++L(bLcr1):
++	li	rRTN, 1
++	bgtlr	cr1
++	li	rRTN, -1
++	blr
++
++	.align 4
++L(large_nalign):
++	lvxl	rVR14, rSTR1, rINDEX
++	lvsl	rVR3, 0, rSTR2		/* set permute control vector.  */
++	lvxl	rVR4, rS2OFF, rINDEX	/* load LSQ.  */
++	lvxl	rVR2, rSTR2, rINDEX	/* load MSQ.  */
++	addi	rINDEX, rINDEX, 16
++	vperm	rVR15, rVR2, rVR4, rVR3	/* align the data.  */
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(large_nalign)
++	cmpldi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++	b	L(small)
++
++	.align 4
++L(large_align):
++	lvxl	rVR14, rSTR1, rINDEX
++	lvxl	rVR15, rSTR2, rINDEX
++	addi	rINDEX, rINDEX, 16
++	vcmpequb.	rVR16, rVR14, rVR15
++	vnor	rVR17, rVR16, rVR16
++	bdnzt	4*cr6+lt, L(large_align)
++	cmpldi	cr1, rN, 0
++	bge	cr6, L(Vwords_Differ)
++	beq	cr1, L(zero)
++	add	rSTR1, rSTR1, rINDEX
++	add	rSTR2, rSTR2, rINDEX
++	b	L(small)
++
++	.align 4
++L(Vwords_Differ):
++	vspltisb	rVR18, 1
++	vspltisb	rVR1, 8
++	vslb	rVR0, rVR1, rVR18
++	vslb	rVR19, rVR0, rVR18
++	vslb	rVR18, rVR19, rVR18
++	vxor	rVR5, rVR5, rVR5
++	vsum4ubs	rVR2, rVR1, rVR18
++	vsro	rVR9, rVR17, rVR19
++	vsrw	rVR19, rVR17, rVR1
++	vsro	rVR10, rVR17, rVR18
++	vsrw	rVR18, rVR17, rVR0
++	vsro	rVR0, rVR17, rVR2
++	vor	rVR11, rVR9, rVR10
++	vsro	rVR2, rVR18, rVR1
++	vor	rVR11, rVR11, rVR0
++	vcmpgtuw	rVR11, rVR11, rVR5
++	vor	rVR11, rVR11, rVR19
++	vor	rVR11, rVR11, rVR18
++	vor	rVR11, rVR11, rVR2
++	vor	rVR15, rVR15, rVR11
++	vor	rVR14, rVR14, rVR11
++	li	rRTN, -1
++	vcmpgtub.	rVR8, rVR15, rVR14
++	bnelr	cr6
++	li	rRTN, 1
++	blr
++
++	.align 4
++L(zero):
++	li	rRTN, 0
++	blr
++
++END (memcmp)
++libc_hidden_builtin_def (memcmp)
++weak_alias (memcmp, bcmp)
diff --git a/recipes-core/glibc/glibc-fsl/0013.glibc.fsl-stcmp-e5500.patch b/recipes-core/glibc/glibc-fsl/0013.glibc.fsl-stcmp-e5500.patch
new file mode 100755
index 0000000..511d88c
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0013.glibc.fsl-stcmp-e5500.patch
@@ -0,0 +1,380 @@
+# Problem Statement:
+  Dhrystone benchmark gave performance degradation due to
+  code alignment.
+  Target: e5500 (32 & 64-bit) 
+
+  Note: This is not a library optimization patch but a performance fix.
+
+# Owned by:
+  Rohit
+
+# Actions:
+  * Aligned loop code of strcmp library to 16 bytes.
+  * Broke down lwzu/ldu to lwz/ld+addi.
+    This combination gives good performance numbers.
+
+diff -Naur libc/sysdeps/powerpc/powerpc32/e5500/strcmp.S libc-strcmp/sysdeps/powerpc/powerpc32/e5500/strcmp.S
+--- libc/sysdeps/powerpc/powerpc32/e5500/strcmp.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-strcmp/sysdeps/powerpc/powerpc32/e5500/strcmp.S	2014-12-15 09:42:36.119952087 -0600
+@@ -0,0 +1,150 @@
++/* Optimized strcmp implementation for PowerPC.
++   Copyright (C) 1997-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how the end-of-string testing works.  */
++
++/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4])  */
++
++EALIGN (strcmp, 4, 0)
++
++#define rTMP2	r0
++#define rRTN	r3
++#define rSTR1	r3	/* first string arg */
++#define rSTR2	r4	/* second string arg */
++#define rWORD1	r5	/* current word in s1 */
++#define rWORD2	r6	/* current word in s2 */
++#define rFEFE	r7	/* constant 0xfefefeff (-0x01010101) */
++#define r7F7F	r8	/* constant 0x7f7f7f7f */
++#define rNEG	r9	/* ~(word in s1 | 0x7f7f7f7f) */
++#define rBITDIF	r10	/* bits that differ in s1 & s2 words */
++#define rTMP	r11
++
++
++	or	rTMP, rSTR2, rSTR1
++	clrlwi.	rTMP, rTMP, 30
++	lis	rFEFE, -0x101
++	bne	L(unaligned)
++
++	lwz	rWORD1, 0(rSTR1)
++	lwz	rWORD2, 0(rSTR2)
++	lis	r7F7F, 0x7f7f
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	b	L(g1)
++
++L(g0):	lwzu	rWORD1, 4(rSTR1)
++	bne	cr1, L(different)
++	lwzu	rWORD2, 4(rSTR2)
++L(g1):	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	cmpw	cr1, rWORD1, rWORD2
++	beq+	L(g0)
++
++/* OK. We've hit the end of the string. We need to be careful that
++   we don't compare two strings as different because of gunk beyond
++   the end of the strings...  */
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	addi    rTMP2, rTMP, -1
++	andc    rTMP2, rTMP2, rTMP
++	rlwimi	rTMP2, rTMP2, 1, 0, 30
++	and	rWORD2, rWORD2, rTMP2		/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rlwimi	rTMP2, rWORD2, 24, 0, 7
++	rlwimi	rTMP, rWORD1, 24, 0, 7
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++L(different):
++	lwz	rWORD1, -4(rSTR1)
++	rlwinm	rTMP2, rWORD2, 8, 0xffffffff	/* Byte reverse word.  */
++	rlwinm	rTMP, rWORD1, 8, 0xffffffff
++	rlwimi	rTMP2, rWORD2, 24, 0, 7
++	rlwimi	rTMP, rWORD1, 24, 0, 7
++	rlwimi	rTMP2, rWORD2, 24, 16, 23
++	rlwimi	rTMP, rWORD1, 24, 16, 23
++	xor.	rBITDIF, rTMP, rTMP2
++	sub	rRTN, rTMP, rTMP2
++	bgelr+
++	ori	rRTN, rTMP2, 1
++	blr
++
++#else
++L(endstring):
++	and	rTMP, r7F7F, rWORD1
++	beq	cr1, L(equal)
++	add	rTMP, rTMP, r7F7F
++	xor.	rBITDIF, rWORD1, rWORD2
++	andc	rNEG, rNEG, rTMP
++	blt-	L(highbit)
++	cntlzw	rBITDIF, rBITDIF
++	cntlzw	rNEG, rNEG
++	addi	rNEG, rNEG, 7
++	cmpw	cr1, rNEG, rBITDIF
++	sub	rRTN, rWORD1, rWORD2
++	bgelr+	cr1
++L(equal):
++	li	rRTN, 0
++	blr
++
++L(different):
++	lwz	rWORD1, -4(rSTR1)
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	bgelr+
++L(highbit):
++	ori	rRTN, rWORD2, 1
++	blr
++#endif
++
++/* Oh well.  In this case, we just do a byte-by-byte comparison.  */
++	.align 4
++L(unaligned):
++	lbz	rWORD1, 0(rSTR1)
++	lbz	rWORD2, 0(rSTR2)
++	b	L(u1)
++
++L(u0):	lbzu	rWORD1, 1(rSTR1)
++	bne-	L(u4)
++	lbzu	rWORD2, 1(rSTR2)
++L(u1):	cmpwi	cr1, rWORD1, 0
++	beq-	cr1, L(u3)
++	cmpw	rWORD1, rWORD2
++	bne-	L(u3)
++	lbzu	rWORD1, 1(rSTR1)
++	lbzu	rWORD2, 1(rSTR2)
++	cmpwi	cr1, rWORD1, 0
++	cmpw	rWORD1, rWORD2
++	bne+	cr1, L(u0)
++L(u3):	sub	rRTN, rWORD1, rWORD2
++	blr
++L(u4):	lbz	rWORD1, -1(rSTR1)
++	sub	rRTN, rWORD1, rWORD2
++	blr
++END (strcmp)
++libc_hidden_builtin_def (strcmp)
+diff -Naur libc/sysdeps/powerpc/powerpc64/e5500/strcmp.S libc-strcmp/sysdeps/powerpc/powerpc64/e5500/strcmp.S
+--- libc/sysdeps/powerpc/powerpc64/e5500/strcmp.S	1969-12-31 18:00:00.000000000 -0600
++++ libc-strcmp/sysdeps/powerpc/powerpc64/e5500/strcmp.S	2014-12-15 09:42:46.247951902 -0600
+@@ -0,0 +1,176 @@
++/* Optimized strcmp implementation for PowerPC64.
++   Copyright (C) 1997-2014 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how the end-of-string testing works.  */
++
++/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4])  */
++
++EALIGN (strcmp, 4, 0)
++	CALL_MCOUNT 2
++
++#define rTMP2	r0
++#define rRTN	r3
++#define rSTR1	r3	/* first string arg */
++#define rSTR2	r4	/* second string arg */
++#define rWORD1	r5	/* current word in s1 */
++#define rWORD2	r6	/* current word in s2 */
++#define rFEFE	r7	/* constant 0xfefefefefefefeff (-0x0101010101010101) */
++#define r7F7F	r8	/* constant 0x7f7f7f7f7f7f7f7f */
++#define rNEG	r9	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
++#define rBITDIF	r10	/* bits that differ in s1 & s2 words */
++#define rTMP	r11
++
++	dcbt	0,rSTR1
++	or	rTMP, rSTR2, rSTR1
++	dcbt	0,rSTR2
++	clrldi.	rTMP, rTMP, 61
++	lis	rFEFE, -0x101
++	bne	L(unaligned)
++
++	ld	rWORD1, 0(rSTR1)
++	ld	rWORD2, 0(rSTR2)
++	lis	r7F7F, 0x7f7f
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	sldi	rTMP, rFEFE, 32
++	insrdi	r7F7F, r7F7F, 32, 0
++	add	rFEFE, rFEFE, rTMP
++	b	L(g1)
++
++L(g0):	ldu	rWORD1, 8(rSTR1)
++	bne	cr1, L(different)
++	ldu	rWORD2, 8(rSTR2)
++L(g1):	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	cmpd	cr1, rWORD1, rWORD2
++	beq+	L(g0)
++
++/* OK. We've hit the end of the string. We need to be careful that
++   we don't compare two strings as different because of gunk beyond
++   the end of the strings...  */
++#ifdef __LITTLE_ENDIAN__
++L(endstring):
++	addi    rTMP2, rTMP, -1
++	beq	cr1, L(equal)
++	andc    rTMP2, rTMP2, rTMP
++	rldimi	rTMP2, rTMP2, 1, 0
++	and	rWORD2, rWORD2, rTMP2	/* Mask off gunk.  */
++	and	rWORD1, rWORD1, rTMP2
++	cmpd	cr1, rWORD1, rWORD2
++	beq	cr1, L(equal)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
++	ori	rRTN, rRTN, 1
++	blr
++L(equal):
++	li	rRTN, 0
++	blr
++
++L(different):
++	ld	rWORD1, -8(rSTR1)
++	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
++	neg	rNEG, rBITDIF
++	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
++	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
++	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
++	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
++	sld	rWORD2, rWORD2, rNEG
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63
++	ori	rRTN, rRTN, 1
++	blr
++L(highbit):
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
++	blr
++
++#else
++L(endstring):
++	and	rTMP, r7F7F, rWORD1
++	beq	cr1, L(equal)
++	add	rTMP, rTMP, r7F7F
++	xor.	rBITDIF, rWORD1, rWORD2
++	andc	rNEG, rNEG, rTMP
++	blt-	L(highbit)
++	cntlzd	rBITDIF, rBITDIF
++	cntlzd	rNEG, rNEG
++	addi	rNEG, rNEG, 7
++	cmpd	cr1, rNEG, rBITDIF
++	sub	rRTN, rWORD1, rWORD2
++	blt-	cr1, L(equal)
++	sradi	rRTN, rRTN, 63		/* must return an int.  */
++	ori	rRTN, rRTN, 1
++	blr
++L(equal):
++	li	rRTN, 0
++	blr
++
++L(different):
++	ld	rWORD1, -8(rSTR1)
++	xor.	rBITDIF, rWORD1, rWORD2
++	sub	rRTN, rWORD1, rWORD2
++	blt-	L(highbit)
++	sradi	rRTN, rRTN, 63
++	ori	rRTN, rRTN, 1
++	blr
++L(highbit):
++	sradi	rRTN, rWORD2, 63
++	ori	rRTN, rRTN, 1
++	blr
++#endif
++
++/* Oh well.  In this case, we just do a byte-by-byte comparison.  */
++	.align 4
++L(unaligned):
++	lbz	rWORD1, 0(rSTR1)
++	lbz	rWORD2, 0(rSTR2)
++	b	L(u1)
++
++L(u0):	lbzu	rWORD1, 1(rSTR1)
++	bne-	L(u4)
++	lbzu	rWORD2, 1(rSTR2)
++L(u1):	cmpwi	cr1, rWORD1, 0
++	beq-	cr1, L(u3)
++	cmpd	rWORD1, rWORD2
++	bne-	L(u3)
++	lbzu	rWORD1, 1(rSTR1)
++	lbzu	rWORD2, 1(rSTR2)
++	cmpdi	cr1, rWORD1, 0
++	cmpd	rWORD1, rWORD2
++	bne+	cr1, L(u0)
++L(u3):	sub	rRTN, rWORD1, rWORD2
++	blr
++L(u4):	lbz	rWORD1, -1(rSTR1)
++	sub	rRTN, rWORD1, rWORD2
++	blr
++END (strcmp)
++libc_hidden_builtin_def (strcmp)
+diff -Naur libc-strcmp/sysdeps/powerpc/powerpc32/e5500/strcmp.S libc-strcmp-dhry/sysdeps/powerpc/powerpc32/e5500/strcmp.S
+--- libc-strcmp/sysdeps/powerpc/powerpc32/e5500/strcmp.S	2014-12-15 09:42:36.119952087 -0600
++++ libc-strcmp-dhry/sysdeps/powerpc/powerpc32/e5500/strcmp.S	2014-12-15 09:46:03.771951808 -0600
+@@ -49,9 +49,12 @@
+ 	addi	r7F7F, r7F7F, 0x7f7f
+ 	b	L(g1)
+ 
+-L(g0):	lwzu	rWORD1, 4(rSTR1)
++	.align 4
++L(g0):	lwz	rWORD1, 4(rSTR1)
++	addi	rSTR1, rSTR1, 4
+ 	bne	cr1, L(different)
+-	lwzu	rWORD2, 4(rSTR2)
++	lwz	rWORD2, 4(rSTR2)
++	addi	rSTR2, rSTR2, 4
+ L(g1):	add	rTMP, rFEFE, rWORD1
+ 	nor	rNEG, r7F7F, rWORD1
+ 	and.	rTMP, rTMP, rNEG
+diff -Naur libc/sysdeps/powerpc/powerpc64/e5500/strcmp.S libc-strcmp/sysdeps/powerpc/powerpc64/e5500/strcmp.S
+--- libc/sysdeps/powerpc/powerpc64/e5500/strcmp.S	2015-01-19 04:07:33.660173151 -0600
++++ libc-strcmp/sysdeps/powerpc/powerpc64/e5500/strcmp.S	2015-01-19 04:09:38.115175293 -0600
+@@ -56,7 +56,8 @@
+ 
+ L(g0):	ldu	rWORD1, 8(rSTR1)
+ 	bne	cr1, L(different)
+-	ldu	rWORD2, 8(rSTR2)
++	ld	rWORD2, 8(rSTR2)
++	addi	rSTR2, rSTR2, 8
+ L(g1):	add	rTMP, rFEFE, rWORD1
+ 	nor	rNEG, r7F7F, rWORD1
+ 	and.	rTMP, rTMP, rNEG
diff --git a/recipes-core/glibc/glibc-fsl/0014.glibc.fsl-strchr-e500mc-e5500.patch b/recipes-core/glibc/glibc-fsl/0014.glibc.fsl-strchr-e500mc-e5500.patch
new file mode 100755
index 0000000..f864afc
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0014.glibc.fsl-strchr-e500mc-e5500.patch
@@ -0,0 +1,659 @@
+# Problem Statement:
+  Implement target specific optimized strchr for e500mc & e5500 32-bit.
+
+# Owned by:
+  Mahesh [based on existing 'asm' implementation of eglibc strchr]
+
+# Actions:
+  * For e500mc target, default glibc implementation was reading
+    two words at a time. Current implementation unrolls the loop to 
+    read sixteen words.
+
+  * For e5500 [32-bit] target, use cmpb instruction to check the occurance
+    of NULL and expected character in a string.
+
+  * Reordered the instruction to get the better performance
+
+  * Got time out error with e5500 (32-bit) target on eglibc test suite.
+    Didn't find any degradation with our performance tests.
+    So updating TIMEOUT boundary to 10.
+
+diff -Naur vanilla/string/stratcliff.c patched/string/stratcliff.c
+--- vanilla/string/stratcliff.c	2015-03-12 05:07:11.970952217 -0500
++++ patched/string/stratcliff.c	2015-03-12 05:18:29.166952009 -0500
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #define _GNU_SOURCE 1
++#define TIMEOUT 10
+ 
+ /* Make sure we don't test the optimized inline functions if we want to
+    test the real implementation.  */
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e500mc/strchr.S patched/sysdeps/powerpc/powerpc32/e500mc/strchr.S
+--- vanilla/sysdeps/powerpc/powerpc32/e500mc/strchr.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e500mc/strchr.S	2015-03-12 06:05:35.086952070 -0500
+@@ -0,0 +1,307 @@
++/* Optimized strchr implementation for 32-bit e500mc PowerPC target.
++   Based on generic 32-bit PowerPC strchr implementation.
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how this works.  */
++
++/* char * [r3] strchr (const char *s [r3] , int c [r4])  */
++
++ENTRY (strchr)
++
++#define rTMP1	r0
++#define rRTN	r3	/* outgoing result.  */
++#define rSTR	r8	/* current word pointer.  */
++#define rCHR	r4	/* byte we are looking for, spread over the
++			   whole word.  */
++#define rWORD	r5	/* the current word.  */
++#define rCLZB	rCHR	/* leading zero byte count.  */
++#define rFEFE	r6	/* constant 0xfefefeff (-0x01010101).  */
++#define r7F7F	r7	/* constant 0x7f7f7f7f.  */
++#define rTMP2	r9
++#define rIGN	r10	/* the number of bits we should ignore in the
++			   first word.  */
++#define rMASK	r11	/* mask with the bits to ignore set to rTMP1.  */
++#define rTMP3	r12
++
++	andi.	rTMP2, rRTN, 3
++	clrrwi	rSTR, rRTN, 2
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	rlwimi	rCHR, rCHR, 16, 0, 15
++	lis	rFEFE, -0x101
++	lis	r7F7F, 0x7f7f
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	beq	L(srcalign)
++	lwz	rWORD, 0(rSTR)
++	li	rMASK, -1
++	rlwinm	rIGN, rRTN, 3, 27, 28
++	srw	rMASK, rMASK, rIGN
++	orc	rWORD, rWORD, rMASK
++	add	rTMP1, rFEFE, rWORD
++	xor	rTMP3, rCHR, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	orc	rTMP3, rTMP3, rMASK
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	b	L(loop)
++L(srcalign):
++	/* Test the first (partial?) word.  */
++	lwz	rWORD, 0(rSTR)
++	add	rTMP1, rFEFE, rWORD
++	xor	rTMP3, rCHR, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* The loop.  */
++L(loop):
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	lwzu	rWORD, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	/* Start test for the bytes we're looking for.  */
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rIGN, rFEFE, rWORD
++	/* Test for 0.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rIGN, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	beq	L(loop)
++	/* There is a zero byte in the word, but may also be a matching
++	   byte (either before or after the zero byte).  In fact, we may be
++	   looking for a zero byte, in which case we return a match.  We
++	   guess that this hasn't happened, though.  */
++L(missed):
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	li	rRTN, 0
++	beqlr
++	/* It did happen.  Decide which one was first...
++	   I'm not sure if this is actually faster than a sequence of rotates,
++	   compares, and branches (we use it anyway because it's shorter).  */
++	and	rFEFE, r7F7F, rWORD
++	or	rMASK, r7F7F, rWORD
++	and	rTMP1, r7F7F, rTMP3
++	or	rIGN, r7F7F, rTMP3
++	add	rFEFE, rFEFE, r7F7F
++	add	rTMP1, rTMP1, r7F7F
++	nor	rWORD, rMASK, rFEFE
++	nor	rTMP2, rIGN, rTMP1
++	cmplw	rWORD, rTMP2
++	cntlzw	rCLZB, rTMP2
++	bgtlr
++	srwi	rCLZB, rCLZB, 3
++	add	rRTN, rSTR, rCLZB
++	blr
++L(foundit):
++	and	rTMP1, r7F7F, rTMP3
++	or	rIGN, r7F7F, rTMP3
++	add	rTMP1, rTMP1, r7F7F
++	nor	rTMP2, rIGN, rTMP1
++	cntlzw	rCLZB, rTMP2
++	subi	rSTR, rSTR, 4
++	srwi	rCLZB, rCLZB, 3
++	add	rRTN, rSTR, rCLZB
++	blr
++
++END (strchr)
++
++weak_alias (strchr, index)
++libc_hidden_builtin_def (strchr)
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e5500/strchr.S patched/sysdeps/powerpc/powerpc32/e5500/strchr.S
+--- vanilla/sysdeps/powerpc/powerpc32/e5500/strchr.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e5500/strchr.S	2015-03-12 06:06:26.507951923 -0500
+@@ -0,0 +1,313 @@
++/* Optimized strchr implementation for 32-bit e5500 PowerPC target.
++   Based on POWER7 strchr implementation.
++
++   Copyright (C) 2010-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how this works.  */
++
++/* char * [r3] strchr (const char *s [r3] , int c [r4])  */
++
++ENTRY (strchr)
++
++#define rTMP1	r0
++#define rRTN	r3	/* outgoing result.  */
++#define rSTR	r8	/* current word pointer.  */
++#define rCHR	r4	/* byte we are looking for, spread over the
++			   whole word.  */
++#define rTMP2	r5
++#define rMASK	r6	/* calculate padding bits.  */
++#define rTMP3	r7
++#define rWORD	r12	/* the current word.  */
++#define rWORD2	r9	/* following word.  */
++#define rTMP4	r10
++#define rTMP5	r11
++
++	dcbt	0, rRTN
++	andi.	rTMP3, rRTN, 7		/* check for double word boundary.  */
++	cmpwi	cr7, rCHR, 0
++	li	rTMP1, 0
++	/* Replicate byte to double word.  */
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	rlwimi	rCHR, rCHR, 16, 0, 15
++	beq	L(dwalign)
++	subfic	rTMP3, rTMP3, 8
++	cmplwi	cr6, rTMP3, 4
++	clrrwi	rSTR, rRTN, 2		/* Align the address to the word
++					   boundary.  */
++	beq	cr6, L(word2)
++	blt	cr6, L(LTword2)
++	lwz	rWORD, 0(rSTR)		/* Load word from memory.  */
++	rlwinm	rMASK, rRTN, 3, 27, 28	/* Calculate padding.  */
++	/* Now rCHR has a word of c bytes and rTMP1 has
++	   a word of null bytes.  */
++	beq	cr7, L(null_match)
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte
++					   against null byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP4, rTMP4, rMASK
++	slw	rTMP5, rTMP5, rMASK
++	srw	rTMP4, rTMP4, rMASK
++	srw	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpwi	cr7, rTMP2, 0		/* If rTMP2 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	/* Handle WORD2 of pair.  */
++	lwzu	rWORD, 4(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)			/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(LTword2):
++	lwz	rWORD, 0(rSTR)		/* Load word from memory.  */
++	rlwinm	rMASK, rRTN, 3, 27, 28	/* Calculate padding.  */
++	/* Now rCHR has a word of c bytes and rTMP1 has
++	   a word of null bytes.  */
++	beq	cr7, L(null_LTword2)
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte
++					   against null byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP4, rTMP4, rMASK
++	slw	rTMP5, rTMP5, rMASK
++	srw	rTMP4, rTMP4, rMASK
++	srw	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpwi	cr7, rTMP2, 0		/* If rTMP2 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	lwz	rWORD, 4(rSTR)
++	lwzu	rWORD2, 8(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	cmpb	rMASK, rWORD2, rCHR
++	cmpb	rTMP3, rWORD2, rTMP1
++	or	rWORD, rTMP4, rTMP5
++	or	rWORD2, rMASK, rTMP3
++	or	rTMP2, rWORD, rWORD2
++	cmpwi	cr7, rTMP2, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the words contains a c/null byte.  Check
++	   the first word and decrement the address in case the first
++	   word really contains a c/null byte.  */
++	cmpwi	cr6, rWORD, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done)
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP4, rMASK
++	mr	rTMP5, rTMP3
++	addi	rSTR, rSTR, 4
++	bne	cr7, L(done)
++L(word2):
++	lwz	rWORD, 0(rSTR)
++	beq	cr7, L(null_word2)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)
++L(dwalign):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for
++	   bigger strings.  */
++	mr	rSTR, rRTN
++	lwz	rWORD, 0(rSTR)
++	lwzu	rWORD2, 4(rSTR)
++	beq	cr7, L(dwalignnull)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	cmpb	rMASK, rWORD2, rCHR
++	cmpb	rTMP3, rWORD2, rTMP1
++	or	rWORD, rTMP4, rTMP5
++	or	rWORD2, rMASK, rTMP3
++	or	rTMP2, rWORD, rWORD2
++	cmpwi	cr7, rTMP2, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the words contains a c/null byte.  Check
++	   the first word and decrement the address in case the first word
++	   really contains a c/null byte.  */
++	cmpwi	cr6, rWORD, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done)
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP4, rMASK
++	mr	rTMP5, rTMP3
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the c/null byte in the original
++	   word from the string.  Use that to calculate the pointer.  */
++	b	L(done)
++L(loop):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for
++	   bigger strings.  */
++	lwz	rWORD, 4(rSTR)
++	lwzu	rWORD2, 8(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	cmpb	rMASK, rWORD2, rCHR
++	cmpb	rTMP3, rWORD2, rTMP1
++	or	rWORD, rTMP4, rTMP5
++	or	rWORD2, rMASK, rTMP3
++	or	rTMP2, rWORD, rWORD2
++	cmpwi	cr7, rTMP2, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the words contains a c/null byte.  Check
++	   the first word and decrement the address in case the first word
++	   really contains a c/null byte.  */
++	cmpwi	cr6, rWORD, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done)
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP4, rMASK
++	mr	rTMP5, rTMP3
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the c/null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++L(done):
++	cntlzw	rCHR, rTMP4		/* Count leading zeroes until
++					   the c matches.  */
++	cntlzw	rTMP1, rTMP5		/* Count leading zeroes until
++					   the null matches.  */
++	cmplw	cr7, rCHR, rTMP1
++	bgt	cr7, L(no_match)
++	srwi	rTMP1, rCHR, 3		/* Convert leading zeroes to bytes.  */
++	add	rRTN, rSTR, rTMP1	/* Return addr of the matching c byte
++					   or null in case c was not found.  */
++	blr
++L(no_match):
++	li	rRTN, 0
++	blr
++	/* We are here because strchr was called with a null byte.  */
++L(null_match):
++	/* rTMP1 has a word of null bytes.  */
++	cmpb	rTMP2, rWORD, rTMP1	/* Compare each byte against null
++					   bytes.  */
++	/* Move the words left and right to discard the bits that are
++	   not part of the string and to bring them back as zeros.  */
++	slw	rTMP2, rTMP2, rMASK
++	srw	rTMP2, rTMP2, rMASK
++	cmpwi	cr7, rTMP2, 0		/* If rTMP4 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done_null)
++	/* Handle WORD2 of pair.  */
++	lwzu	rWORD, 4(rSTR)
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done_null)
++	b	L(loop_null)		/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(null_LTword2):
++	/* rTMP1 has a word of null bytes.  */
++	cmpb	rTMP2, rWORD, rTMP1	/* Compare each byte against null
++					   bytes.  */
++	/* Move the words left and right to discard the bits that are
++	   not part of the string and to bring them back as zeros.  */
++	slw	rTMP2, rTMP2, rMASK
++	srw	rTMP2, rTMP2, rMASK
++	cmpwi	cr7, rTMP2, 0		/* If rTMP4 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done_null)
++	b	L(loop_null)
++L(null_word2):
++	/* Handle WORD2 of pair.  */
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done_null)
++	b	L(loop_null)		/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(dwalignnull):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for
++	   bigger strings.  */
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpb	rTMP4, rWORD2, rTMP1
++	or	rMASK, rTMP2, rTMP4
++	cmpwi	cr7, rMASK, 0
++	beq	cr7, L(loop_null)
++	/* OK, one (or both) of the words contains a null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a null byte.  */
++	cmpwi	cr6, rTMP2, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done_null)
++	/* The null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP2, rTMP4
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original
++	   word from the string.  Use that to calculate the pointer.  */
++	b	L(done_null)
++L(loop_null):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for
++	   bigger strings.  */
++	lwz	rWORD, 4(rSTR)
++	lwzu	rTMP5, 8(rSTR)
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpb	rTMP4, rTMP5, rTMP1
++	or	rMASK, rTMP2, rTMP4
++	cmpwi	cr7, rMASK, 0
++	beq	cr7, L(loop_null)
++	/* OK, one (or both) of the words contains a null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a null byte.  */
++	cmpwi	cr6, rTMP2, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done_null)
++	/* The null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP2, rTMP4
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++L(done_null):
++	cntlzw	rTMP1, rTMP2		/* Count leading zeros before the
++					   match.  */
++	srwi	rTMP1, rTMP1, 3		/* Convert leading zeros to bytes.  */
++	add	rRTN, rSTR, rTMP1	/* Return address of the matching
++					   null byte.  */
++	blr
++
++END (strchr)
++
++weak_alias (strchr, index)
++libc_hidden_builtin_def (strchr)
diff --git a/recipes-core/glibc/glibc-fsl/0015.glibc.fsl-strcpy-e500mc-e5500.patch b/recipes-core/glibc/glibc-fsl/0015.glibc.fsl-strcpy-e500mc-e5500.patch
new file mode 100755
index 0000000..17dd029
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0015.glibc.fsl-strcpy-e500mc-e5500.patch
@@ -0,0 +1,627 @@
+# Problem Statement:
+  Implement target specific optimized strcpy for e500mc,32-bit e5500,
+  64-bit e5500
+
+# Owned by:
+  Ajay [based on existing 'asm' implementation of glibc]
+
+# Actions:
+  * For e500mc and e5500 [32-bit and 64-bit] targets, there is a slight
+    improvement in the performance for aligned data.
+
+  * For e500mc and e5500 [32-bit and 64-bit] targets, there is a appreciable
+    improvement in the performance [approx. 64% in case of e500mc and 32-bit
+    e5500 and 78% in case of 64-bit e5500] for non-aligned data.
+
+  * Rev2:
+    a) e5500 64-bit: Fixed "segmentation fault" issues for strcpy with eglibc
+       v2.15 test suite for unaligned data.
+
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e500mc/strcpy.S patched/sysdeps/powerpc/powerpc32/e500mc/strcpy.S
+--- vanilla/sysdeps/powerpc/powerpc32/e500mc/strcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e500mc/strcpy.S	2015-03-14 08:14:13.094951983 -0500
+@@ -0,0 +1,186 @@
++/* Optimized strcpy implementation for PowerPC e500mc target.
++   Based on generic 32-bit PowerPC strcpy implementation.
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how the end-of-string testing works.  */
++
++/* char * [r3] strcpy (char *dest [r3], const char *src [r4])  */
++
++EALIGN (strcpy, 4, 0)
++
++#define rTMP	r0
++#define rRTN	r3	/* incoming DEST arg preserved as result.  */
++#define rSRC	r4	/* pointer to previous word in src.  */
++#define rDEST	r5	/* pointer to previous word in dest.  */
++#define rWORD1	r6	/* word from src.  */
++#define rFEFE	r7	/* constant 0xfefefeff (-0x01010101).  */
++#define r7F7F	r8	/* constant 0x7f7f7f7f.  */
++#define rNEG	r9	/* ~(word in s1 | 0x7f7f7f7f).  */
++#define rTMP1	r9
++#define rWORD2	r10	/* word from src.  */
++#define rWORD3	r11
++#define rWORD4	r12
++
++	andi.	rTMP, rSRC, 0x03
++	bne	L(src_unaligned)
++L(aligned):
++	addi	rDEST, rRTN, -4
++	lis	rFEFE, -0x101
++	lis	r7F7F, 0x7f7f
++	lwz	rWORD2, 0(rSRC)
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	bne	L(move_register_10)
++L(loop_for_aligned):
++	lwzu	rWORD1, 4(rSRC)
++	stwu	rWORD2, 4(rDEST)
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	bne	L(copy_rest_bytes)
++	lwzu	rWORD2, 4(rSRC)
++	stwu	rWORD1, 4(rDEST)
++L(g2):
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	beq+	L(loop_for_aligned)
++
++L(move_register_10):
++	mr	rWORD1, rWORD2
++	/* We've hit the end of the string.  Do the rest byte-by-byte.  */
++L(copy_rest_bytes):
++	rlwinm.	rTMP, rWORD1, 8, 24, 31
++	stb	rTMP, 4(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 16, 24, 31
++	stb	rTMP, 5(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 24, 24, 31
++	stb	rTMP, 6(rDEST)
++	beqlr
++	stb	rWORD1, 7(rDEST)
++	blr
++	/* end of already aligned src.  */
++L(src_got_aligned):
++	lis	r7F7F, 0x7f7f
++	lwz	rWORD1, 0(rSRC)
++	lis	rFEFE, -0x101
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	bne	L(copy_rest_bytes_for_unaligned)
++	lwzu	rWORD2, 4(rSRC)
++	stw	rWORD1, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_10_for_unaligned)
++L(loop_for_nonaligned):
++	lwz	rWORD1, 4(rSRC)
++	stw	rWORD2, 0(rDEST)
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(copy_rest_bytes_for_unaligned)
++	lwzu	rWORD2, 8(rSRC)
++	stw	rWORD1, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_10_for_unaligned)
++	lwz	rWORD3, 4(rSRC)
++	stw	rWORD2, 0(rDEST)
++	add	rTMP, rFEFE, rWORD3
++	nor	rNEG, r7F7F, rWORD3
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_11)
++	lwzu	rWORD4, 8(rSRC)
++	stw	rWORD3, 0(rDEST)
++	add	rTMP, rFEFE, rWORD4
++	nor	rNEG, r7F7F, rWORD4
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_12)
++	lwzu	rWORD2, 4(rSRC)
++	stw	rWORD4, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	beq	L(loop_for_nonaligned)
++L(move_register_10_for_unaligned):
++	mr	rWORD1, rWORD2
++L(copy_rest_bytes_for_unaligned):
++	rlwinm.	rTMP, rWORD1, 8, 24, 31
++	stb	rTMP, 0(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 16, 24, 31
++	stb	rTMP, 1(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 24, 24, 31
++	stb	rTMP, 2(rDEST)
++	beqlr
++	stb	rWORD1, 3(rDEST)
++	blr
++L(move_register_11):
++	mr	rWORD1, rWORD3
++	b	L(copy_rest_bytes_for_unaligned)
++L(move_register_12):
++	mr	rWORD1, rWORD4
++	b	L(copy_rest_bytes_for_unaligned)
++L(src_unaligned):
++	lbz	rWORD1, 0(rSRC)
++	addi	rDEST, rRTN, 0
++	cmpwi	rWORD1, 0x0
++	stb	rWORD1, 0(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD2, 1(rSRC)
++	cmpwi	rWORD2, 0x0
++	stb	rWORD2, 1(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD3, 2(rSRC)
++	cmpwi	rWORD3, 0x0
++	stb	rWORD3, 2(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD2, 3(rSRC)
++	cmpwi	rWORD2, 0x0
++	beq	L(endstrcpy1)
++	li	rTMP1, 4
++	sub	rTMP1, rTMP1, rTMP
++	add	rSRC, rSRC, rTMP1
++	add	rDEST, rDEST, rTMP1
++	b	L(src_got_aligned)
++L(endstrcpy1):
++	stb	rWORD2, 3(rDEST)
++L(endstrcpy):
++	blr
++
++END (strcpy)
++libc_hidden_builtin_def (strcpy)
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e5500/strcpy.S patched/sysdeps/powerpc/powerpc32/e5500/strcpy.S
+--- vanilla/sysdeps/powerpc/powerpc32/e5500/strcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e5500/strcpy.S	2015-03-14 08:14:52.103951985 -0500
+@@ -0,0 +1,180 @@
++/* Optimized strcpy implementation for 32-bit e5500 PowerPC target.
++   Based on generic 32-bit PowerPC strcpy implementation.
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how the end-of-string testing works.  */
++
++/* char * [r3] strcpy (char *dest [r3], const char *src [r4])  */
++
++EALIGN (strcpy, 4, 0)
++
++#define rTMP	r0
++#define rRTN	r3	/* incoming DEST arg preserved as result.  */
++#define rSRC	r4	/* pointer to previous word in src.  */
++#define rDEST	r5	/* pointer to previous word in dest.  */
++#define rWORD1	r6	/* word from src.  */
++#define rFEFE	r7	/* constant 0xfefefeff (-0x01010101).  */
++#define r7F7F	r8	/* constant 0x7f7f7f7f.  */
++#define rNEG	r9	/* ~(word in s1 | 0x7f7f7f7f).  */
++#define rTMP1	r9
++#define rWORD2	r10	/* word from src.  */
++#define rWORD3	r11
++#define rWORD4	r12
++
++	andi.	rTMP, rSRC, 0x03
++	bne	L(src_unaligned)
++	addi	rDEST, rRTN, -4
++	lis	rFEFE, -0x101
++	lis	r7F7F, 0x7f7f
++	lwz	rWORD2, 0(rSRC)
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	b	L(g2)
++L(g0):
++	lwzu	rWORD1, 4(rSRC)
++	stwu	rWORD2, 4(rDEST)
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	bne	L(g1)
++	lwzu	rWORD2, 4(rSRC)
++	stwu	rWORD1, 4(rDEST)
++L(g2):
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	beq	L(g0)
++	mr	rWORD1, rWORD2
++	/* We've hit the end of the string.  Do the rest byte-by-byte.  */
++L(g1):
++	rlwinm.	rTMP, rWORD1, 8, 24, 31
++	stb	rTMP, 4(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 16, 24, 31
++	stb	rTMP, 5(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 24, 24, 31
++	stb	rTMP, 6(rDEST)
++	beqlr
++	stb	rWORD1, 7(rDEST)
++	blr
++	/* end of already aligned src.  */
++L(src_got_aligned):
++	lis	r7F7F, 0x7f7f
++	lwz	rWORD1, 0(rSRC)
++	lis	rFEFE, -0x101
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	bne	L(copy_rest_bytes_for_unaligned)
++	lwzu	rWORD2, 4(rSRC)
++	stw	rWORD1, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_10_for_unaligned)
++L(loop_for_nonaligned):
++	lwz	rWORD1, 4(rSRC)
++	stw	rWORD2, 0(rDEST)
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(copy_rest_bytes_for_unaligned)
++	lwzu	rWORD2, 8(rSRC)
++	stw	rWORD1, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_10_for_unaligned)
++	lwz	rWORD3, 4(rSRC)
++	stw	rWORD2, 0(rDEST)
++	add	rTMP, rFEFE, rWORD3
++	nor	rNEG, r7F7F, rWORD3
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_11)
++	lwzu	rWORD4, 8(rSRC)
++	stw	rWORD3, 0(rDEST)
++	add	rTMP, rFEFE, rWORD4
++	nor	rNEG, r7F7F, rWORD4
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	bne	L(move_register_12)
++	lwzu	rWORD2, 4(rSRC)
++	stw	rWORD4, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 4
++	beq	L(loop_for_nonaligned)
++L(move_register_10_for_unaligned):
++	mr	rWORD1, rWORD2
++L(copy_rest_bytes_for_unaligned):
++	rlwinm.	rTMP, rWORD1, 8, 24, 31
++	stb	rTMP, 0(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 16, 24, 31
++	stb	rTMP, 1(rDEST)
++	beqlr
++	rlwinm.	rTMP, rWORD1, 24, 24, 31
++	stb	rTMP, 2(rDEST)
++	beqlr
++	stb	rWORD1, 3(rDEST)
++	blr
++L(move_register_11):
++	mr	rWORD1, rWORD3
++	b	L(copy_rest_bytes_for_unaligned)
++L(move_register_12):
++	mr	rWORD1, rWORD4
++	b	L(copy_rest_bytes_for_unaligned)
++L(src_unaligned):
++	lbz	rWORD1, 0(rSRC)
++	addi	rDEST, rRTN, 0
++	cmpwi	rWORD1, 0x0
++	stb	rWORD1, 0(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD2, 1(rSRC)
++	cmpwi	rWORD2, 0x0
++	stb	rWORD2, 1(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD3, 2(rSRC)
++	cmpwi	rWORD3, 0x0
++	stb	rWORD3, 2(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD2, 3(rSRC)
++	cmpwi	rWORD2, 0x0
++	beq	L(endstrcpy1)
++	li	rTMP1, 4
++	sub	rTMP1, rTMP1, rTMP
++	add	rSRC, rSRC, rTMP1
++	add	rDEST, rDEST, rTMP1
++	b	L(src_got_aligned)
++L(endstrcpy1):
++	stb	rWORD2, 3(rDEST)
++L(endstrcpy):
++	blr
++
++END (strcpy)
++libc_hidden_builtin_def (strcpy)
+diff -Naur vanilla/sysdeps/powerpc/powerpc64/e5500/strcpy.S patched/sysdeps/powerpc/powerpc64/e5500/strcpy.S
+--- vanilla/sysdeps/powerpc/powerpc64/e5500/strcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc64/e5500/strcpy.S	2015-03-14 08:16:17.828951956 -0500
+@@ -0,0 +1,230 @@
++/* Optimized strcpy implementation for 64-bit e5500 PowerPC target.
++   Based on generic 64-bit PowerPC strcpy implementation.
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how the end-of-string testing works.  */
++
++/* char * [r3] strcpy (char *dest [r3], const char *src [r4])  */
++
++EALIGN (strcpy, 4, 0)
++	CALL_MCOUNT 2
++
++#define rTMP	r0
++#define rRTN	r3
++#define rSRC	r4	/* pointer to previous word in src.  */
++#define rDEST	r5	/* pointer to previous word in dest.  */
++#define rWORD1	r6	/* word from src.  */
++#define rFEFE	r7	/* constant value 0xfefefefefefefeff
++			   (-0x0101010101010101).  */
++#define r7F7F	r8	/* constant 0x7f7f7f7f7f7f7f7f.  */
++#define rNEG	r9	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f).  */
++#define rTMP1	r9
++#define rWORD2	r10	/* word from src.  */
++#define rWORD3	r11
++#define rWORD4	r12
++
++	dcbt	0, rSRC
++	andi.	rTMP, rSRC, 0x07
++	dcbtst	0, rRTN
++	bne	L(src_unaligned)
++	addi	rDEST, rRTN, -8
++	lis	rFEFE, -0x101
++	lis	r7F7F, 0x7f7f
++	ld	rWORD1, 0(rSRC)
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	sldi	rTMP, rFEFE, 32
++	insrdi	r7F7F, r7F7F, 32, 0
++	add	rFEFE, rFEFE, rTMP
++	b	L(g2)
++L(g0):
++	ldu	rWORD2, 8(rSRC)
++	stdu	rWORD1, 8(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	bne-	L(g1)
++	ldu	rWORD1, 8(rSRC)
++	stdu	rWORD2, 8(rDEST)
++L(g2):
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	beq+	L(g0)
++	mr	rWORD2, rWORD1
++	/* We've hit the end of the string.  Do the rest byte-by-byte.  */
++L(g1):
++	extrdi.	rTMP, rWORD2, 8, 0
++	stb	rTMP, 8(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD2, 8, 8
++	stb	rTMP, 9(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD2, 8, 16
++	stb	rTMP, 10(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD2, 8, 24
++	stb	rTMP, 11(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD2, 8, 32
++	stb	rTMP, 12(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD2, 8, 40
++	stb	rTMP, 13(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD2, 8, 48
++	stb	rTMP, 14(rDEST)
++	beqlr
++	stb	rWORD2, 15(rDEST)
++	blr
++	/* end of already aligned src.  */
++L(src_got_aligned):
++	lis	r7F7F, 0x7f7f
++	lis	rFEFE, -0x101
++	addi	rFEFE, rFEFE, -0x101
++	ld	rWORD1, 0(rSRC)
++	addi	r7F7F, r7F7F, 0x7f7f
++	sldi	rTMP, rFEFE, 32
++	insrdi	r7F7F, r7F7F, 32, 0
++	add	rFEFE, rFEFE, rTMP
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	bne	L(copy_rest_bytes_for_unaligned)
++	ldu	rWORD2, 8(rSRC)
++	std	rWORD1, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 8
++	bne	L(move_register_10_for_unaligned)
++L(loop_for_nonaligned):
++	ld	rWORD1, 8(rSRC)
++	std	rWORD2, 0(rDEST)
++	add	rTMP, rFEFE, rWORD1
++	nor	rNEG, r7F7F, rWORD1
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 8
++	bne	L(copy_rest_bytes_for_unaligned)
++	ldu	rWORD2, 16(rSRC)
++	std	rWORD1, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 8
++	bne	L(move_register_10_for_unaligned)
++	ld	rWORD3, 8(rSRC)
++	std	rWORD2, 0(rDEST)
++	add	rTMP, rFEFE, rWORD3
++	nor	rNEG, r7F7F, rWORD3
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 8
++	bne	L(move_register_11)
++	ldu	rWORD4, 16(rSRC)
++	std	rWORD3, 0(rDEST)
++	add	rTMP, rFEFE, rWORD4
++	nor	rNEG, r7F7F, rWORD4
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 8
++	bne	L(move_register_12)
++	ldu	rWORD2, 8(rSRC)
++	std	rWORD4, 0(rDEST)
++	add	rTMP, rFEFE, rWORD2
++	nor	rNEG, r7F7F, rWORD2
++	and.	rTMP, rTMP, rNEG
++	addi	rDEST, rDEST, 8
++	beq	L(loop_for_nonaligned)
++L(move_register_10_for_unaligned):
++	 mr	rWORD1, rWORD2
++L(copy_rest_bytes_for_unaligned):
++	extrdi.	rTMP, rWORD1, 8, 0
++	stb	rTMP, 0(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD1, 8, 8
++	stb	rTMP, 1(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD1, 8, 16
++	stb	rTMP, 2(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD1, 8, 24
++	stb	rTMP, 3(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD1, 8, 32
++	stb	rTMP, 4(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD1, 8, 40
++	stb	rTMP, 5(rDEST)
++	beqlr
++	extrdi.	rTMP, rWORD1, 8, 48
++	stb	rTMP, 6(rDEST)
++	beqlr
++	stb	rWORD1, 7(rDEST)
++	blr
++L(move_register_11):
++	mr	rWORD1, rWORD3
++	b	L(copy_rest_bytes_for_unaligned)
++L(move_register_12):
++	mr	rWORD1, rWORD4
++	b	L(copy_rest_bytes_for_unaligned)
++L(src_unaligned):
++	lbz	rWORD1, 0(rSRC)
++	addi	rDEST, rRTN, 0
++	cmpwi	rWORD1, 0
++	stb	rWORD1, 0(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD2, 1(rSRC)
++	cmpwi	rWORD2, 0
++	stb	rWORD2, 1(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD3, 2(rSRC)
++	cmpwi	rWORD3, 0
++	stb	rWORD3, 2(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD2, 3(rSRC)
++	cmpwi	rWORD2, 0
++	stb	rWORD2, 3(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD1, 4(rSRC)
++	cmpwi	rWORD1, 0
++	stb	rWORD1, 4(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD3, 5(rSRC)
++	cmpwi	rWORD3, 0
++	stb	rWORD3, 5(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD3, 6(rSRC)
++	cmpwi	rWORD3, 0
++	stb	rWORD3, 6(rDEST)
++	beq	L(endstrcpy)
++	lbz	rWORD2, 7(rSRC)
++	cmpwi	rWORD2, 0
++	beq	L(endstrcpy1)
++	li	rTMP1, 8
++	sub	rTMP1, rTMP1, rTMP
++	add	rSRC, rSRC, rTMP1
++	add	rDEST, rDEST, rTMP1
++	b	L(src_got_aligned)
++L(endstrcpy1):
++	stb	rWORD2, 7(rDEST)
++L(endstrcpy):
++	blr
++
++END (strcpy)
++libc_hidden_builtin_def (strcpy)
diff --git a/recipes-core/glibc/glibc-fsl/0016-Remove-bash-dependency-for-nscd-init-script.patch b/recipes-core/glibc/glibc-fsl/0016-Remove-bash-dependency-for-nscd-init-script.patch
new file mode 100644
index 0000000..1d9983b
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0016-Remove-bash-dependency-for-nscd-init-script.patch
@@ -0,0 +1,75 @@
+From 69d378001adfe9a359d2f4b069c1ed2d36de4480 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Thu, 31 Dec 2015 14:33:02 -0800
+Subject: [PATCH 16/25] Remove bash dependency for nscd init script
+
+The nscd init script uses #! /bin/bash but only really uses one bashism
+(translated strings), so remove them and switch the shell to #!/bin/sh.
+
+Upstream-Status: Pending
+
+Signed-off-by: Ross Burton <ross.burton@intel.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ nscd/nscd.init | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/nscd/nscd.init b/nscd/nscd.init
+index a882da7d8b..b02986ec15 100644
+--- a/nscd/nscd.init
++++ b/nscd/nscd.init
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+ #
+ # nscd:		Starts the Name Switch Cache Daemon
+ #
+@@ -49,7 +49,7 @@ prog=nscd
+ start () {
+     [ -d /var/run/nscd ] || mkdir /var/run/nscd
+     [ -d /var/db/nscd ] || mkdir /var/db/nscd
+-    echo -n $"Starting $prog: "
++    echo -n "Starting $prog: "
+     daemon /usr/sbin/nscd
+     RETVAL=$?
+     echo
+@@ -58,7 +58,7 @@ start () {
+ }
+ 
+ stop () {
+-    echo -n $"Stopping $prog: "
++    echo -n "Stopping $prog: "
+     /usr/sbin/nscd -K
+     RETVAL=$?
+     if [ $RETVAL -eq 0 ]; then
+@@ -67,9 +67,9 @@ stop () {
+ 	# a non-privileged user
+ 	rm -f /var/run/nscd/nscd.pid
+ 	rm -f /var/run/nscd/socket
+-       	success $"$prog shutdown"
++	success "$prog shutdown"
+     else
+-       	failure $"$prog shutdown"
++	failure "$prog shutdown"
+     fi
+     echo
+     return $RETVAL
+@@ -103,13 +103,13 @@ case "$1" in
+ 	RETVAL=$?
+ 	;;
+     force-reload | reload)
+-    	echo -n $"Reloading $prog: "
++	echo -n "Reloading $prog: "
+ 	killproc /usr/sbin/nscd -HUP
+ 	RETVAL=$?
+ 	echo
+ 	;;
+     *)
+-	echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
++	echo "Usage: $0 {start|stop|status|restart|reload|condrestart}"
+ 	RETVAL=1
+ 	;;
+ esac
+-- 
+2.13.2
+
diff --git a/recipes-core/glibc/glibc-fsl/0016.glibc.fsl-strlen-e500mc-e5500.patch b/recipes-core/glibc/glibc-fsl/0016.glibc.fsl-strlen-e500mc-e5500.patch
new file mode 100755
index 0000000..e8844c4
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0016.glibc.fsl-strlen-e500mc-e5500.patch
@@ -0,0 +1,407 @@
+# Problem Statement:
+  Implement target specific optimized strlen for e500mc,
+  64-bit e5500
+
+# Owned by:
+  Ajay [based on existing 'asm' implementation of glibc]
+
+# Actions:
+  * For e500mc and e5500 [64-bit] targets,glibc implementation was reading
+    two words at a time,I have unrolled the loop to read four words at a time.
+
+  * Reordered the instruction to get the better performance.
+
+  * Rev2:
+    a) e500mc and e5500 64-bit: Fixed "segmentation fault" issues for strlen
+       with eglibc v2.15 test suite.
+    b) added e5500 32-bit strlen optimized library.
+    c) e5500 (32 & 64-bit) optimized strlen referenced from eglibc v2.19
+       power7 implementation
+
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e500mc/strlen.S patched/sysdeps/powerpc/powerpc32/e500mc/strlen.S
+--- vanilla/sysdeps/powerpc/powerpc32/e500mc/strlen.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e500mc/strlen.S	2015-03-12 07:37:15.310952010 -0500
+@@ -0,0 +1,168 @@
++/* Optimized strlen implementation for 32-bit e500mc PowerPC target.
++   Based on generic 32-bit PowerPC strlen implementation.
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* The algorithm here uses the following techniques:
++
++   1) Given a word 'x', we can test to see if it contains any 0 bytes
++      by subtracting 0x01010101, and seeing if any of the high bits of each
++      byte changed from 0 to 1.  This works because the least significant
++      0 byte must have had no incoming carry (otherwise it's not the least
++      significant), so it is 0x00 - 0x01 == 0xff.  For all other
++      byte values, either they have the high bit set initially, or when
++      1 is subtracted you get a value in the range 0x00-0x7f, none of which
++      have their high bit set.  The expression here is
++      (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
++      there were no 0x00 bytes in the word.  You get 0x80 in bytes that
++      match, but possibly false 0x80 matches in the next more significant
++      byte to a true match due to carries.  For little-endian this is
++      of no consequence since the least significant match is the one
++      we're interested in, but big-endian needs method 2 to find which
++      byte matches.
++
++   2) Given a word 'x', we can test to see _which_ byte was zero by
++      calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
++      This produces 0x80 in each byte that was zero, and 0x00 in all
++      the other bytes.  The '| 0x7f7f7f7f' clears the low 7 bits in each
++      byte, and the '| x' part ensures that bytes with the high bit set
++      produce 0x00.  The addition will carry into the high bit of each byte
++      iff that byte had one of its low 7 bits set.  We can then just see
++      which was the most significant bit set and divide by 8 to find how
++      many to add to the index.
++      This is from the book 'The PowerPC Compiler Writer's Guide',
++      by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
++
++   We deal with strings not aligned to a word boundary by taking the
++   first word and ensuring that bytes not part of the string
++   are treated as nonzero.  To allow for memory latency, we unroll the
++   loop a few times, being careful to ensure that we do not read ahead
++   across cache line boundaries.
++
++   Questions to answer:
++   1) How long are strings passed to strlen? If they're often really long,
++   we should probably use cache management instructions and/or unroll the
++   loop more.  If they're often quite short, it might be better to use
++   fact (2) in the inner loop than have to recalculate it.
++   2) How popular are bytes with the high bit set? If they are very rare,
++   on some processors it might be useful to use the simpler expression
++   ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
++   ALU), but this fails when any character has its high bit set.  */
++
++/* Some notes on register usage: Under the SVR4 ABI, we can use registers
++   0 and 3 through 12 (so long as we don't call any procedures) without
++   saving them.  We can also use registers 14 through 31 if we save them.
++   We can't use r1 (it's the stack pointer), r2 nor r13 because the user
++   program may expect them to hold their usual value if we get sent
++   a signal.  Integer parameters are passed in r3 through r10.
++   We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
++   them, the others we must save.  */
++
++/* int [r3] strlen (char *s [r3])  */
++
++ENTRY (strlen)
++
++#define rTMP1	r0
++#define rRTN	r3	/* incoming STR arg, outgoing result.  */
++#define rSTR	r4	/* current string position.  */
++#define rPADN	r5	/* number of padding bits we prepend to the
++			   string to make it start at a word boundary.  */
++#define rTMP3	r5
++#define rFEFE	r6	/* constant 0xfefefeff (-0x01010101).  */
++#define r7F7F	r7	/* constant 0x7f7f7f7f.  */
++#define rWORD1	r8	/* current string word.  */
++#define rWORD2	r9	/* next string word.  */
++#define rMASK	r9	/* mask for first string word.  */
++#define rTMP2	r10
++
++	clrrwi	rSTR, rRTN, 2
++	lis	r7F7F, 0x7f7f
++	rlwinm	rPADN, rRTN, 3, 27, 28
++	lwz	rWORD1, 0(rSTR)
++	li	rMASK, -1
++	addi	r7F7F, r7F7F, 0x7f7f
++	/* That's the setup done, now do the first pair of words.
++	   We make an exception and use method (2) on the first two words, to
++	   reduce overhead.  */
++	srw	rMASK, rMASK, rPADN
++	and	rTMP1, r7F7F, rWORD1
++	or	rTMP2, r7F7F, rWORD1
++	add	rTMP1, rTMP1, r7F7F
++	nor	rTMP1, rTMP2, rTMP1
++	and.	rWORD1, rTMP1, rMASK
++	mtcrf	0x01, rRTN
++	bne	L(done0)
++	lis	rFEFE, -0x101
++	addi	rFEFE, rFEFE, -0x101
++	/* Are we now aligned to a double word boundary?  */
++	bt	29, L(loop)
++	/* Handle second word of pair.  */
++	lwzu	rWORD1, 4(rSTR)
++	and	rTMP1, r7F7F, rWORD1
++	or	rTMP2, r7F7F, rWORD1
++	add	rTMP1, rTMP1, r7F7F
++	nor.	rWORD1, rTMP2, rTMP1
++	bne	L(done0)
++	/* The loop.  */
++L(loop):
++	lwz	rWORD1, 4(rSTR)
++	lwzu	rWORD2, 8(rSTR)
++	add	rTMP1, rFEFE, rWORD1
++	nor	rTMP2, r7F7F, rWORD1
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rWORD2
++	bne	L(done1)
++	nor	rTMP2, r7F7F, rWORD2
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(address)
++	lwz	rWORD1, 4(rSTR)
++	lwzu	rWORD2, 8(rSTR)
++	add	rTMP1, rFEFE, rWORD1
++	nor	rTMP2, r7F7F, rWORD1
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rWORD2
++	bne	L(done1)
++	nor	rTMP2, r7F7F, rWORD2
++	and.	rTMP1, rTMP1, rTMP2
++	beq	L(loop)
++	and	rTMP1, r7F7F, rWORD2
++	add	rTMP1, rTMP1, r7F7F
++	andc	rWORD1, rTMP2, rTMP1
++	b	L(done0)
++L(address):
++	mr	rWORD1, rWORD2
++	addi	rSTR, rSTR, 4
++L(done1):
++	and	rTMP1, r7F7F, rWORD1
++	subi	rSTR, rSTR, 4
++	add	rTMP1, rTMP1, r7F7F
++	andc	rWORD1, rTMP2, rTMP1
++	/* When we get to here, rSTR points to the first word in the string
++	   that contains a zero byte, and the most significant set bit in
++	   rWORD1 is in that byte.  */
++L(done0):
++	cntlzw	rTMP3, rWORD1
++	subf	rTMP1, rRTN, rSTR
++	srwi	rTMP3, rTMP3, 3
++	add	rRTN, rTMP1, rTMP3
++	/* GKM FIXME: check high bound.  */
++	blr
++
++END (strlen)
++libc_hidden_builtin_def (strlen)
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e5500/strlen.S patched/sysdeps/powerpc/powerpc32/e5500/strlen.S
+--- vanilla/sysdeps/powerpc/powerpc32/e5500/strlen.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e5500/strlen.S	2015-03-12 07:40:07.346952026 -0500
+@@ -0,0 +1,123 @@
++/* Optimized strlen implementation for 32-bit e5500 PowerPC target.
++   Based on POWER7 strlen implementation.
++   Copyright (C) 2010-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* int [r3] strlen (char *s [r3])  */
++
++ENTRY (strlen)
++
++	clrrwi	r4, r3, 2	/* Align the address to word boundary.  */
++	rlwinm	r6, r3, 3, 27, 28	/* Calculate padding.  */
++	li	r0, 0		/* Word with null chars to use with cmpb.  */
++	li	r5, -1		/* MASK = 0xffffffffffffffff.  */
++	lwz	r12, 0(r4)	/* Load word from memory.  */
++	srw	r5, r5, r6	/* MASK = MASK >> padding.  */
++	orc	r9, r12, r5	/* Mask bits that are
++				   not part of the string.  */
++	cmpb	r10, r9, r0	/* Check for null bytes in WORD1.  */
++	cmpwi	cr7, r10, 0	/* If r10 == 0, no null's have been found.  */
++	bne	cr7, L(done)
++	/* Are we now aligned to a four word boundary?  If so, skip to the
++	   main loop.  Otherwise, go through the alignment code.  */
++	mtcrf	0x01, r3
++	bt	28, L(if_source_aligned_by_8_or_12)
++	bt	29, L(if_source_aligned_by_4)
++	/* Handle WORD2,WORD3,WORD4 as source is aligned by 0.  */
++	lwzu	r12, 4(r4)
++	cmpb	r10, r12, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done)
++	lwzu	r12, 4(r4)
++	cmpb	r10, r12, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done)
++	lwzu	r12, 4(r4)
++	cmpb	r10, r12, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done)
++	b	L(loop)		/* We branch here (rather than falling through)
++				   to skip the nops due to heavy alignment
++				   of the loop below.  */
++L(if_source_aligned_by_8_or_12):
++	bt	29, L(loop)	/* if source address is aligned by 12 then only
++				   one word needs to be handled to make source
++				   address as 16 byte align which we have
++				   already handled in the begining, so jump
++				   directly to main loop.  */
++	lwzu	r12, 4(r4)	/* else source is aligned by 8.  */
++	cmpb	r10, r12, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done)
++L(loop):
++	lwz	r8, 4(r4)
++	lwzu	r9, 8(r4)
++	lwz	r11, 4(r4)
++	lwzu	r12, 8(r4)
++	cmpb	r10, r8, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done1)
++	cmpb	r10, r9, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done2)
++	cmpb	r10, r11, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done3)
++	cmpb	r10, r12, r0
++	cmpwi	cr7, r10, 0
++	beq	cr7, L(loop)
++	/* r10 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original word
++	   from the string.  Use that to calculate the length.  */
++	cntlzw	r0, r10
++	subf	r5, r3, r4
++	srwi	r0, r0, 3
++	add	r3, r5, r0
++	blr
++L(done1):
++	addi	r4, r4, -12	/* Adjust the address.  */
++L(done):
++	cntlzw	r0, r10		/* Count leading zeroes before the match.  */
++	subf	r5, r3, r4
++	srwi	r0, r0, 3	/* Convert leading zeroes to bytes.  */
++	add	r3, r5, r0	/* Compute final length.  */
++	blr
++L(done2):
++	addi	r4, r4, -8	/* Adjust the address.  */
++	b	L(done)
++L(done3):
++	addi	r4, r4, -4	/* Adjust the address.  */
++	b	L(done)
++	/* if source address is aligned by 4 then total three words need to
++	   be handled to make source address as 16 byte align in which we
++	   have already handled one word in the begining, so now handle next
++	   two words then jump to main loop.  */
++L(if_source_aligned_by_4):
++	lwzu	r12, 4(r4)
++	cmpb	r10, r12, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done)
++	lwzu	r12, 4(r4)
++	cmpb	r10, r12, r0
++	cmpwi	cr7, r10, 0
++	bne	cr7, L(done)
++	b	L(loop)
++
++END (strlen)
++libc_hidden_builtin_def (strlen)
+diff -Naur vanilla/sysdeps/powerpc/powerpc64/e5500/strlen.S patched/sysdeps/powerpc/powerpc64/e5500/strlen.S
+--- vanilla/sysdeps/powerpc/powerpc64/e5500/strlen.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc64/e5500/strlen.S	2015-03-12 07:39:06.118952040 -0500
+@@ -0,0 +1,84 @@
++/* Optimized strlen implementation for 64-bit e5500 PowerPC target.
++   Based on POWER7 strlen implementation.
++   Copyright (C) 2010-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* int [r3] strlen (char *s [r3])  */
++
++ENTRY (strlen)
++	CALL_MCOUNT 1
++
++	dcbt	0, r3
++	clrrdi	r4, r3, 3	/* Align address to double word boundary.  */
++	rlwinm	r6, r3, 3, 26, 28	/* Calculate padding.  */
++	li	r0, 0		/* Doubleword with null chars to use
++				   with cmpb.  */
++	li	r5, -1		/* MASK = 0xffffffffffffffff.  */
++	ld	r12, 0(r4)	/* Load doubleword from memory.  */
++	srd	r5, r5, r6	/* MASK = MASK >> padding.  */
++	orc	r9, r12, r5	/* Mask bits that are not part of string.  */
++	cmpb	r10, r9, r0	/* Check for null bytes in DWORD1.  */
++	cmpdi	cr7, r10, 0	/* If r10 == 0, no null's have been found.  */
++	bne	cr7, L(done)
++	mtcrf	0x01, r4
++	/* Are we now aligned to a quad word boundary?  If so, skip to the
++	   main loop.  Otherwise, go through the alignment code.  */
++	bt	28, L(loop)
++/* Handle DWORD2 of pair.  */
++	ldu	r12, 8(r4)
++	cmpb	r10, r12, r0
++	cmpdi	cr7, r10, 0
++	bne	cr7, L(done)
++	b	L(loop)		/* We branch here (rather than falling through)
++				   to skip the nops due to heavy alignment of
++				   the loop below.  */
++L(loop):
++	/* Load two doublewords, compare and merge in a single register for
++	   speed.  This is an attempt to speed up the null-checking process
++	   for bigger strings.  */
++	ld	r12, 8(r4)
++	ldu	r11, 16(r4)
++	cmpb	r10, r12, r0
++	cmpb	r9, r11, r0
++	or	r8, r9, r10	/* Merge everything in one doubleword.  */
++	cmpdi	cr7, r8, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the doublewords contains a null byte.  Check
++	   the first doubleword and decrement the address in case the first
++	   doubleword really contains a null byte.  */
++	cmpdi	cr6, r10, 0
++	addi	r4, r4, -8
++	bne	cr6, L(done)
++	/* The null byte must be in the second doubleword.  Adjust the address
++	   again and move the result of cmpb to r10 so we can calculate the
++	   length.  */
++	mr	r10, r9
++	addi	r4, r4, 8
++	/* r10 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original
++	   doubleword from the string.  Use that to calculate the length.  */
++L(done):
++	cntlzd	r0, r10		/* Count leading zeroes before the match.  */
++	subf	r5, r3, r4
++	srdi	r0, r0, 3	/* Convert leading zeroes to bytes.  */
++	add	r3, r5, r0	/* Compute final length.  */
++	blr
++
++END (strlen)
++libc_hidden_builtin_def (strlen)
diff --git a/recipes-core/glibc/glibc-fsl/0017.glibc.fsl-strrchr-e500mc-e5500.patch b/recipes-core/glibc/glibc-fsl/0017.glibc.fsl-strrchr-e500mc-e5500.patch
new file mode 100755
index 0000000..64cec3a
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0017.glibc.fsl-strrchr-e500mc-e5500.patch
@@ -0,0 +1,1072 @@
+# Problem Statement:
+  Implement target specific optimized strrchr for e500mc, 32-bit e5500 and
+  64-bit e5500
+
+# Owned by:
+  Mahesh [based on existing 'asm' implementation of glibc strchr]
+
+# Actions:
+  * For e500mc target, default glibc implementation reads
+    two words at a time. Current implementation unrolls the loop to
+    read eight words.
+
+  * For e5500 [32-bit and 64-bit] targets, use 'cmpb' instruction to check 
+    the occurance of NULL and expected character in a string.
+
+  * Reordered the instructions to get the better performance
+
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e500mc/strrchr.S patched/sysdeps/powerpc/powerpc32/e500mc/strrchr.S
+--- vanilla/sysdeps/powerpc/powerpc32/e500mc/strrchr.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e500mc/strrchr.S	2015-03-13 03:18:38.082952006 -0500
+@@ -0,0 +1,344 @@
++/* Optimized strrchr implementation for PowerPC e500mc target.
++   Based on generic strchr implementation of 32-bit PowerPC.
++   Copyright (C) 1997-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how this works.  */
++
++/* char * [r3] strrchr (const char *s [r3] , int c [r4])  */
++
++ENTRY (strrchr)
++
++#define rTMP1	r0
++#define rRTN	r3	/* outgoing result.  */
++#define rSTR	r8	/* current word pointer.  */
++#define rCHR	r4	/* byte we are looking for, spread over the
++			   whole word.  */
++#define rWORD	r5	/* the current word.  */
++#define rFEFE	r6	/* constant 0xfefefeff (-0x01010101).  */
++#define r7F7F	r7	/* constant 0x7f7f7f7f.  */
++#define rTMP2	r9
++#define rIGN	r10	/* number of bits we should ignore in first word.  */
++#define rMASK	r11	/* mask with the bits to ignore set to rTMP1
++			   and to load preceding word.  */
++#define rTMP3	r12
++
++	andi.	rTMP2, rRTN, 3
++	cmplwi	cr7, rCHR, 0
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	rlwimi	rCHR, rCHR, 16, 0, 15
++	lis	rFEFE, -0x101
++	lis	r7F7F, 0x7f7f
++	clrrwi	rSTR, rRTN, 2
++	addi	rFEFE, rFEFE, -0x101
++	addi	r7F7F, r7F7F, 0x7f7f
++	lwz	rWORD, 0(rSTR)
++	li	rIGN, -1
++	beq	L(srcalign)
++	rlwinm	rTMP1, rRTN, 3, 27, 28
++	srw	rMASK, rIGN, rTMP1
++	orc	rWORD, rWORD, rMASK
++	li	rRTN, 0
++	beq	cr7, L(null)
++	add	rTMP1, rFEFE, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	xor	rTMP3, rCHR, rWORD
++	orc	rTMP3, rTMP3, rMASK
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	b	L(loop)
++L(srcalign):
++	li	rRTN, 0
++	beq	cr7, L(nullwordalign)
++L(srcalign2):
++	add	rTMP1, rFEFE, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	xor	rTMP3, rCHR, rWORD
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++L(loop):
++	lwzu	rMASK, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rMASK
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rMASK
++	xor	rTMP3, rCHR, rMASK
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed1)
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit1)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	lwzu	rMASK, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rMASK
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rMASK
++	xor	rTMP3, rCHR, rMASK
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed1)
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit1)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	lwzu	rMASK, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rMASK
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rMASK
++	xor	rTMP3, rCHR, rMASK
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed1)
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit1)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rWORD
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	lwzu	rMASK, 4(rSTR)
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit)
++	add	rTMP1, rFEFE, rMASK
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rMASK
++	xor	rTMP3, rCHR, rMASK
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed1)
++	nor	rTMP2, r7F7F, rTMP3
++	lwzu	rWORD, 4(rSTR)
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundit1)
++	add	rTMP1, rFEFE, rWORD
++	/* Test for rTMP1.  */
++	nor	rTMP2, r7F7F, rWORD
++	dcbt	rTMP1, rSTR
++	xor	rTMP3, rCHR, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	add	rTMP1, rFEFE, rTMP3
++	beq	L(loop)
++L(missed):
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	beqlr
++	and	rFEFE, r7F7F, rWORD
++	or	rMASK, r7F7F, rWORD
++	and	rTMP1, r7F7F, rTMP3
++	or	rTMP2, r7F7F, rTMP3
++	add	rFEFE, rFEFE, r7F7F
++	add	rTMP1, rTMP1, r7F7F
++	nor	rWORD, rMASK, rFEFE
++	nor	rTMP2, rTMP2, rTMP1
++	cmplw	rWORD, rTMP2
++	bgtlr
++	cntlzw	rWORD, rTMP2
++	srwi	rWORD, rWORD, 3
++	add	rRTN, rSTR, rWORD
++	addi	rSTR, rRTN, 1
++	andi.	rTMP2, rSTR, 3
++	cmpwi	rFEFE, rTMP2, 2
++	bgt	rFEFE, L(b3l)
++	li	rTMP1, 24
++	srw	rCHR, rCHR, rTMP1
++	beq	rFEFE, L(b2)
++	lbz	rWORD, 0(rSTR)
++	cmpwi	rFEFE, rWORD, 0
++	beq	rFEFE, L(b3l)
++	lbzu	rTMP3, 1(rSTR)
++	cmpw	r7F7F, rWORD, rCHR
++	beq	r7F7F, L(ret1)
++	cmpwi	rFEFE, rTMP3, 0
++	beq	rFEFE, L(b3l)
++	cmpw	r7F7F, rTMP3, rCHR
++	beq	r7F7F, L(ret2)
++	blr
++L(missed1):
++	mr	rWORD,rMASK
++	nor	rTMP2, r7F7F, rTMP3
++	and.	rTMP1, rTMP1, rTMP2
++	beqlr
++	and	rFEFE, r7F7F, rWORD
++	or	rMASK, r7F7F, rWORD
++	and	rTMP1, r7F7F, rTMP3
++	or	rTMP2, r7F7F, rTMP3
++	add	rFEFE, rFEFE, r7F7F
++	add	rTMP1, rTMP1, r7F7F
++	nor	rWORD, rMASK, rFEFE
++	nor	rTMP2, rTMP2, rTMP1
++	cmplw	rWORD, rTMP2
++	bgtlr
++	cntlzw	rWORD, rTMP2
++	srwi	rWORD, rWORD, 3
++	add	rRTN, rSTR, rWORD
++	addi	rSTR, rRTN, 1
++	andi.	rTMP2, rSTR, 3
++	cmpwi	rFEFE, rTMP2, 2
++	bgt	rFEFE, L(b3l)
++	li	rTMP1, 24
++	srw	rCHR, rCHR, rTMP1
++	beq	rFEFE, L(b2)
++	lbz	rWORD, 0(rSTR)
++	cmpwi	rFEFE, rWORD, 0
++	beq	rFEFE, L(b3l)
++	lbzu	rTMP3, 1(rSTR)
++	cmpw	r7F7F, rWORD, rCHR
++	beq	r7F7F, L(ret1)
++	cmpwi	rFEFE, rTMP3, 0
++	beq	rFEFE, L(b3l)
++	cmpw	r7F7F, rTMP3, rCHR
++	beq	r7F7F, L(ret2)
++	blr
++L(ret2):
++	mr	rRTN, rSTR
++	blr
++L(ret1):
++	subi	rRTN, rSTR, 1
++	blr
++L(b2):
++	lbz	rWORD, 0(rSTR)
++	cmpwi	rFEFE, rWORD, 0
++	beq	rFEFE, L(b3l)
++	cmpw	r7F7F, rWORD, rCHR
++	beq	r7F7F, L(ret)
++	blr
++L(ret):
++	mr	rRTN, rSTR
++	blr
++L(b3l):
++	blr
++L(foundit):
++	and	rTMP1, r7F7F, rTMP3
++	or	rTMP2, r7F7F, rTMP3
++	add	rTMP1, rTMP1, r7F7F
++	nor	rTMP2, rTMP2, rTMP1
++	cntlzw	rTMP3, rTMP2
++	subi	rSTR, rSTR, 4
++	srwi	rTMP3, rTMP3, 3
++	add	rRTN, rSTR, rTMP3
++	addi	rTMP1, rRTN, 1
++L(Nextword):
++	andi.	rTMP2, rTMP1, 3
++	clrrwi	rSTR, rTMP1, 2
++	bne	L(srcalign_make)
++	mr	rWORD,rMASK
++	b	L(srcalign2)
++L(srcalign_make):
++	rlwinm	rTMP1, rTMP1, 3, 27, 28
++	slw	rWORD, rWORD, rTMP1
++	srw	rWORD, rWORD, rTMP1
++	srw	rMASK, rIGN, rTMP1
++	orc	rWORD, rWORD, rMASK
++	add	rTMP1, rFEFE, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	xor	rTMP3, rCHR, rWORD
++	orc	rTMP3, rTMP3, rMASK
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	b	L(loop)
++L(foundit1):
++	and	rTMP1, r7F7F, rTMP3
++	or	rTMP2, r7F7F, rTMP3
++	add	rTMP1, rTMP1, r7F7F
++	nor	rTMP2, rTMP2, rTMP1
++	cntlzw	rTMP3, rTMP2
++	subi	rSTR, rSTR, 4
++	srwi	rTMP3, rTMP3, 3
++	add	rRTN, rSTR, rTMP3
++	addi	rTMP1, rRTN, 1
++L(Nextword1):
++	andi.	rTMP2, rTMP1, 3
++	clrrwi	rSTR, rTMP1, 2
++	beq	L(srcalign2)
++	mr	rWORD, rMASK
++	rlwinm	rTMP1, rTMP1, rRTN, 27, 28
++	slw	rWORD, rWORD, rTMP1
++	srw	rWORD, rWORD, rTMP1
++	srw	rMASK, rIGN, rTMP1
++	orc	rWORD, rWORD, rMASK
++	add	rTMP1, rFEFE, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	xor	rTMP3, rCHR, rWORD
++	orc	rTMP3, rTMP3, rMASK
++	add	rTMP1, rFEFE, rTMP3
++	bne	L(missed)
++	b	L(loop)
++
++L(nullwordalign):
++	add	rTMP1, rFEFE, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundnull)
++	b	L(loopnull)
++L(null):
++	add	rTMP1, rFEFE, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	bne	L(foundnull)
++L(loopnull):
++	lwzu	rWORD, 4(rSTR)
++	add	rTMP1, rFEFE, rWORD
++	nor	rTMP2, r7F7F, rWORD
++	and.	rTMP1, rTMP1, rTMP2
++	beq	L(loopnull)
++L(foundnull):
++	and	rTMP1, r7F7F, rWORD
++	or	rIGN, r7F7F, rWORD
++	add	rTMP1, rTMP1, r7F7F
++	nor	rTMP2, rIGN, rTMP1
++	cntlzw	rTMP3, rTMP2
++	srwi	rTMP3, rTMP3, 3
++	add	rRTN, rSTR, rTMP3
++	blr
++END (strrchr)
++
++weak_alias (strrchr, rindex)
++libc_hidden_builtin_def (strrchr)
+diff -Naur vanilla/sysdeps/powerpc/powerpc32/e5500/strrchr.S patched/sysdeps/powerpc/powerpc32/e5500/strrchr.S
+--- vanilla/sysdeps/powerpc/powerpc32/e5500/strrchr.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc32/e5500/strrchr.S	2015-03-13 03:19:56.365952010 -0500
+@@ -0,0 +1,348 @@
++/* Optimized strrchr implementation for 32-bit e5500 PowerPC target.
++   Based on POWER7 strchr implementation.
++   Copyright (C) 2010-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how this works.  */
++
++/* char * [r3] strrchr (const char *s [r3] , int c [r4])  */
++
++ENTRY (strrchr)
++
++#define rTMP1	r0
++#define rRTN	r3	/* outgoing result.  */
++#define rSTR	r8	/* current word pointer.  */
++#define rCHR	r4	/* byte we are looking for, spread over the
++			   whole word.  */
++#define rTMP2	r5
++#define rMASK	r6	/* calculate padding bits.  */
++#define rTMP3	r7
++#define rWORD	r12	/* the current word.  */
++#define rWORD2	r9	/* following word.  */
++#define rTMP4	r10
++#define rTMP5	r11
++
++	dcbt	0, rRTN
++	andi.	rTMP3, rRTN, 7		/* check for double word boundary.  */
++	cmpwi	cr7, rCHR, 0
++	li	rTMP1, 0
++	/* Replicate byte to double word.  */
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	rlwimi	rCHR,rCHR, 16, 0, 15
++	beq	L(dwalign)
++	subfic	rTMP3, rTMP3, 8
++	cmplwi	cr6, rTMP3, 4
++	clrrwi	rSTR, rRTN, 2		/* Align address to word boundary.  */
++	beq	cr6, L(word2)
++	blt	cr6, L(LTword2)
++	lwz	rWORD, 0(rSTR)		/* Load word from memory.  */
++	rlwinm	rMASK, rRTN, 3, 27, 28	/* Calculate padding.  */
++	/* By now the rCHR has a word of c bytes and the rTMP1 has a word of
++	   null bytes.  */
++	li	rRTN, 0
++	beq	cr7, L(null_match)
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte against c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against the null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP4, rTMP4, rMASK
++	slw	rTMP5, rTMP5, rMASK
++	srw	rTMP4, rTMP4, rMASK
++	srw	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpwi	cr7, rTMP2, 0		/* If rTMP2 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	/* Handle WORD2 of pair.  */
++	lwzu	rWORD, 4(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)			/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(LTword2):
++	lwz	rWORD, 0(rSTR)		/* Load word from memory.  */
++	rlwinm	rMASK, rRTN, 3, 27, 28	/* Calculate padding.  */
++	/* By now the rCHR has a word of c bytes and the rTMP1 has a word
++	   of null bytes.  */
++	li	rRTN, 0
++	beq	cr7, L(null_LTword2)
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against the null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP4, rTMP4, rMASK
++	slw	rTMP5, rTMP5, rMASK
++	srw	rTMP4, rTMP4, rMASK
++	srw	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpwi	cr7, rTMP2, 0		/* If rTMP2 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	b	L(loop)
++L(word2):
++	lwz	rWORD, 0(rSTR)
++	li	rRTN, 0
++	beq	cr7, L(null_word2)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)
++L(dwalign):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for
++	   bigger strings.  */
++	mr	rSTR, rRTN
++	li	rRTN, 0
++	lwz	rWORD, 0(rSTR)
++	lwzu	rWORD2, 4(rSTR)
++	beq	cr7, L(dwalignnull)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	cmpb	rMASK, rWORD2, rCHR
++	cmpb	rTMP3, rWORD2, rTMP1
++	or	rWORD, rTMP4, rTMP5
++	or	rWORD2, rMASK, rTMP3
++	or	rTMP2, rWORD, rWORD2
++	cmpwi	cr7, rTMP2, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the words contains a c/null byte.  Check
++	   the first word and decrement the address in case the first word
++	   really contains a c/null byte.  */
++	cmpwi	cr6, rWORD, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done)
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP4, rMASK
++	mr	rTMP5, rTMP3
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the c/null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++	b	L(done)
++L(loop):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for
++	   bigger strings.  */
++	lwz	rWORD, 4(rSTR)
++	lwzu	rWORD2, 8(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	cmpb	rMASK, rWORD2, rCHR
++	cmpb	rTMP3, rWORD2, rTMP1
++	or	rWORD, rTMP4, rTMP5
++	or	rWORD2, rMASK, rTMP3
++	or	rTMP2, rWORD, rWORD2
++	cmpwi	cr7, rTMP2, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the words contains a c/null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a c/null byte.  */
++	cmpwi	cr6, rWORD, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done)
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP4, rMASK
++	mr	rTMP5, rTMP3
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the c/null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++L(done):
++	cntlzw	rTMP3, rTMP4		/* Count leading zeroes before c
++					   matches.  */
++	cntlzw	rMASK, rTMP5		/* Count leading zeroes before null
++					   matches.  */
++	cmplw	cr7, rTMP3, rMASK
++	bgt	cr7, L(no_match)
++	srwi	rMASK, rTMP3, 3		/* Convert leading zeroes to bytes.  */
++	add	rRTN, rSTR, rMASK	/* Return addr of the matching c byte
++					   or null in case c is not found.  */
++	addi	rTMP4, rRTN, 1
++L(loop_check):
++	andi.	rTMP3, rTMP4, 7		/* check for double word boundary.  */
++	beq	L(loop)
++	subfic	rTMP3, rTMP3, 8
++	cmpwi	cr6, rTMP3, 4
++	clrrwi	rSTR, rTMP4, 2		/* Align address to word boundary.  */
++	lwz	rWORD, 0(rSTR)
++	beq	cr6, L(word2_check)
++	ble	cr6, L(LTword2_check)
++	rlwinm	rMASK, rTMP4, 3, 27, 28	/* Calculate padding.  */
++	/* By now the rCHR has a word of c bytes and the rTMP1 has a word
++	   of null bytes.  */
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP4, rTMP4, rMASK
++	slw	rTMP5, rTMP5, rMASK
++	srw	rTMP4, rTMP4, rMASK
++	srw	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpwi	cr7, rTMP2, 0		/* If rTMP2 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	/* Handle WORD2 of pair.  */
++	lwzu	rWORD, 4(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)			/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(LTword2_check):
++	rlwinm	rMASK, rTMP4, 3, 27, 28	/* Calculate padding.  */
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP4, rTMP4, rMASK
++	slw	rTMP5, rTMP5, rMASK
++	srw	rTMP4, rTMP4, rMASK
++	srw	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpwi	cr7, rTMP2, 0		/* If rTMP2 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	b	L(loop)
++L(word2_check):
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)
++L(no_match):
++	blr
++	/* We are here because strrchr was called with a null byte.  */
++L(null_match):
++	/* rTMP1 has a word of null bytes.  */
++	cmpb	rTMP2, rWORD, rTMP1	/* Compare each byte against null
++					   bytes.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP2, rTMP2, rMASK
++	srw	rTMP2, rTMP2, rMASK
++	cmpwi	cr7, rTMP2, 0		/* If rTMP4 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done_null)
++	/* Handle WORD2 of pair.  */
++	lwzu	rWORD, 4(rSTR)
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done_null)
++	b	L(loop_null)		/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(null_LTword2):
++	/* rTMP1 has a word of null bytes.  */
++	cmpb	rTMP2, rWORD, rTMP1	/* Compare each byte against null
++					   bytes.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	slw	rTMP2, rTMP2, rMASK
++	srw	rTMP2, rTMP2, rMASK
++	cmpwi	cr7, rTMP2, 0		/* If rTMP4 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done_null)
++	b	L(loop_null)
++L(null_word2):
++	/* Handle WORD2 of pair.  */
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpwi	cr7, rTMP2, 0
++	bne	cr7, L(done_null)
++	b	L(loop_null)		/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(dwalignnull):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for
++	   bigger strings.  */
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpb	rTMP4, rWORD2, rTMP1
++	or	rMASK, rTMP2, rTMP4
++	cmpwi	cr7, rMASK, 0
++	beq	cr7, L(loop_null)
++	/* OK, one (or both) of the words contains a null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a null byte.  */
++	cmpwi	cr6, rTMP2, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done_null)
++	/* The null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP2, rTMP4
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++	b	L(done_null)
++L(loop_null):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for bigger
++	   strings.  */
++	lwz	rWORD, 4(rSTR)
++	lwzu	rTMP5, 8(rSTR)
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpb	rTMP4, rTMP5, rTMP1
++	or	rMASK, rTMP2, rTMP4
++	cmpwi	cr7, rMASK, 0
++	beq	cr7, L(loop_null)
++	/* OK, one (or both) of the words contains a null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a null byte.  */
++	cmpwi	cr6, rTMP2, 0
++	addi	rSTR, rSTR, -4
++	bne	cr6, L(done_null)
++	/* The null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP2, rTMP4
++	addi	rSTR, rSTR, 4
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++L(done_null):
++	cntlzw	rTMP1, rTMP2		/* Count leading zeros before match.  */
++	srwi	rTMP1, rTMP1, 3		/* Convert leading zeros to bytes.  */
++	add	rRTN, rSTR, rTMP1	/* Return address of the matching null
++					   byte.  */
++	blr
++
++END (strrchr)
++
++weak_alias (strrchr, rindex)
++libc_hidden_builtin_def (strrchr)
+diff -Naur vanilla/sysdeps/powerpc/powerpc64/e5500/strrchr.S patched/sysdeps/powerpc/powerpc64/e5500/strrchr.S
+--- vanilla/sysdeps/powerpc/powerpc64/e5500/strrchr.S	1969-12-31 18:00:00.000000000 -0600
++++ patched/sysdeps/powerpc/powerpc64/e5500/strrchr.S	2015-03-13 03:28:16.701951974 -0500
+@@ -0,0 +1,351 @@
++/* Optimized strrchr implementation for 64-bit e5500 PowerPC target.
++   Based on POWER7 strchr implementation.
++   Copyright (C) 2010-2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* See strlen.s for comments on how this works.  */
++
++/* char * [r3] strrchr (const char *s [r3] , int c [r4])  */
++
++ENTRY (strrchr)
++	CALL_MCOUNT 2
++
++#define rTMP1	r0
++#define rRTN	r3	/* outgoing result.  */
++#define rSTR	r8	/* current word pointer.  */
++#define rCHR	r4	/* byte we are looking for, spread over the whole
++			   word.  */
++#define rTMP2	r5
++#define rMASK	r6	/* calculate padding bits.  */
++#define rTMP3	r7
++#define rWORD	r12	/* the current word.  */
++#define rWORD2	r9	/* following word.  */
++#define rTMP4	r10
++#define rTMP5	r11
++
++	dcbt	0, rRTN
++	andi.	rTMP3, rRTN, 15		/* check for 4 word boundary.  */
++	cmpwi	cr7, rCHR, 0
++	li	rTMP1, 0
++	/* Replicate byte to double word.  */
++	rlwimi	rCHR, rCHR, 8, 16, 23
++	rlwimi	rCHR, rCHR, 16, 0, 15
++	insrdi	rCHR, rCHR, 32, 0
++	beq	L(qwalign)
++	subfic	rTMP3, rTMP3, 16
++	cmpldi	cr6, rTMP3, 8
++	clrrdi	rSTR, rRTN, 3		/* Align the address to double word
++					   boundary.  */
++	beq	cr6, L(doubleword2)
++	blt	cr6, L(LTdoubleword2)
++	ld	rWORD, 0(rSTR)		/* Load word from memory.  */
++	rlwinm	rMASK, rRTN, 3, 26, 28	/* Calculate padding.  */
++	/* By now the rCHR has a word of c bytes and the rTMP1 has a word of
++	   null bytes.  */
++	li	rRTN, 0
++	beq	cr7, L(null_match)
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not part
++	   of the string and to bring them back as zeros.  */
++	sld	rTMP4, rTMP4, rMASK
++	sld	rTMP5, rTMP5, rMASK
++	srd	rTMP4, rTMP4, rMASK
++	srd	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpdi	cr7, rTMP2, 0		/* If rTMP2==0,no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	/* Handle WORD2 of pair.  */
++	ldu	rWORD, 8(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpdi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)			/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(LTdoubleword2):
++	ld	rWORD, 0(rSTR)		/* Load word from memory.  */
++	rlwinm	rMASK, rRTN, 3, 26, 28	/* Calculate padding.  */
++	/* By now rCHR has a word of c bytes and rTMP1 has a word of null
++	   bytes.  */
++	li	rRTN, 0
++	beq	cr7, L(null_LTdoubleword2)
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	sld	rTMP4, rTMP4, rMASK
++	sld	rTMP5, rTMP5, rMASK
++	srd	rTMP4, rTMP4, rMASK
++	srd	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpdi	cr7, rTMP2, 0		/* If rTMP2==0,no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	b	L(loop)
++L(doubleword2):
++	ld	rWORD, 0(rSTR)
++	li	rRTN, 0
++	beq	cr7, L(null_doubleword2)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpdi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)
++L(qwalign):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for bigger
++	   strings.  */
++	mr	rSTR, rRTN
++	li	rRTN, 0
++	ld	rWORD, 0(rSTR)
++	ldu	rWORD2, 8(rSTR)
++	beq	cr7, L(qwalignnull)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	cmpb	rMASK, rWORD2, rCHR
++	cmpb	rTMP3, rWORD2, rTMP1
++	or	rWORD, rTMP4, rTMP5
++	or	rWORD2, rMASK, rTMP3
++	or	rTMP2, rWORD, rWORD2
++	cmpdi	cr7, rTMP2, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the words contains a c/null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a c/null byte.  */
++	cmpdi	cr6, rWORD, 0
++	addi	rSTR, rSTR, -8
++	bne	cr6, L(done)
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP4, rMASK
++	mr	rTMP5, rTMP3
++	addi	rSTR, rSTR, 8
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the c/null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++	b	L(done)
++L(loop):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for bigger
++	   strings.  */
++	ld	rWORD, 8(rSTR)
++	ldu	rWORD2, 16(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	cmpb	rMASK, rWORD2, rCHR
++	cmpb	rTMP3, rWORD2, rTMP1
++	or	rWORD, rTMP4, rTMP5
++	or	rWORD2, rMASK, rTMP3
++	or	rTMP2, rWORD, rWORD2
++	cmpdi	cr7, rTMP2, 0
++	beq	cr7, L(loop)
++	/* OK, one (or both) of the words contains a c/null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a c/null byte.  */
++	cmpdi	cr6, rWORD, 0
++	addi	rSTR, rSTR, -8
++	bne	cr6, L(done)
++	/* The c/null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP4, rMASK
++	mr	rTMP5, rTMP3
++	addi	rSTR, rSTR, 8
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the c/null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++L(done):
++	cntlzd	rTMP3, rTMP4		/* Count the leading zeroes before c
++					   matches.  */
++	cntlzd	rMASK, rTMP5		/* Count the leading zeroes before
++					   null matches.  */
++	cmpld	cr7, rTMP3, rMASK
++	bgt	cr7, L(no_match)
++	srdi	rMASK, rTMP3, 3		/* Convert leading zeroes to bytes.  */
++	add	rRTN, rSTR, rMASK	/* Return addr of the matching c byte
++					   or null in case c was not found.  */
++	addi	rTMP4, rRTN, 1
++L(loop_check):
++	andi.	rTMP3, rTMP4, 15	/* check for 4 word boundary.  */
++	beq	L(loop)
++	subfic	rTMP3, rTMP3, 16
++	cmpldi	cr6, rTMP3, 8
++	clrrdi	rSTR, rTMP4, 3		/* Align the address to double word
++					   boundary.  */
++	ld	rWORD, 0(rSTR)		/* Load double word from memory.  */
++	beq	cr6, L(doubleword2_check)
++	ble	cr6, L(LTdoubleword2_check)
++	rlwinm	rMASK, rTMP4, 3, 26, 28	/* Calculate padding.  */
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	sld	rTMP4, rTMP4, rMASK
++	sld	rTMP5, rTMP5, rMASK
++	srd	rTMP4, rTMP4, rMASK
++	srd	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpdi	cr7, rTMP2, 0		/* If rTMP2==0,no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	/* Handle WORD2 of pair.  */
++	ldu	rWORD, 8(rSTR)
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpdi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)			/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(LTdoubleword2_check):
++	rlwinm	rMASK, rTMP4, 3, 26, 28	/* Calculate padding.  */
++	cmpb	rTMP4, rWORD, rCHR	/* Compare each byte with c byte.  */
++	cmpb	rTMP5, rWORD, rTMP1	/* Compare each byte against null
++					   byte.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	sld	rTMP4, rTMP4, rMASK
++	sld	rTMP5, rTMP5, rMASK
++	srd	rTMP4, rTMP4, rMASK
++	srd	rTMP5, rTMP5, rMASK
++	or	rTMP2, rTMP4, rTMP5	/* OR results to speed things up.  */
++	cmpdi	cr7, rTMP2, 0		/* If rTMP2==0,no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done)
++	b	L(loop)
++L(doubleword2_check):
++	cmpb	rTMP4, rWORD, rCHR
++	cmpb	rTMP5, rWORD, rTMP1
++	or	rTMP2, rTMP4, rTMP5
++	cmpdi	cr7, rTMP2, 0
++	bne	cr7, L(done)
++	b	L(loop)
++L(no_match):
++	blr
++	/* We are here because strrchr was called with a null byte.  */
++L(null_match):
++	/* rTMP1 has a word of null bytes.  */
++	cmpb	rTMP2, rWORD, rTMP1	/* Compare each byte against null
++					   bytes.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	sld	rTMP2, rTMP2, rMASK
++	srd	rTMP2, rTMP2, rMASK
++	cmpdi	cr7, rTMP2, 0		/* If rTMP4 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done_null)
++	/* Handle WORD2 of pair.  */
++	ldu	rWORD, 8(rSTR)
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpdi	cr7, rTMP2, 0
++	bne	cr7, L(done_null)
++	b	L(loop_null)		/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(null_LTdoubleword2):
++	/* rTMP1 has a word of null bytes.  */
++	cmpb	rTMP2, rWORD, rTMP1	/* Compare each byte against null
++					   bytes.  */
++	/* Move the words left and right to discard the bits that are not
++	   part of the string and to bring them back as zeros.  */
++	sld	rTMP2, rTMP2, rMASK
++	srd	rTMP2, rTMP2, rMASK
++	cmpdi	cr7, rTMP2, 0		/* If rTMP4 == 0, no c or null bytes
++					   have been found.  */
++	bne	cr7, L(done_null)
++	b	L(loop_null)
++L(null_doubleword2):
++	/* Handle WORD2 of pair.  */
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpdi	cr7, rTMP2, 0
++	bne	cr7, L(done_null)
++	b	L(loop_null)		/* We branch here (rather than falling
++					   through) to skip the nops due to
++					   heavy alignment of loop below.  */
++L(qwalignnull):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for bigger
++	   strings.  */
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpb	rTMP4, rWORD2, rTMP1
++	or	rMASK, rTMP2, rTMP4
++	cmpdi	cr7, rMASK, 0
++	beq	cr7, L(loop_null)
++	/* OK, one (or both) of the words contains a null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a null byte.  */
++	cmpdi	cr6, rTMP2, 0
++	addi	rSTR, rSTR, -8
++	bne	cr6, L(done_null)
++	/* The null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP2, rTMP4
++	addi	rSTR, rSTR, 8
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++	b	L(done_null)
++L(loop_null):
++	/* Load two words, compare and merge in a single register for speed.
++	   This is an attempt to speed up the null-checking process for bigger
++	   strings.  */
++	ld	rWORD, 8(rSTR)
++	ldu	rTMP5, 16(rSTR)
++	cmpb	rTMP2, rWORD, rTMP1
++	cmpb	rTMP4, rTMP5, rTMP1
++	or	rMASK, rTMP2, rTMP4
++	cmpdi	cr7, rMASK, 0
++	beq	cr7, L(loop_null)
++	/* OK, one (or both) of the words contains a null byte.  Check the
++	   first word and decrement the address in case the first word really
++	   contains a null byte.  */
++	cmpdi	cr6, rTMP2, 0
++	addi	rSTR, rSTR, -8
++	bne	cr6, L(done_null)
++	/* The null byte must be in the second word.  Adjust the address
++	   again and move the result of cmpb to rTMP4 so we can calculate the
++	   pointer.  */
++	mr	rTMP2, rTMP4
++	addi	rSTR, rSTR, 8
++	/* rTMP2 has the output of the cmpb instruction, that is, it contains
++	   0xff in the same position as the null byte in the original word
++	   from the string.  Use that to calculate the pointer.  */
++L(done_null):
++	cntlzd	rTMP1, rTMP2		/* Count the leading zeros before the
++					   match.  */
++	srdi	rTMP1, rTMP1, 3		/* Convert leading zeros to bytes.  */
++	add	rRTN, rSTR, rTMP1	/* Return address of the matching null
++					   byte.  */
++	blr
++
++END (strrchr)
++
++weak_alias (strrchr, rindex)
++libc_hidden_builtin_def (strrchr)
diff --git a/recipes-core/glibc/glibc-fsl/0018.glibc.testsuite_remove-blocking-test.patch b/recipes-core/glibc/glibc-fsl/0018.glibc.testsuite_remove-blocking-test.patch
new file mode 100755
index 0000000..920274f
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0018.glibc.testsuite_remove-blocking-test.patch
@@ -0,0 +1,258 @@
+# Problem Statement:
+  Temporary fix for the eglibc tests to continue running without getting hanged
+
+# Owned By:
+  Ram
+
+# Actions:
+  Remove the 'rt/tst-mqueue3.c' test case, which is blocking the tests to
+  continue, from the eglibc testsuite
+
+
+diff -Naur libc/rt/tst-mqueue3.c libc_eglibc_tests/rt/tst-mqueue3.c
+--- libc/rt/tst-mqueue3.c	2014-06-11 02:44:11.000000000 -0500
++++ libc_eglibc_tests/rt/tst-mqueue3.c	1969-12-31 18:00:00.000000000 -0600
+@@ -1,243 +0,0 @@
+-/* Test SIGEV_THREAD handling for POSIX message queues.
+-   Copyright (C) 2004-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-#include <errno.h>
+-#include <mqueue.h>
+-#include <signal.h>
+-#include <stddef.h>
+-#include <stdint.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <sys/mman.h>
+-#include <sys/wait.h>
+-#include <unistd.h>
+-
+-#if _POSIX_THREADS
+-# include <pthread.h>
+-
+-static pid_t pid;
+-static mqd_t m;
+-static const char message[] = "hello";
+-
+-# define MAXMSG 10
+-# define MSGSIZE 10
+-# define UNIQUE 42
+-
+-
+-static void
+-fct (union sigval s)
+-{
+-  /* Put the mq in non-blocking mode.  */
+-  struct mq_attr attr;
+-  if (mq_getattr (m, &attr) != 0)
+-    {
+-      printf ("%s: mq_getattr failed: %m\n", __FUNCTION__);
+-      exit (1);
+-    }
+-  attr.mq_flags |= O_NONBLOCK;
+-  if (mq_setattr (m, &attr, NULL) != 0)
+-    {
+-      printf ("%s: mq_setattr failed: %m\n", __FUNCTION__);
+-      exit (1);
+-    }
+-
+-  /* Check the values.  */
+-  if (attr.mq_maxmsg != MAXMSG)
+-    {
+-      printf ("%s: mq_maxmsg wrong: is %ld, expecte %d\n",
+-	      __FUNCTION__, attr.mq_maxmsg, MAXMSG);
+-      exit (1);
+-    }
+-  if (attr.mq_msgsize != MAXMSG)
+-    {
+-      printf ("%s: mq_msgsize wrong: is %ld, expecte %d\n",
+-	      __FUNCTION__, attr.mq_msgsize, MSGSIZE);
+-      exit (1);
+-    }
+-
+-  /* Read the message.  */
+-  char buf[attr.mq_msgsize];
+-  ssize_t n = TEMP_FAILURE_RETRY (mq_receive (m, buf, attr.mq_msgsize, NULL));
+-  if (n != sizeof (message))
+-    {
+-      printf ("%s: length of message wrong: is %zd, expected %zu\n",
+-	      __FUNCTION__, n, sizeof (message));
+-      exit (1);
+-    }
+-  if (memcmp (buf, message, sizeof (message)) != 0)
+-    {
+-      printf ("%s: message wrong: is \"%s\", expected \"%s\"\n",
+-	      __FUNCTION__, buf, message);
+-      exit (1);
+-    }
+-
+-  exit (UNIQUE);
+-}
+-
+-
+-int
+-do_test (void)
+-{
+-  char tmpfname[] = "/tmp/tst-mqueue3-barrier.XXXXXX";
+-  int fd = mkstemp (tmpfname);
+-  if (fd == -1)
+-    {
+-      printf ("cannot open temporary file: %m\n");
+-      return 1;
+-    }
+-
+-  /* Make sure it is always removed.  */
+-  unlink (tmpfname);
+-
+-  /* Create one page of data.  */
+-  size_t ps = sysconf (_SC_PAGESIZE);
+-  char data[ps];
+-  memset (data, '\0', ps);
+-
+-  /* Write the data to the file.  */
+-  if (write (fd, data, ps) != (ssize_t) ps)
+-    {
+-      puts ("short write");
+-      return 1;
+-    }
+-
+-  void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+-  if (mem == MAP_FAILED)
+-    {
+-      printf ("mmap failed: %m\n");
+-      return 1;
+-    }
+-
+-  pthread_barrier_t *b;
+-  b = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t))
+-                             & ~(__alignof (pthread_barrier_t) - 1));
+-
+-  pthread_barrierattr_t a;
+-  if (pthread_barrierattr_init (&a) != 0)
+-    {
+-      puts ("barrierattr_init failed");
+-      return 1;
+-    }
+-
+-  if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
+-    {
+-      puts ("barrierattr_setpshared failed, could not test");
+-      return 0;
+-    }
+-
+-  if (pthread_barrier_init (b, &a, 2) != 0)
+-    {
+-      puts ("barrier_init failed");
+-      return 1;
+-    }
+-
+-  if (pthread_barrierattr_destroy (&a) != 0)
+-    {
+-      puts ("barrierattr_destroy failed");
+-      return 1;
+-    }
+-
+-  /* Name for the message queue.  */
+-  char mqname[sizeof ("/tst-mqueue3-") + 3 * sizeof (pid_t)];
+-  snprintf (mqname, sizeof (mqname) - 1, "/tst-mqueue3-%ld",
+-	    (long int) getpid ());
+-
+-  /* Create the message queue.  */
+-  struct mq_attr attr = { .mq_maxmsg = MAXMSG, .mq_msgsize = MSGSIZE };
+-  m = mq_open (mqname, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
+-  if (m == -1)
+-    {
+-      if (errno == ENOSYS)
+-	{
+-	  puts ("not implemented");
+-	  return 0;
+-	}
+-
+-      puts ("mq_open failed");
+-      return 1;
+-    }
+-
+-  /* Unlink the message queue right away.  */
+-  if (mq_unlink (mqname) != 0)
+-    {
+-      puts ("mq_unlink failed");
+-      return 1;
+-    }
+-
+-  pid = fork ();
+-  if (pid == -1)
+-    {
+-      puts ("fork failed");
+-      return 1;
+-    }
+-  if (pid == 0)
+-    {
+-      /* Request notification via thread.  */
+-      struct sigevent ev;
+-      ev.sigev_notify = SIGEV_THREAD;
+-      ev.sigev_notify_function = fct;
+-      ev.sigev_value.sival_ptr = NULL;
+-      ev.sigev_notify_attributes = NULL;
+-
+-      /* Tell the kernel.  */
+-      if (mq_notify (m,&ev) != 0)
+-	{
+-	  puts ("mq_notify failed");
+-	  exit (1);
+-	}
+-
+-      /* Tell the parent we are ready.  */
+-      (void) pthread_barrier_wait (b);
+-
+-      /* Make sure the process goes away eventually.  */
+-      alarm (10);
+-
+-      /* Do nothing forever.  */
+-      while (1)
+-	pause ();
+-    }
+-
+-  /* Wait for the child process to register to notification method.  */
+-  (void) pthread_barrier_wait (b);
+-
+-  /* Send the message.  */
+-  if (mq_send (m, message, sizeof (message), 1) != 0)
+-    {
+-      kill (pid, SIGKILL);
+-      puts ("mq_send failed");
+-      return 1;
+-    }
+-
+-  int r;
+-  if (TEMP_FAILURE_RETRY (waitpid (pid, &r, 0)) != pid)
+-    {
+-      kill (pid, SIGKILL);
+-      puts ("waitpid failed");
+-      return 1;
+-    }
+-
+-  return WIFEXITED (r) && WEXITSTATUS (r) == UNIQUE ? 0 : 1;
+-}
+-# define TEST_FUNCTION do_test ()
+-#else
+-# define TEST_FUNCTION 0
+-#endif
+-
+-#include "../test-skeleton.c"
diff --git a/recipes-core/glibc/glibc-fsl/0019.glibc.readv_proto.patch b/recipes-core/glibc/glibc-fsl/0019.glibc.readv_proto.patch
new file mode 100755
index 0000000..df9da4e
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0019.glibc.readv_proto.patch
@@ -0,0 +1,61 @@
+glibc.readv_proto
+
+Unfortunate choice of variable names. Causes syntax errors on Altivec
+enabled targets.
+
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/readv.c glibc-2.20-patch/sysdeps/unix/sysv/linux/readv.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/readv.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/readv.c	2015-02-12 10:56:11.773738962 -0600
+@@ -27,20 +27,20 @@
+ /* Consider moving to syscalls.list.  */
+ 
+ ssize_t
+-__libc_readv (fd, vector, count)
++__libc_readv (fd, vec_tor, count)
+      int fd;
+-     const struct iovec *vector;
++     const struct iovec *vec_tor;
+      int count;
+ {
+   ssize_t result;
+ 
+   if (SINGLE_THREAD_P)
+-    result = INLINE_SYSCALL (readv, 3, fd, vector, count);
++    result = INLINE_SYSCALL (readv, 3, fd, vec_tor, count);
+   else
+     {
+       int oldtype = LIBC_CANCEL_ASYNC ();
+ 
+-      result = INLINE_SYSCALL (readv, 3, fd, vector, count);
++      result = INLINE_SYSCALL (readv, 3, fd, vec_tor, count);
+ 
+       LIBC_CANCEL_RESET (oldtype);
+     }
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/writev.c glibc-2.20-patch/sysdeps/unix/sysv/linux/writev.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/writev.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/writev.c	2015-02-12 10:56:11.774738974 -0600
+@@ -28,20 +28,20 @@
+ /* Consider moving to syscalls.list.  */
+ 
+ ssize_t
+-__libc_writev (fd, vector, count)
++__libc_writev (fd, vec_tor, count)
+      int fd;
+-     const struct iovec *vector;
++     const struct iovec *vec_tor;
+      int count;
+ {
+   ssize_t result;
+ 
+   if (SINGLE_THREAD_P)
+-    result = INLINE_SYSCALL (writev, 3, fd, vector, count);
++    result = INLINE_SYSCALL (writev, 3, fd, vec_tor, count);
+   else
+     {
+       int oldtype = LIBC_CANCEL_ASYNC ();
+ 
+-      result = INLINE_SYSCALL (writev, 3, fd, vector, count);
++      result = INLINE_SYSCALL (writev, 3, fd, vec_tor, count);
+ 
+       LIBC_CANCEL_RESET (oldtype);
+     }
diff --git a/recipes-core/glibc/glibc-fsl/0020.glibc.fsl-largemcpy-e500mc-e5500-e6500.patch b/recipes-core/glibc/glibc-fsl/0020.glibc.fsl-largemcpy-e500mc-e5500-e6500.patch
new file mode 100755
index 0000000..b0097f7
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0020.glibc.fsl-largemcpy-e500mc-e5500-e6500.patch
@@ -0,0 +1,932 @@
+diff -ruN glibc-2.20-mcpy-new-large-original/include/string.h glibc-2.20-mcpy-new-large-mcpy-new/include/string.h
+--- glibc-2.20-mcpy-new-large-original/include/string.h	2015-09-02 14:28:58.404187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/include/string.h	2015-09-02 14:30:49.773187000 -0500
+@@ -70,6 +70,9 @@
+     }))
+ #endif
+ 
++#if defined (__powerpc__)
++libc_hidden_proto (largememcpy)
++#endif
+ libc_hidden_proto (__mempcpy)
+ libc_hidden_proto (__stpcpy)
+ libc_hidden_proto (__stpncpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/string/string.h glibc-2.20-mcpy-new-large-mcpy-new/string/string.h
+--- glibc-2.20-mcpy-new-large-original/string/string.h	2015-09-02 14:28:58.383187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/string/string.h	2015-09-02 14:30:49.752187000 -0500
+@@ -45,6 +45,10 @@
+ /* Copy N bytes of SRC to DEST.  */
+ extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
+ 		     size_t __n) __THROW __nonnull ((1, 2));
++#if defined (__powerpc__)
++extern void *largememcpy (void *__restrict __dest, const void *__restrict __src,
++		     size_t __n) __THROW __nonnull ((1, 2));
++#endif
+ /* Copy N bytes of SRC to DEST, guaranteeing
+    correct behavior for overlapping strings.  */
+ extern void *memmove (void *__dest, const void *__src, size_t __n)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/memcpy.c glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/memcpy.c
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/memcpy.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/memcpy.c	2015-09-02 14:30:49.590187000 -0500
+@@ -0,0 +1,4 @@
++#include <string/memcpy.c>
++
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/405/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/405/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/405/memcpy.S	2015-09-02 14:28:58.206187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/405/memcpy.S	2015-09-02 14:30:49.554187000 -0500
+@@ -128,3 +128,5 @@
+        blr
+ END (memcpy)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy,largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/a2/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/a2/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/a2/memcpy.S	2015-09-02 14:28:58.194187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/a2/memcpy.S	2015-09-02 14:30:49.541187000 -0500
+@@ -525,3 +525,5 @@
+ 
+ END (memcpy)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/cell/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/cell/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/cell/memcpy.S	2015-09-02 14:28:58.213187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/cell/memcpy.S	2015-09-02 14:30:49.561187000 -0500
+@@ -240,3 +240,5 @@
+ 
+ END (memcpy)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e500/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e500/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e500/memcpy.S	2015-09-02 14:29:07.888186901 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e500/memcpy.S	2015-09-02 14:30:49.539187000 -0500
+@@ -406,3 +406,8 @@
+ 
+ END (FUNCTION)
+ libc_hidden_builtin_def (FUNCTION)
++
++#ifndef __MEMMOVE__
++weak_alias (memcpy,largememcpy)
++libc_hidden_def (largememcpy)
++#endif
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e500mc/largememcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e500mc/largememcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e500mc/largememcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e500mc/largememcpy.S	2015-09-02 14:54:00.062186965 -0500
+@@ -0,0 +1,499 @@
++/* Optimized largememcpy implementation for e500mc 32-bit PowerPC.
++   This version uses cache management instructions.
++
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3]
++   largememcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
++   Returns 'dst'.
++
++	 r3 = destination
++	 r4 = source
++	 r5 = byte count
++
++	 volatile fixed point registers usable:
++	 r0, r3-r12
++
++	 volatile floating point registers usable:
++	 f0-f13.  */
++
++EALIGN (largememcpy, 5, 0)
++	cmplw	cr0, r4, r3		/* if source==destination, return.  */
++	beqlr	cr0
++	/* if number of bytes is less than 8 (optimal value TBD),
++	   but greater than zero, copy byte-by-byte.  */
++	cmplwi	r5, 8
++	mr	r6, r3
++	blt	L(copy_bytes)
++	neg	r0, r4
++	andi.	r11, r0, 3
++	beq	L(src_aligned4)
++        /* We have to align the src pointer by r11 bytes */
++	cmplwi  cr0, r11, 1
++	ble     L(src_1)
++	/* 2 or 3 bytes */
++	addi    r8, r11, -2
++	lhz     r9, 0(r4)
++	lhzx    r12, r4, r8
++	sth     r9, 0(r6)
++	sthx    r12, r6, r8
++	b       L(src_0)
++L(src_1):
++	lbz     r8, 0(r4)
++	stb     r8, 0(r6)
++L(src_0):
++	subf	r5, r11, r5
++	add	r4, r4, r11
++	add	r6, r6, r11
++L(src_aligned4):
++	cmplwi	7, r5, 63
++	ble	7, L(copy_remaining)
++	andi.	r10, r0, 63
++	beq	L(src_aligned64)
++	subf.	r10, r11, r10
++	beq	0, L(src_aligned64)
++	srwi	r11, r10, 2
++	subf	r5, r10, r5
++	mtctr	r11
++L(copy_salign4):
++	lwz	0, 0(r4)
++	addi	r4, r4, 4
++	stw	0, 0(r6)
++	addi	r6, r6, 4
++	bdnz	L(copy_salign4)
++L(src_aligned64):
++	srwi.	r11, r5, 6		/* No of 64 byte copy count.  */
++	beq	0, L(copy_remaining)
++	rlwinm	r5, r5, 0, 26, 31	/* remaining bytes.  */
++	rlwinm.	r0, r6, 0, 29, 31
++	bne	0, L(src_dnalign)
++	cmplwi	7, r11, 256
++	ble	7, L(label1)
++	addi	r7, r11, -256
++	mtctr	r7
++#ifdef SHARED
++	mflr	r0
++	/* Establishes GOT addressability so we can load __cache_line_size from
++	   static.  This value was set from the aux vector during startup.  */
++	SETUP_GOT_ACCESS(r9,got_label_1)
++	addis	r9, r9, __cache_line_size-got_label_1@ha
++	lwz	r9, __cache_line_size-got_label_1@l(r9)
++	mtlr	r0
++#else
++	/* Load __cache_line_size from static.  This value was set from the
++	   aux vector during startup.  */
++	lis	r9, __cache_line_size@ha
++	lwz	r9, __cache_line_size@l(r9)
++#endif
++	cmplwi	5, r9, 64
++	li	r10, 256
++	li	r12, 64
++	bne	5, L(lcopy_dalign_nc)
++L(lcopy_dalign):
++	dcbt	r10, r4
++	dcbzl	r12, r6
++#ifndef _SOFT_FLOAT
++	lfd	0, 0(r4)
++	lfd	1, 8(r4)
++	lfd	2, 16(r4)
++	lfd	3, 24(r4)
++	lfd	4, 32(r4)
++	lfd	5, 40(r4)
++	lfd	6, 48(r4)
++	lfd	7, 56(r4)
++	stfd	0, 0(r6)
++	stfd	1, 8(r6)
++	stfd	2, 16(r6)
++	stfd	3, 24(r6)
++	addi	r4, r4, 64
++	stfd	4, 32(r6)
++	stfd	5, 40(r6)
++	stfd	6, 48(r6)
++	stfd	7, 56(r6)
++#else
++	lwz	r0, 0(r4)
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++#endif
++	dcbf	0, r6
++	addi	r6, r6, 64
++	bdnz	L(lcopy_dalign)
++	subf	r11, r7, r11
++L(label1):
++	mtctr	r11
++L(copy_dalign):
++#ifndef _SOFT_FLOAT
++	lfd	0, 0(r4)
++	lfd	1, 8(r4)
++	lfd	2, 16(r4)
++	lfd	3, 24(r4)
++	stfd	0, 0(r6)
++	stfd	1, 8(r6)
++	stfd	2, 16(r6)
++	stfd	3, 24(r6)
++	lfd	0, 32(r4)
++	lfd	1, 40(r4)
++	lfd	2, 48(r4)
++	lfd	3, 56(r4)
++	addi	r4, r4, 64
++	stfd	0, 32(r6)
++	stfd	1, 40(r6)
++	stfd	2, 48(r6)
++	stfd	3, 56(r6)
++#else
++	lwz	r0, 0(r4)
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++#endif
++	addi	r6, r6, 64
++	bdnz	L(copy_dalign)
++L(copy_remaining):
++	srwi.	r11, r5, 3		/* No of 8 byte copy count.  */
++	rlwinm	r5, r5, 0, 29, 31	/* remaining bytes.  */
++	beq	0, L(copy_bytes)
++	mtcrf	0x01, r11
++	bf	cr7*4+1, L(cp16b)
++	lwz	r0, 0(r4)		/* copy 32 bytes.  */
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	addi	r4, r4, 32
++	stw	r9, 20(r6)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	addi	r6, r6, 32
++L(cp16b):
++	bf	cr7*4+2, L(cp8b)
++	lwz	r0, 0(r4)		/* copy 16 bytes.  */
++	lwz	r7, 4(r4)
++	lwz	r8, 8(r4)
++	lwz	r9, 12(r4)
++	addi	r4, r4, 16
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	stw	r8, 8(r6)
++	stw	r9, 12(r6)
++	addi	r6, r6, 16
++L(cp8b):
++	bf	cr7*4+3, L(copy_bytes)
++	lwz	r0, 0(r4)		/* copy 8 bytes.  */
++	lwz	r7, 4(r4)
++	addi	r4, r4, 8
++	stw	r0, 0(r6)
++	stw	r7, 4(r6)
++	addi	r6, r6, 8
++L(copy_bytes):
++	cmplwi	cr1, r5, 4
++	cmplwi	cr0, r5, 1
++	bgt	cr1, L(gt4b)		/* nb > 4?  (5, 6, 7 bytes).  */
++	ble	cr0, L(lt1b)		/* nb <= 1? (0, 1 bytes).  */
++	addi	r0, r5, -2		/* 2, 3, 4 bytes.  */
++	lhz	r9, 0(r4)
++	lhzx	r11, r4, r0
++	sth	r9, 0(r6)
++	sthx	r11, r6, r0
++	blr
++L(gt4b):
++	addi	r0, r5, -4		/* 5, 6, 7 bytes.  */
++	lwz	r9, 0(r4)
++	lwzx	r11, r4, r0
++	stw	r9, 0(r6)
++	stwx	r11, r6, r0
++	blr
++L(lt1b):
++	mtocrf	0x1, r5			/* nb == 0 ? return.  */
++	bflr	31
++	lbz	r0, 0(r4)		/* nb == 1.  */
++	stb	r0, 0(r6)
++	blr
++
++L(src_dnalign):
++	cmplwi	7, r11, 256
++	ble	7, L(label2)
++	addi	r7, r11, -256
++	mtctr	r7
++#ifdef SHARED
++	mflr	r0
++	/* Establishes GOT addressability so we can load __cache_line_size from
++	   static.  This value was set from the aux vector during startup.  */
++	SETUP_GOT_ACCESS(r9,got_label_2)
++	addis	r9, r9, __cache_line_size-got_label_2@ha
++	lwz	r9, __cache_line_size-got_label_2@l(r9)
++	mtlr	r0
++#else
++	/* Load __cache_line_size from static.  This value was set from the
++	   aux vector during startup.  */
++	lis	r9, __cache_line_size@ha
++	lwz	r9, __cache_line_size@l(r9)
++#endif
++	cmplwi	5, r9, 64
++	li	r10, 256
++	li	r12, 64
++	bne	5, L(lcopy_dnalign_nc)
++L(lcopy_dnalign):
++	dcbt	r10, r4
++	dcbzl	r12, r6
++	lwz	r0, 0(r4)		/* copy 64 bytes.  */
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++	dcbf	0, r6
++	addi	r6, r6, 64
++	bdnz	L(lcopy_dnalign)
++	li	r11, 256
++L(label2):
++	mtctr	r11
++L(copy_dnalign):
++	lwz	r0, 0(r4)		/* copy 64 bytes.  */
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_dnalign)
++	b	L(copy_remaining)
++
++L(lcopy_dalign_nc):
++#ifndef _SOFT_FLOAT
++	lfd	0, 0(r4)		/* copy 64 bytes.  */
++	lfd	1, 8(r4)
++	lfd	2, 16(r4)
++	lfd	3, 24(r4)
++	lfd	4, 32(r4)
++	lfd	5, 40(r4)
++	lfd	6, 48(r4)
++	lfd	7, 56(r4)
++	stfd	0, 0(r6)
++	stfd	1, 8(r6)
++	stfd	2, 16(r6)
++	stfd	3, 24(r6)
++	addi	r4, r4, 64
++	stfd	4, 32(r6)
++	stfd	5, 40(r6)
++	stfd	6, 48(r6)
++	stfd	7, 56(r6)
++#else
++	lwz	r0, 0(r4)		/* copy 64 bytes.  */
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++#endif
++	addi	r6, r6, 64
++	bdnz	L(lcopy_dalign_nc)
++	subf	r11, r7, r11
++	b	L(label1)
++
++L(lcopy_dnalign_nc):
++	lwz	r0, 0(r4)		/* copy 64 bytes.  */
++	lwz	r8, 4(r4)
++	lwz	r9, 8(r4)
++	stw	r0, 0(r6)
++	stw	r8, 4(r6)
++	stw	r9, 8(r6)
++	lwz	r0, 12(r4)
++	lwz	r8, 16(r4)
++	lwz	r9, 20(r4)
++	stw	r0, 12(r6)
++	stw	r8, 16(r6)
++	stw	r9, 20(r6)
++	lwz	r0, 24(r4)
++	lwz	r8, 28(r4)
++	lwz	r9, 32(r4)
++	stw	r0, 24(r6)
++	stw	r8, 28(r6)
++	stw	r9, 32(r6)
++	lwz	r0, 36(r4)
++	lwz	r8, 40(r4)
++	lwz	r9, 44(r4)
++	stw	r0, 36(r6)
++	stw	r8, 40(r6)
++	stw	r9, 44(r6)
++	lwz	r0, 48(r4)
++	lwz	r8, 52(r4)
++	lwz	r9, 56(r4)
++	stw	r0, 48(r6)
++	lwz	r0, 60(r4)
++	addi	r4, r4, 64
++	stw	r8, 52(r6)
++	stw	r9, 56(r6)
++	stw	r0, 60(r6)
++	addi	r6, r6, 64
++	bdnz	L(lcopy_dnalign_nc)
++	li	r11, 256
++	b	L(label2)
++
++END (largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e500mc/Makefile glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e500mc/Makefile
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e500mc/Makefile	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e500mc/Makefile	2015-09-02 14:30:49.552187000 -0500
+@@ -0,0 +1,5 @@
++#Makefile fragment for PowerPC e500mc core
++
++ifeq ($(subdir),string)
++sysdep_routines += largememcpy
++endif
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e5500/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e5500/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e5500/memcpy.S	2015-09-02 14:28:58.208187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e5500/memcpy.S	2015-09-02 14:30:49.556187000 -0500
+@@ -249,4 +249,6 @@
+ 	b	L(copy_remaining)
+ 
+ END (memcpy)
++weak_alias (memcpy, largememcpy)
+ libc_hidden_builtin_def (memcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e6500/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e6500/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/e6500/memcpy.S	2015-09-02 14:28:58.214187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/e6500/memcpy.S	2015-09-02 14:30:49.562187000 -0500
+@@ -237,3 +237,5 @@
+ 
+ END (memcpy)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy,largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/power4/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/power4/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/power4/memcpy.S	2015-09-02 14:28:58.194187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/power4/memcpy.S	2015-09-02 14:30:49.541187000 -0500
+@@ -479,3 +479,5 @@
+ END (memcpy)
+ 
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/power6/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/power6/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/power6/memcpy.S	2015-09-02 14:28:58.211187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/power6/memcpy.S	2015-09-02 14:30:49.559187000 -0500
+@@ -905,3 +905,5 @@
+ END (memcpy)
+ 
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/power7/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/power7/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc32/power7/memcpy.S	2015-09-02 14:28:58.207187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc32/power7/memcpy.S	2015-09-02 14:30:49.555187000 -0500
+@@ -536,3 +536,5 @@
+ 
+ END (memcpy)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/a2/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/a2/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/a2/memcpy.S	2015-09-02 14:28:58.219187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/a2/memcpy.S	2015-09-02 14:30:49.567187000 -0500
+@@ -522,3 +522,5 @@
+ 
+ END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/cell/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/cell/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/cell/memcpy.S	2015-09-02 14:28:58.239187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/cell/memcpy.S	2015-09-02 14:30:49.588187000 -0500
+@@ -240,3 +240,5 @@
+ 
+ END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy, largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/e5500/largememcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/e5500/largememcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/e5500/largememcpy.S	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/e5500/largememcpy.S	2015-09-02 14:56:08.056186467 -0500
+@@ -0,0 +1,221 @@
++/* Optimized largememcpy implementation for e5500 64-bit PowerPC64.
++   This version uses cache management instructions.
++
++   Copyright (C) 2015 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <sysdep.h>
++
++/* __ptr_t [r3] largememcpy __ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]
++   Returns 'dst'.
++
++	 r3 = destination
++	 r4 = source
++	 r5 = byte count
++
++	 volatile fixed point registers usable:
++	 r0, r3-r12
++
++	 volatile floating point registers usable:
++	 f0-f13.  */
++
++	.section ".toc", "aw"
++.LC0:
++	.tc __cache_line_size[TC], __cache_line_size
++	.section ".text"
++	.align 2
++
++EALIGN (largememcpy, 5, 0)
++	CALL_MCOUNT 3
++	cmpld	cr0, r4, r3		/* if source==destination, return.  */
++	beqlr	cr0
++	/* if number of bytes is less than 8, (optimal value TBD),
++	   but greater than zero copy byte-by-byte.  */
++	cmpldi	r5, 8
++	mr	r6, r3
++	blt	L(copy_bytes)
++	neg	r0, r4
++	andi.	r11, r0, 7
++	beq	L(src_aligned)
++	/* We have to align the src pointer by r11 bytes */
++	cmplwi	cr1, r11, 4
++	cmplwi	cr0, r11, 1
++	bgt	cr1, L(src_567)
++	ble	cr0, L(src_1)
++	/* 2, 3 or 4 bytes */
++	addi	r0, r11, -2
++	lhz	r9, 0(r4)
++	lhzx	r12, r4, r0
++	sth	r9, 0(r6)
++	sthx	r12, r6, r0
++	b	L(src_0)
++L(src_567):
++	addi	r0, r11, -4
++	lwz	r9, 0(r4)
++	lwzx	r12, r4, r0
++	stw	r9, 0(r6)
++	stwx	r12, r6, r0
++	b	L(src_0)
++L(src_1):
++	lbz	r0, 0(r4)
++	stb	r0, 0(r6)
++L(src_0):
++	subf	r5, r11, r5
++	add	r4, r4, r11
++	add	r6, r6, r11
++L(src_aligned):
++	cmpldi	7, r5, 63
++	ble	7, L(copy_remaining)
++	srwi	r11, r5, 6		/* No of 64 byte copy count.  */
++	rlwinm.	r5, r5, 0, 26, 31	/* remaining bytes.  */
++	cmpldi	7, r11, 256
++	ble	7, L(2)
++	rlwinm.	r0, r6, 0, 28, 31
++	cmpldi	r0, 8
++	addi	r7, r11, -256
++	mtctr	r7
++	ble	L(copy_dnaligned)
++	ld	r9, .LC0@toc(r2)	/* get cache line size.  */
++	lwz	r9, 0(r9)
++	cmpldi	5, r9, 64
++	li	r10, 256
++	li	r12, 64
++	bne	5, L(copy_dnaligned)
++L(lcopy_daligned):
++	dcbt	r10, r4
++	dcbzl	r12, r6
++	ld	r0, 0(r4)		/* 64-byte copy.  */
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	ld	r0, 32(r4)
++	ld	r7, 40(r4)
++	ld	r8, 48(r4)
++	ld	r9, 56(r4)
++	addi	r4, r4, 64
++	std	r0, 32(r6)
++	std	r7, 40(r6)
++	std	r8, 48(r6)
++	std	r9, 56(r6)
++	dcbf	0, r6
++	addi	r6, r6, 64
++	bdnz	L(lcopy_daligned)
++L(1):	li	r11, 256
++L(2):	mtctr	r11
++L(copy_daligned):
++	ld	r0, 0(r4)
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	ld	r0, 32(r4)
++	ld	r7, 40(r4)
++	ld	r8, 48(r4)
++	ld	r9, 56(r4)
++	addi	r4, r4, 64
++	std	r0, 32(r6)
++	std	r7, 40(r6)
++	std	r8, 48(r6)
++	std	r9, 56(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_daligned)
++L(copy_remaining):
++	srwi.	r11, r5, 3		/* No of 8 byte copy count.  */
++	rlwinm	r5, r5, 0, 29, 31	/* remaining bytes.  */
++	beq	0, L(copy_bytes)
++	mtcrf	0x01, r11
++	bf	cr7*4+1, L(cp16b)
++	ld	r0, 0(r4)		/* copy 32 bytes.  */
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	addi	r4, r4, 32
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	addi	r6, r6, 32
++L(cp16b):
++	bf	cr7*4+2, L(cp8b)	/* copy 16 bytes.  */
++	ld	r7, 0(r4)
++	ld	r8, 8(r4)
++	addi	r4, r4, 16
++	std	r7, 0(r6)
++	std	r8, 8(r6)
++	addi	r6, r6, 16
++L(cp8b):
++	bf	cr7*4+3, L(copy_bytes)	/* copy 8 bytes.  */
++	ld	r7, 0(r4)
++	addi	r4, r4, 8
++	std	r7, 0(r6)
++	addi	r6, r6, 8
++L(copy_bytes):
++	cmpldi	cr1, r5, 4
++	cmpldi	cr0, r5, 1
++	bgt	cr1, L(gt4b)		/* nb > 4?  (5, 6, 7 bytes).  */
++	ble	cr0, L(lt1b)		/* nb <= 1? (0, 1 bytes).  */
++	addi	r0, r5, -2		/* 2, 3, 4 bytes.  */
++	lhz	r9, 0(r4)
++	lhzx	r11, r4, r0
++	sth	r9, 0(r6)
++	sthx	r11, r6, r0
++	blr
++L(gt4b):
++	addi	r0, r5, -4		/* 5, 6, 7 bytes.  */
++	lwz	r9, 0(r4)
++	lwzx	r11, r4, r0
++	stw	r9, 0(r6)
++	stwx	r11, r6, r0
++	blr
++L(lt1b):
++	mtocrf	0x1, r5			/* nb == 0 ? return.  */
++	bflr	31
++	lbz	r0, 0(r4)		/* nb == 1.  */
++	stb	r0, 0(r6)
++	blr
++L(copy_dnaligned):
++	ld	r0, 0(r4)
++	ld	r7, 8(r4)
++	ld	r8, 16(r4)
++	ld	r9, 24(r4)
++	std	r0, 0(r6)
++	std	r7, 8(r6)
++	std	r8, 16(r6)
++	std	r9, 24(r6)
++	ld	r0, 32(r4)
++	ld	r7, 40(r4)
++	ld	r8, 48(r4)
++	ld	r9, 56(r4)
++	addi	r4, r4, 64
++	std	r0, 32(r6)
++	std	r7, 40(r6)
++	std	r8, 48(r6)
++	std	r9, 56(r6)
++	addi	r6, r6, 64
++	bdnz	L(copy_dnaligned)
++	b	L(1)
++
++END_GEN_TB (largememcpy,TB_TOCLESS)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/e5500/Makefile glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/e5500/Makefile
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/e5500/Makefile	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/e5500/Makefile	2015-09-02 14:30:49.572187000 -0500
+@@ -0,0 +1,5 @@
++#Makefile fragment for PowerPC e5500 64-bit core
++
++ifeq ($(subdir),string)
++sysdep_routines += largememcpy
++endif
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/e6500/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/e6500/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/e6500/memcpy.S	2015-09-02 14:28:58.240187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/e6500/memcpy.S	2015-09-02 14:30:49.589187000 -0500
+@@ -210,4 +210,6 @@
+ 	b	L(copy_remaining)
+ 
+ END_GEN_TB (memcpy,TB_TOCLESS)
++weak_alias (memcpy,largememcpy)
+ libc_hidden_builtin_def (memcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/power4/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/power4/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/power4/memcpy.S	2015-09-02 14:28:58.219187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/power4/memcpy.S	2015-09-02 14:30:49.567187000 -0500
+@@ -472,3 +472,5 @@
+     blr
+ END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy,largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/power6/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/power6/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/power6/memcpy.S	2015-09-02 14:28:58.238187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/power6/memcpy.S	2015-09-02 14:30:49.586187000 -0500
+@@ -1494,3 +1494,5 @@
+     blr
+ END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy,largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/power7/memcpy.S glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/power7/memcpy.S
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/powerpc64/power7/memcpy.S	2015-09-02 14:28:58.222187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/powerpc64/power7/memcpy.S	2015-09-02 14:30:49.570187000 -0500
+@@ -424,3 +424,5 @@
+ 
+ END_GEN_TB (memcpy,TB_TOCLESS)
+ libc_hidden_builtin_def (memcpy)
++weak_alias (memcpy,largememcpy)
++libc_hidden_def (largememcpy)
+diff -ruN glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/Versions glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/Versions
+--- glibc-2.20-mcpy-new-large-original/sysdeps/powerpc/Versions	2015-09-02 14:28:58.244187000 -0500
++++ glibc-2.20-mcpy-new-large-mcpy-new/sysdeps/powerpc/Versions	2015-09-02 14:30:49.593187000 -0500
+@@ -9,6 +9,7 @@
+   GLIBC_2.3.4 {
+     _longjmp; __sigsetjmp; _setjmp;
+     longjmp; setjmp;
++    largememcpy;
+   }
+   GLIBC_PRIVATE {
+     __novmx__libc_longjmp; __novmx__libc_siglongjmp;
diff --git a/recipes-core/glibc/glibc-fsl/0021.glibc.undefined_static.patch b/recipes-core/glibc/glibc-fsl/0021.glibc.undefined_static.patch
new file mode 100755
index 0000000..baad08f
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0021.glibc.undefined_static.patch
@@ -0,0 +1,37 @@
+glibc.undefined_static
+
+This works around an old binutils bug, which would delete static
+constants out of the code, thus causing undefined symbols. Not sure if
+this patch is still needed.
+
+diff -rc libc-orig/stdio-common/psiginfo-define.h libc-new/stdio-common/psiginfo-define.h
+*** libc-orig/stdio-common/psiginfo-define.h	2009-04-09 08:12:53.000000000 -0500
+--- libc-new/stdio-common/psiginfo-define.h	2009-04-09 08:20:36.000000000 -0500
+***************
+*** 1,4 ****
+! static const union C(codestrs_t_, NOW) {
+    struct {
+  #define P(n, s) char MF(__LINE__)[sizeof (s)];
+  #include "psiginfo-data.h"
+--- 1,4 ----
+! const union C(codestrs_t_, NOW) {
+    struct {
+  #define P(n, s) char MF(__LINE__)[sizeof (s)];
+  #include "psiginfo-data.h"
+***************
+*** 8,14 ****
+  #define P(n, s) s,
+  #include "psiginfo-data.h"
+    } };
+! static const uint8_t C(codes_, NOW)[] = {
+  #define P(n, s) [(n) - 1] = offsetof (union C(codestrs_t_, NOW), MF(__LINE__)),
+  #include "psiginfo-data.h"
+  };
+--- 8,14 ----
+  #define P(n, s) s,
+  #include "psiginfo-data.h"
+    } };
+! const uint8_t C(codes_, NOW)[] = {
+  #define P(n, s) [(n) - 1] = offsetof (union C(codestrs_t_, NOW), MF(__LINE__)),
+  #include "psiginfo-data.h"
+  };
diff --git a/recipes-core/glibc/glibc-fsl/0022.glibc.use-option-groups.patch b/recipes-core/glibc/glibc-fsl/0022.glibc.use-option-groups.patch
new file mode 100644
index 0000000..631013b
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/0022.glibc.use-option-groups.patch
@@ -0,0 +1,149 @@
+From d6fe2c92acf68509ee00af1145ba0cfbd714426b Mon Sep 17 00:00:00 2001
+From: Ting Liu <ting.liu@freescale.com>
+Date: Fri, 14 Aug 2015 16:49:16 +0800
+Subject: [PATCH] 0024.glibc.use-option-groups.patch new updates
+
+Signed-off-by: Ting Liu <ting.liu@freescale.com>
+---
+ elf/Makefile                   | 10 +++++++---
+ include/libc-symbols.h         |  3 +--
+ misc/sys/xattr.h               |  2 --
+ sysdeps/ieee754/dbl-64/s_sin.c | 16 ++++++----------
+ 4 files changed, 14 insertions(+), 17 deletions(-)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 25012cc..dd6b330 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -17,6 +17,8 @@
+ 
+ # Makefile for elf subdirectory of GNU C Library.
+ 
++include ../option-groups.mak
++
+ subdir		:= elf
+ 
+ include ../Makeconfig
+@@ -144,10 +146,11 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
+ 	 tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
+ 	 tst-stackguard1 tst-addr1 tst-thrlock \
+-	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
++	 tst-unique1 tst-unique2 \
+ 	 tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
+ 	 tst-ptrguard1
+ #	 reldep9
++tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-unique3 tst-unique4
+ ifeq ($(build-hardcoded-path-in-tests),yes)
+ tests += tst-dlopen-aout
+ endif
+@@ -205,8 +208,6 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		tst-unique1mod1 tst-unique1mod2 \
+ 		tst-unique2mod1 tst-unique2mod2 \
+ 		tst-auditmod9a tst-auditmod9b \
+-		tst-unique3lib tst-unique3lib2 \
+-		tst-unique4lib \
+ 		tst-initordera1 tst-initorderb1 \
+ 		tst-initordera2 tst-initorderb2 \
+ 		tst-initordera3 tst-initordera4 \
+@@ -214,6 +215,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		tst-initorder2d \
+ 		tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
+ 		tst-array5dep tst-null-argv-lib
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++modules-names += tst-unique3lib tst-unique3lib2 tst-unique4lib 
++endif
+ ifeq (yesyes,$(have-fpie)$(build-shared))
+ modules-names += tst-piemod1
+ tests += tst-pie1 tst-pie2
+diff --git a/include/libc-symbols.h b/include/libc-symbols.h
+index d4ab1f3..25662cb 100644
+--- a/include/libc-symbols.h
++++ b/include/libc-symbols.h
+@@ -60,8 +60,7 @@
+ /* Define these macros for the benefit of portable GNU code that wants to check
+    them.  Of course, STDC_HEADERS is never false when building libc!  */
+ #define STDC_HEADERS	1
+-#define HAVE_MBSTATE_T	1
+-#define HAVE_MBSRTOWCS	1
++
+ #define HAVE_LIBINTL_H	1
+ #define HAVE_WCTYPE_H	1
+ #define HAVE_ISWCTYPE	1
+diff --git a/misc/sys/xattr.h b/misc/sys/xattr.h
+index 796df90..929cd87 100644
+--- a/misc/sys/xattr.h
++++ b/misc/sys/xattr.h
+@@ -26,7 +26,6 @@ __BEGIN_DECLS
+ 
+ /* The following constants should be used for the fifth parameter of
+    `*setxattr'.  */
+-#ifndef __USE_KERNEL_XATTR_DEFS
+ enum
+ {
+   XATTR_CREATE = 1,	/* set value, fail if attr already exists.  */
+@@ -34,7 +33,6 @@ enum
+   XATTR_REPLACE = 2	/* set value, fail if attr does not exist.  */
+ #define XATTR_REPLACE	XATTR_REPLACE
+ };
+-#endif
+ 
+ /* Set the attribute NAME of the file pointed to by PATH to VALUE (which
+    is SIZE bytes long).  Return 0 on success, -1 for errors.  */
+diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
+index 50109b8..6105e9f 100644
+--- a/sysdeps/ieee754/dbl-64/s_sin.c
++++ b/sysdeps/ieee754/dbl-64/s_sin.c
+@@ -447,21 +447,19 @@ __sin (double x)
+ 	    }
+ 	  else
+ 	    {
+-	      double t;
+ 	      if (a > 0)
+ 		{
+ 		  m = 1;
+-		  t = a;
+ 		  db = da;
+ 		}
+ 	      else
+ 		{
+ 		  m = 0;
+-		  t = -a;
++		  a = -a;
+ 		  db = -da;
+ 		}
+-	      u.x = big + t;
+-	      y = t - (u.x - big);
++	      u.x = big + a;
++	      y = a - (u.x - big);
+ 	      res = do_sin (u, y, db, &cor);
+ 	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
+ 	      retval = ((res == res + cor) ? ((m) ? res : -res)
+@@ -673,21 +671,19 @@
+ 	    }
+ 	  else
+ 	    {
+-	      double t;
+ 	      if (a > 0)
+ 		{
+ 		  m = 1;
+-		  t = a;
+ 		  db = da;
+ 		}
+ 	      else
+ 		{
+ 		  m = 0;
+-		  t = -a;
++		  a = -a;
+ 		  db = -da;
+ 		}
+-	      u.x = big + t;
+-	      y = t - (u.x - big);
++	      u.x = big + a;
++	      y = a - (u.x - big);
+ 	      res = do_sin (u, y, db, &cor);
+ 	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
+ 	      retval = ((res == res + cor) ? ((m) ? res : -res)
+-- 
+1.9.2
+
diff --git a/recipes-core/glibc/glibc-fsl/00xx.glibc.add-option-groups-support.patch b/recipes-core/glibc/glibc-fsl/00xx.glibc.add-option-groups-support.patch
new file mode 100755
index 0000000..eff2257
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/00xx.glibc.add-option-groups-support.patch
@@ -0,0 +1,1389 @@
+# Problem Statement:
+  Port eglibc option group infrastructure to glibc v2.20.
+
+# Referred from patch by:
+  Yocto Project
+  http://git.yoctoproject.org/cgit.cgi/poky/plain/meta/recipes-core/glibc/glibc/option-groups.patch
+  Upstream-Status: Pending
+
+diff -Naur glibc-2.20/config.make.in glibc-2.20-patch/config.make.in
+--- glibc-2.20/config.make.in	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/config.make.in	2015-02-19 03:54:24.155759769 -0600
+@@ -46,6 +46,8 @@
+ c++-sysincludes = @CXX_SYSINCLUDES@
+ all-warnings = @all_warnings@
+ 
++kconfig_tools = @KCONFIG_TOOLS@
++
+ have-z-combreloc = @libc_cv_z_combreloc@
+ have-z-execstack = @libc_cv_z_execstack@
+ have-Bgroup = @libc_cv_Bgroup@
+diff -Naur glibc-2.20/configure glibc-2.20-patch/configure
+--- glibc-2.20/configure	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/configure	2015-02-19 03:54:24.157759768 -0600
+@@ -619,6 +619,7 @@
+ PERL
+ BASH_SHELL
+ libc_cv_gcc_static_libgcc
++KCONFIG_TOOLS
+ CXX_SYSINCLUDES
+ SYSINCLUDES
+ AUTOCONF
+@@ -733,6 +734,7 @@
+ with_binutils
+ with_selinux
+ with_headers
++with_kconfig
+ with_default_link
+ enable_sanity_checks
+ enable_shared
+@@ -1437,6 +1439,9 @@
+   --with-selinux          if building with SELinux support
+   --with-headers=PATH     location of system headers to use (for example
+                           /usr/src/linux/include) [default=compiler default]
++  --with-kconfig=PATH     location of kconfig tools to use (from Linux kernel
++                          builds) to re-use for configuring EGLIBC option
++                          groups
+   --with-default-link     do not use explicit linker scripts
+   --with-cpu=CPU          select code for CPU variant
+ 
+@@ -3400,6 +3405,14 @@
+ 
+ 
+ 
++# Check whether --with-kconfig was given.
++if test "${with_kconfig+set}" = set; then
++  withval=$with_kconfig; KCONFIG_TOOLS=$withval
++else
++  KCONFIG_TOOLS=''
++fi
++
++
+ 
+ # Check whether --with-default-link was given.
+ if test "${with_default_link+set}" = set; then :
+diff -Naur glibc-2.20/configure.ac glibc-2.20-patch/configure.ac
+--- glibc-2.20/configure.ac	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/configure.ac	2015-02-19 03:54:24.155759769 -0600
+@@ -127,6 +127,16 @@
+ 	    [sysheaders=''])
+ AC_SUBST(sysheaders)
+ 
++AC_ARG_WITH([kconfig],
++	    AC_HELP_STRING([--with-kconfig=PATH],
++			   [location of kconfig tools to use (from Linux
++			    kernel builds) to re-use for configuring EGLIBC
++			    option groups]),
++	    [KCONFIG_TOOLS=$withval],
++	    [KCONFIG_TOOLS=''])
++AC_SUBST(KCONFIG_TOOLS)
++
++
+ AC_SUBST(use_default_link)
+ AC_ARG_WITH([default-link],
+ 	    AC_HELP_STRING([--with-default-link],
+diff -Naur glibc-2.20/EGLIBC.option-groups glibc-2.20-patch/EGLIBC.option-groups
+--- glibc-2.20/EGLIBC.option-groups	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/EGLIBC.option-groups	2015-02-19 03:54:24.154759770 -0600
+@@ -0,0 +1,122 @@
++                                                        -*- mode: text -*-
++
++              The EGLIBC Component Configuration System
++                  Jim Blandy <jimb@codesourcery.com>
++
++Introduction
++
++The GNU C library (GLIBC) provides a broad range of functionality,
++ranging from internationalization support to transcendental
++mathematical functions.  Its website boasts that "nearly all known and
++useful functions from any other C library are available."  This
++exhaustive approach has been one of GLIBC's strengths on desktop and
++server systems, but it has also given GLIBC a large footprint, both in
++memory and on disk, making it a challenge to use in embedded systems
++with limited resources.
++
++The Embedded GNU C library (EGLIBC) is a variant of the GNU C library
++designed to work well on embedded systems.  In particular, EGLIBC's
++component configuration system allows embedded developers to build
++customized versions of the library that include only the features
++their application uses, reducing its space requirements.
++
++EGLIBC's component configuration system categorizes the library's
++functions into "option groups", and allows you to include or exclude
++option groups individually.  Some option groups depend on others;
++EGLIBC tracks these relationships, and ensures that the selected
++configuration yields a functioning library.
++
++
++Consistent and Predictable Behavior
++
++A flexible configuration system is a mixed blessing: if the options
++offered are poorly designed, it can be hard to see which choices will
++have the desired effects, and choices with obscure consequences can
++make debugging difficult.  EGLIBC's configuration follows some general
++principles to reduce these risks:
++
++- EGLIBC has a single default configuration for each target
++  architecture.
++
++- In the default configuration, all option groups are enabled, and
++  EGLIBC is upwardly API- and ABI-compatible with GLIBC.
++
++- As much as possible, configurations only affect what functions are
++  present, not how they behave.  If the system works with an option
++  group disabled, it will still work with it enabled.
++
++- As much as possible, configurations only select option groups ---
++  they do not describe characteristics of the target architecture.
++
++These rules mean that you have a simple debugging strategy available
++if you suspect that your EGLIBC configuration might be the source of a
++problem: fall back to the default configuration, re-test, and then
++disable option groups one by one, until the problem reappears.
++
++
++The Option Groups
++
++To see the current full list of implemented option groups, refer to the
++file 'option-groups.def' at the top of the source tree, or run
++'make menuconfig' from the top-level build directory.
++
++The POSIX.1-2001 specification includes a suggested partition of all
++the functions in the POSIX C API into option groups: math functions
++like 'sin' and 'cos'; networking functions like 'socket' and
++'connect'; and so on.  EGLIBC could use this partitioning as the basis
++for future option groups.
++
++
++Implementation
++
++The EGLIBC component configuration system resembles the approach used
++by the Linux kernel to select device drivers, network protocols, and
++other features.  A file named 'option-groups.config' in the top-level
++build directory contains assignments to Make variables, each of which
++enables or disables a particular option group.  If the variable's
++value is set to 'y', then the option group is enabled; if it set to
++anything else, the option group is omitted.  The file
++'option-groups.defaults', at the top of the source tree, establishes
++default values for all variables; all option groups are enabled by
++default.
++
++For example, the following 'option-groups.config' would omit locale
++data, but include mathematical functions, and everything else:
++
++   OPTION_EGLIBC_LOCALES = n
++   OPTION_EGLIBC_LIBM = y
++
++Like the Linux kernel, EGLIBC supports a similar set of '*config' make
++targets to make it easier to create 'option-groups.config', with all
++dependencies between option groups automatically satisfied.  Run
++'make help' to see the list of supported make config targets.  For
++example, 'make menuconfig' will update the current config utilising a
++menu based program.
++
++The option group names and their type (boolean, int, hex, string), help
++description, and dependencies with other option groups, are described by
++'option-groups.def' at the top of the source tree, analogous to the
++'Kconfig' files in the Linux kernel.
++
++In general, each option group variable controls whether a given set of
++object files in EGLIBC is compiled and included in the final
++libraries, or omitted from the build.
++
++Each subdirectory's Makefile categorizes its routines, libraries, and
++executables by option group.  For example, EGLIBC's 'math/Makefile'
++places the 'libm' library in the OPTION_EGLIBC_LIBM group as follows:
++
++   extra-libs-$(OPTION_EGLIBC_LIBM) := libm
++
++Finally, common code in 'Makerules' cites the value of the variable
++'extra-libs-y', selecting only those libraries that belong to enabled
++option groups to be built.
++
++
++Current Status and Future Directions
++
++The EGLIBC component configuration system described here is still
++under development.
++
++We have used the system to subset some portions of EGLIBC's
++Index: libc/configure.ac
+diff -Naur glibc-2.20/Makefile glibc-2.20-patch/Makefile
+--- glibc-2.20/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/Makefile	2015-02-19 03:54:24.154759770 -0600
+@@ -24,6 +24,7 @@
+ 
+ include Makeconfig
+ 
++include options-config/Makefile
+ 
+ # This is the default target; it makes everything except the tests.
+ .PHONY: all
+diff -Naur glibc-2.20/option-groups.def glibc-2.20-patch/option-groups.def
+--- glibc-2.20/option-groups.def	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/option-groups.def	2015-02-19 03:54:24.153759771 -0600
+@@ -0,0 +1,868 @@
++# This file documents the option groups EGLIBC currently supports, in
++# a format akin to the Linux Kconfig system's.  The syntax may change
++# over time.
++#
++# An entry of the form:
++#
++#   config GROUP_NAME
++#       bool "one-line explanation of what this option group controls"
++#       help
++#           Multi-line help explaining the option group's meaning in
++#           some detail, terminated by indentation level.
++#
++# defines an option group whose variable is GROUP_NAME, with
++# meaningful values 'y' (enabled) and 'n' (disabled).  The
++# documentation is formatted to be consumed by some sort of
++# interactive configuration interface, but EGLIBC doesn't have such an
++# interface yet.
++#
++# An option may have a 'depends on' line, indicating which other options
++# must also be enabled if this option is.  At present, EGLIBC doesn't
++# check that these dependencies are satisfied.
++#
++# Option group variables get their default values from the file
++# 'option-groups.defaults', in the top directory of the EGLIBC source
++# tree.  By default, all EGLIBC option groups are enabled --- their
++# variables are set to 'y'.
++#
++# After including 'option-groups.defaults', the EGLIBC make machinery
++# includes the file 'option-groups.config' from the top of the build
++# tree, if it is present.  Developers can place assignments to option
++# group variables in that file to override the defaults.  For example,
++# to disable an option group, place a line of the form:
++#
++#    OPTION_GROUP_NAME = n
++#
++# in 'option-groups.config' at the top of your build tree.  To
++# explicitly enable an option group, you may also write:
++#
++#    OPTION_GROUP_NAME = y
++#
++# although this simply reestablishes the value already set by
++# 'option-groups.defaults'.
++
++config EGLIBC_ADVANCED_INET6
++   bool "IPv6 Advanced Sockets API support (RFC3542)"
++   depends on EGLIBC_INET
++   help
++       This option group includes the functions specified by RFC 3542,
++       "Advanced Sockets Application Program Interface (API) for
++       IPv6".
++
++       This option group includes the following functions:
++
++         inet6_opt_append
++         inet6_opt_find
++         inet6_opt_finish
++         inet6_opt_get_val
++         inet6_opt_init
++         inet6_option_alloc
++         inet6_option_append
++         inet6_option_find
++         inet6_option_init
++         inet6_option_next
++         inet6_option_space
++         inet6_opt_next
++         inet6_opt_set_val
++         inet6_rth_add
++         inet6_rth_getaddr
++         inet6_rth_init
++         inet6_rth_reverse
++         inet6_rth_segments
++         inet6_rth_space
++
++config EGLIBC_BACKTRACE
++   bool "Functions for producing backtraces"
++   help
++       This option group includes functions for producing a list of
++       the function calls that are currently active in a thread, from
++       within the thread itself.  These functions are often used
++       within signal handlers, to produce diagnostic output.
++
++       This option group includes the following functions:
++
++         backtrace
++         backtrace_symbols
++         backtrace_symbols_fd
++
++config EGLIBC_BIG_MACROS
++   bool "Use extensive inline code"
++   help
++       This option group specifies whether certain pieces of code
++       should be inlined to achieve maximum speed.  If this option
++       group is not selected, function calls will be used instead,
++       hence reducing the library footprint.
++
++config EGLIBC_BSD
++   bool "BSD-specific functions, and their compatibility stubs"
++   help
++       This option group includes functions specific to BSD kernels.
++       A number of these functions have stub versions that are also
++       included in libraries built for non-BSD systems for
++       compatibility.
++
++       This option group includes the following functions:
++
++         chflags
++         fchflags
++         lchmod
++         revoke
++         setlogin
++
++config EGLIBC_CXX_TESTS
++   bool "Tests that link against the standard C++ library."
++   depends on POSIX_WIDE_CHAR_DEVICE_IO && EGLIBC_LIBM
++   help
++       This option group does not include any C library functions;
++       instead, it controls which EGLIBC tests an ordinary 'make
++       tests' runs.  With this group disabled, tests that would
++       normally link against the standard C++ library are not
++       run.
++
++       The standard C++ library depends on the math library 'libm' and
++       the wide character I/O functions included in EGLIBC.  So those
++       option groups must be enabled if this test is enabled.
++
++config EGLIBC_CATGETS
++   bool "Functions for accessing message catalogs"
++   depends on EGLIBC_LOCALE_CODE
++   help
++       This option group includes functions for accessing message
++       catalogs: catopen, catclose, and catgets.
++
++       This option group depends on the EGLIBC_LOCALE_CODE
++       option group.
++
++config EGLIBC_CHARSETS
++   bool "iconv/gconv character set conversion libraries"
++   help
++       This option group includes support for character sets other
++       than ASCII (ANSI_X3.4-1968) and Unicode and ISO-10646 in their
++       various encodings.  This affects both the character sets
++       supported by the wide and multibyte character functions, and
++       those supported by the 'iconv' functions.
++
++       With this option group disabled, EGLIBC supports only the
++       following character sets:
++
++          ANSI_X3.4         - ASCII
++          ANSI_X3.4-1968
++          ANSI_X3.4-1986
++          ASCII
++          CP367
++          CSASCII
++          IBM367
++          ISO-IR-6
++          ISO646-US
++          ISO_646.IRV:1991
++          OSF00010020
++          US
++          US-ASCII
++
++          10646-1:1993      - ISO 10646, in big-endian UCS4 form
++          10646-1:1993/UCS4
++          CSUCS4
++          ISO-10646
++          ISO-10646/UCS4
++          OSF00010104
++          OSF00010105
++          OSF00010106
++          UCS-4
++          UCS-4BE
++          UCS4
++
++          UCS-4LE           - ISO 10646, in little-endian UCS4 form
++
++          ISO-10646/UTF-8   - ISO 10646, in UTF-8 form
++          ISO-10646/UTF8
++          ISO-IR-193
++          OSF05010001
++          UTF-8
++          UTF8
++
++          ISO-10646/UCS2    - ISO 10646, in target-endian UCS2 form
++          OSF00010100
++          OSF00010101
++          OSF00010102
++          UCS-2
++          UCS2
++
++          UCS-2BE           - ISO 10646, in big-endian UCS2 form
++          UNICODEBIG
++
++          UCS-2LE           - ISO 10646, in little-endian UCS2 form
++          UNICODELITTLE
++
++          WCHAR_T           - EGLIBC's internal form (target-endian,
++                              32-bit ISO 10646)
++
++config EGLIBC_CRYPT
++   bool "Encryption library"
++   help
++       This option group includes the `libcrypt' library which
++       provides functions for one-way encryption.  Supported
++       encryption algorithms include MD5, SHA-256, SHA-512 and DES.
++
++config EGLIBC_CRYPT_UFC
++   bool "Ultra fast `crypt' implementation"
++   depends on EGLIBC_CRYPT
++   help
++       This option group provides ultra fast DES-based implementation of
++       the `crypt' function.  When this option group is disabled,
++       (a) the library will not provide the setkey[_r] and encrypt[_r]
++       functions and (b) the crypt[_r] function will return NULL and set the
++       errno to ENOSYS if /salt/ passed does not correspond to either MD5,
++       SHA-256 or SHA-512 algorithm.
++
++config EGLIBC_DB_ALIASES
++   bool "Functions for accessing the mail aliases database"
++   help
++       This option group includues functions for looking up mail
++       aliases in '/etc/aliases' or using nsswitch.  It includes the
++       following functions:
++
++         endaliasent
++         getaliasbyname
++         getaliasbyname_r
++         getaliasent
++         getaliasent_r
++         setaliasent
++
++       When this option group is disabled, the NSS service libraries
++       also lack support for querying their mail alias tables.
++
++config EGLIBC_ENVZ
++   bool "Functions for handling envz-style environment vectors."
++   help
++       This option group contains functions for creating and operating
++       on envz vectors.  An "envz vector" is a vector of strings in a
++       contiguous block of memory, where each element is a name-value
++       pair, and elements are separated from their neighbors by null
++       characters.
++
++       This option group includes the following functions:
++
++        envz_add        envz_merge
++        envz_entry      envz_remove
++        envz_get        envz_strip
++
++config EGLIBC_FCVT
++   bool "Functions for converting floating-point numbers to strings"
++   help
++       This option group includes functions for converting
++       floating-point numbers to strings.
++
++       This option group includes the following functions:
++
++         ecvt           qecvt
++	 ecvt_r		qecvt_r
++         fcvt		qfcvt
++	 fcvt_r		qfcvt_r
++         gcvt		qgcvt
++
++config EGLIBC_FMTMSG
++   bool "Functions for formatting messages"
++   help
++       This option group includes the following functions:
++
++         addseverity    fmtmsg
++
++config EGLIBC_FSTAB
++   bool "Access functions for 'fstab'"
++   help
++       This option group includes functions for reading the mount
++       point specification table, '/etc/fstab'.  These functions are
++       not included in the POSIX standard, which provides the
++       'getmntent' family of functions instead.
++
++       This option group includes the following functions:
++
++         endfsent       getfsspec
++         getfsent       setfsent
++         getfsfile
++
++config EGLIBC_FTRAVERSE
++   bool "Functions for traversing file hierarchies"
++   help
++       This option group includes functions for traversing file
++       UNIX file hierachies.
++
++       This option group includes the following functions:
++
++         fts_open       ftw
++	 fts_read	nftw
++         fts_children	ftw64
++	 fts_set	nftw64
++         fts_close
++
++config EGLIBC_GETLOGIN
++   bool "The getlogin function"
++   depends on EGLIBC_UTMP
++   help
++       This function group includes the 'getlogin' and 'getlogin_r'
++       functions, which return the user name associated by the login
++       activity with the current process's controlling terminal.
++
++       With this option group disabled, the 'glob' function will not
++       fall back on 'getlogin' to find the user's login name for tilde
++       expansion when the 'HOME' environment variable is not set.
++
++config EGLIBC_IDN
++   bool "International domain names support"
++   help
++       This option group includes the `libcidn' library which
++       provides support for international domain names.
++
++config EGLIBC_INET
++   bool "Networking support"
++   help
++       This option group includes networking-specific functions and
++       data.  With EGLIBC_INET disabled, the EGLIBC
++       installation and API changes as follows:
++
++       - The following libraries are not installed:
++
++         libnsl
++         libnss_compat
++         libnss_dns
++         libnss_hesiod
++         libnss_nis
++         libnss_nisplus
++         libresolv
++
++       - The following functions and variables are omitted from libc:
++
++         authdes_create           hstrerror              svc_fdset
++         authdes_getucred         htonl                  svc_getreq
++         authdes_pk_create        htons                  svc_getreq_common
++         authnone_create          if_freenameindex       svc_getreq_poll
++         authunix_create          if_indextoname         svc_getreqset
++         authunix_create_default  if_nameindex           svc_max_pollfd
++         bindresvport             if_nametoindex         svc_pollfd
++         callrpc                  in6addr_any            svcraw_create
++         cbc_crypt                in6addr_loopback       svc_register
++         clnt_broadcast           inet6_opt_append       svc_run
++         clnt_create              inet6_opt_find         svc_sendreply
++         clnt_pcreateerror        inet6_opt_finish       svctcp_create
++         clnt_perrno              inet6_opt_get_val      svcudp_bufcreate
++         clnt_perror              inet6_opt_init         svcudp_create
++         clntraw_create           inet6_option_alloc     svcudp_enablecache
++         clnt_spcreateerror       inet6_option_append    svcunix_create
++         clnt_sperrno             inet6_option_find      svcunixfd_create
++         clnt_sperror             inet6_option_init      svc_unregister
++         clnttcp_create           inet6_option_next      user2netname
++         clntudp_bufcreate        inet6_option_space     xdecrypt
++         clntudp_create           inet6_opt_next         xdr_accepted_reply
++         clntunix_create          inet6_opt_set_val      xdr_array
++         des_setparity            inet6_rth_add          xdr_authdes_cred
++         ecb_crypt                inet6_rth_getaddr      xdr_authdes_verf
++         endaliasent              inet6_rth_init         xdr_authunix_parms
++         endhostent               inet6_rth_reverse      xdr_bool
++         endnetent                inet6_rth_segments     xdr_bytes
++         endnetgrent              inet6_rth_space        xdr_callhdr
++         endprotoent              inet_addr              xdr_callmsg
++         endrpcent                inet_aton              xdr_char
++         endservent               inet_lnaof             xdr_cryptkeyarg
++         ether_aton               inet_makeaddr          xdr_cryptkeyarg2
++         ether_aton_r             inet_netof             xdr_cryptkeyres
++         ether_hostton            inet_network           xdr_des_block
++         ether_line               inet_nsap_addr         xdr_double
++         ether_ntoa               inet_nsap_ntoa         xdr_enum
++         ether_ntoa_r             inet_ntoa              xdr_float
++         ether_ntohost            inet_ntop              xdr_free
++         freeaddrinfo             inet_pton              xdr_getcredres
++         freeifaddrs              innetgr                xdr_hyper
++         gai_strerror             iruserok               xdr_int
++         getaddrinfo              iruserok_af            xdr_int16_t
++         getaliasbyname           key_decryptsession     xdr_int32_t
++         getaliasbyname_r         key_decryptsession_pk  xdr_int64_t
++         getaliasent              key_encryptsession     xdr_int8_t
++         getaliasent_r            key_encryptsession_pk  xdr_keybuf
++         gethostbyaddr            key_gendes             xdr_key_netstarg
++         gethostbyaddr_r          key_get_conv           xdr_key_netstres
++         gethostbyname            key_secretkey_is_set   xdr_keystatus
++         gethostbyname2           key_setnet             xdr_long
++         gethostbyname2_r         key_setsecret          xdr_longlong_t
++         gethostbyname_r          netname2host           xdrmem_create
++         gethostent               netname2user           xdr_netnamestr
++         gethostent_r             ntohl                  xdr_netobj
++         getifaddrs               ntohs                  xdr_opaque
++         getipv4sourcefilter      passwd2des             xdr_opaque_auth
++         get_myaddress            pmap_getmaps           xdr_pmap
++         getnameinfo              pmap_getport           xdr_pmaplist
++         getnetbyaddr             pmap_rmtcall           xdr_pointer
++         getnetbyaddr_r           pmap_set               xdr_quad_t
++         getnetbyname             pmap_unset             xdrrec_create
++         getnetbyname_r           rcmd                   xdrrec_endofrecord
++         getnetent                rcmd_af                xdrrec_eof
++         getnetent_r              registerrpc            xdrrec_skiprecord
++         getnetgrent              res_init               xdr_reference
++         getnetgrent_r            rexec                  xdr_rejected_reply
++         getnetname               rexec_af               xdr_replymsg
++         getprotobyname           rexecoptions           xdr_rmtcall_args
++         getprotobyname_r         rpc_createerr          xdr_rmtcallres
++         getprotobynumber         rresvport              xdr_short
++         getprotobynumber_r       rresvport_af           xdr_sizeof
++         getprotoent              rtime                  xdrstdio_create
++         getprotoent_r            ruserok                xdr_string
++         getpublickey             ruserok_af             xdr_u_char
++         getrpcbyname             ruserpass              xdr_u_hyper
++         getrpcbyname_r           setaliasent            xdr_u_int
++         getrpcbynumber           sethostent             xdr_uint16_t
++         getrpcbynumber_r         setipv4sourcefilter    xdr_uint32_t
++         getrpcent                setnetent              xdr_uint64_t
++         getrpcent_r              setnetgrent            xdr_uint8_t
++         getrpcport               setprotoent            xdr_u_long
++         getsecretkey             setrpcent              xdr_u_longlong_t
++         getservbyname            setservent             xdr_union
++         getservbyname_r          setsourcefilter        xdr_unixcred
++         getservbyport            svcauthdes_stats       xdr_u_quad_t
++         getservbyport_r          svcerr_auth            xdr_u_short
++         getservent               svcerr_decode          xdr_vector
++         getservent_r             svcerr_noproc          xdr_void
++         getsourcefilter          svcerr_noprog          xdr_wrapstring
++         h_errlist                svcerr_progvers        xencrypt
++         h_errno                  svcerr_systemerr       xprt_register
++         herror                   svcerr_weakauth        xprt_unregister
++         h_nerr                   svc_exit
++         host2netname             svcfd_create
++
++       - The rpcgen, nscd, and rpcinfo commands are not installed.
++
++       - The 'rpc' file (a text file listing RPC services) is not installed.
++
++       Socket-related system calls do not fall in this option group,
++       because many are also used for other inter-process
++       communication mechanisms.  For example, the 'syslog' routines
++       use Unix-domain sockets to communicate with the syslog daemon;
++       syslog is valuable in non-networked contexts.
++
++config EGLIBC_INET_ANL
++   bool "Asynchronous name lookup"
++   depends on EGLIBC_INET
++   help
++       This option group includes the `libanl' library which
++       provides support for asynchronous name lookup.
++
++config EGLIBC_LIBM
++   bool "libm (math library)"
++   help
++       This option group includes the 'libm' library, containing
++       mathematical functions.  If this option group is omitted, then
++       an EGLIBC installation does not include shared or unshared versions
++       of the math library.
++
++       Note that this does not remove all floating-point related
++       functionality from EGLIBC; for example, 'printf' and 'scanf'
++       can still print and read floating-point values with this option
++       group disabled.
++
++       Note that the ISO Standard C++ library 'libstdc++' depends on
++       EGLIBC's math library 'libm'.  If you disable this option
++       group, you will not be able to build 'libstdc++' against the
++       resulting EGLIBC installation.
++
++config EGLIBC_LOCALES
++   bool "Locale definitions"
++   help
++       This option group includes all locale definitions other than
++       that for the "C" locale.  If this option group is omitted, then
++       only the "C" locale is supported.
++
++
++config EGLIBC_LOCALE_CODE
++   bool "Locale functions"
++   depends on POSIX_C_LANG_WIDE_CHAR
++   help
++       This option group includes locale support functions, programs,
++       and libraries.  With EGLIBC_LOCALE_CODE disabled,
++       EGLIBC supports only the 'C' locale (also known as 'POSIX'),
++       and ignores the settings of the 'LANG' and 'LC_*' environment
++       variables.
++
++       With EGLIBC_LOCALE_CODE disabled, the following
++       functions are omitted from libc:
++
++         duplocale   localeconv  nl_langinfo    rpmatch  strfmon_l
++         freelocale  newlocale   nl_langinfo_l  strfmon  uselocale
++
++       Furthermore, only the LC_CTYPE and LC_TIME categories of the
++       standard "C" locale are available.
++
++       The EGLIBC_CATGETS option group depends on this option group.
++
++
++config EGLIBC_MEMUSAGE
++   bool "Memory profiling library"
++   help
++       This option group includes the `libmemusage' library and
++       the `memusage' and `memusagestat' utilities.
++       These components provide memory profiling functions.
++
++config EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++   int "Memory profiling library buffer size"
++   depends on EGLIBC_MEMUSAGE
++   default "32768"
++   help
++       Libmemusage library buffers the profiling data in memory
++       before writing it out to disk.  By default, the library
++       allocates 1.5M buffer, which can be substantial for some
++       systems.  EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE option
++       allows to change the default buffer size.  It specifies
++       the number of entries the buffer should have.
++       On most architectures one buffer entry amounts to 48 bytes,
++       so setting this option to the value of 512 will reduce the size of
++       the memory buffer to 24K.
++
++config EGLIBC_NIS
++   bool "Support for NIS, NIS+, and the special 'compat' services."
++   depends on EGLIBC_INET && EGLIBC_SUNRPC
++   help
++       This option group includes the NIS, NIS+, and 'compat' Name
++       Service Switch service libraries.  When it is disabled, those
++       services libraries are not installed; you should remove any
++       references to them from your 'nsswitch.conf' file.
++
++       This option group depends on the EGLIBC_INET option
++       group; you must enable that to enable this option group.
++
++config EGLIBC_NSSWITCH
++   bool "Name service switch (nsswitch) support"
++   help
++       This option group includes support for the 'nsswitch' facility.
++       With this option group enabled, all EGLIBC functions for
++       accessing various system databases (passwords and groups;
++       networking; aliases; public keys; and so on) consult the
++       '/etc/nsswitch.conf' configuration file to decide how to handle
++       queries.
++
++       With this option group disabled, EGLIBC uses a fixed list of
++       services to satisfy queries on each database, as requested by
++       configuration files specified when EGLIBC is built.  Your
++       'option-groups.config' file must set the following two
++       variables:
++
++config EGLIBC_NSSWITCH_FIXED_CONFIG
++   string "Nsswitch fixed config filename"
++   depends on !EGLIBC_NSSWITCH
++   default ""
++   help
++          Set this to the name of a file whose contents observe the
++          same syntax as an ordinary '/etc/nsswitch.conf' file.  The
++          EGLIBC build process parses this file just as EGLIBC would
++          at run time if EGLIBC_NSSWITCH were enabled, and
++          produces a C library that uses the nsswitch service
++          libraries to search for database entries as this file
++          specifies, instead of consulting '/etc/nsswitch.conf' at run
++          time.
++
++          This should be an absolute filename.  The EGLIBC build
++          process may use it from several different working
++          directories.  It may include references to Makefile
++          variables like 'common-objpfx' (the top of the build tree,
++          with a trailing slash), or '..' (the top of the source tree,
++          with a trailing slash).
++
++          The EGLIBC source tree includes a sample configuration file
++          named 'nss/fixed-nsswitch.conf'; for simple configurations,
++          you will probably want to delete references to databases not
++          needed on your system.
++
++config EGLIBC_NSSWITCH_FIXED_FUNCTIONS
++   string "Nsswitch fixed functions filename"
++   depends on !EGLIBC_NSSWITCH
++   default ""
++   help
++          The EGLIBC build process uses this file to decide which
++          functions to make available from which service libraries.
++          The file 'nss/fixed-nsswitch.functions' serves as a sample
++          configuration file for this setting, and explains its syntax
++          and meaning in more detail.
++
++          This should be an absolute file name.  The EGLIBC build
++          process may use it from several different working
++          directories.  It may include references to Makefile
++          variables like 'common-objpfx' (the top of the build tree,
++          with a trailing slash), or '..' (the top of the source tree,
++          with a trailing slash).
++
++          Be sure to mention each function in each service you wish to
++          use.  If you do not mention a service's function here, the
++          EGLIBC database access functions will not find it, even if
++          it is listed in the EGLIBC_NSSWITCH_FIXED_CONFIG
++          file.
++
++          In this arrangement, EGLIBC will not use the 'dlopen' and
++          'dlsym' functions to find database access functions.  Instead,
++          libc hard-codes references to the service libraries' database
++          access functions.  You must explicitly link your program
++          against the name service libraries (those whose names start
++          with 'libnss_', in the sysroot's '/lib' directory) whose
++          functions you intend to use.  This arrangement helps
++          system-wide static analysis tools decide which functions a
++          system actually uses.
++
++          Note that some nsswitch service libraries require other option
++          groups to be enabled; for example, the EGLIBC_INET
++          option group must be enabled to use the 'libnss_dns.so.2'
++          service library, which uses the Domain Name System network
++          protocol to answer queries.
++
++config EGLIBC_RCMD
++   bool "Support for 'rcmd' and related library functions"
++   depends on EGLIBC_INET
++   help
++      This option group includes functions for running commands on
++      remote machines via the 'rsh' protocol, and doing authentication
++      related to those functions.  This also includes functions that
++      use the 'rexec' protocol.
++
++      This option group includes the following functions:
++
++        rcmd            ruserok
++        rcmd_af         ruserok_af
++        rexec           iruserok
++        rexec_af        iruserok_af
++        rresvport       ruserpass
++        rresvport_af
++
++config EGLIBC_RTLD_DEBUG
++   bool "Runtime linker debug print outs"
++   help
++      This option group enables debug output of the runtime linker
++      which is activated via LD_DEBUG and LD_TRACE_PRELINKING
++      environment variables.  Disabling this option group yields
++      a smaller runtime linker binary.
++      BEWARE: Disabling this option group is likely to break
++      the `ldd' utility which may also be used by the prelinker.
++      In particular, the `--unused' ldd option will not work correctly.
++
++config EGLIBC_SPAWN
++   bool "Support for POSIX posix_spawn functions"
++   help
++      This option group includes the POSIX functions for executing
++      programs in child processes without using 'fork' or 'vfork'.
++
++      This option group includes the following functions:
++
++        posix_spawn
++        posix_spawnattr_destroy
++        posix_spawnattr_getflags
++        posix_spawnattr_getpgroup
++        posix_spawnattr_getschedparam
++        posix_spawnattr_getschedpolicy
++        posix_spawnattr_getsigdefault
++        posix_spawnattr_getsigmask
++        posix_spawnattr_init
++        posix_spawnattr_setflags
++        posix_spawnattr_setpgroup
++        posix_spawnattr_setschedparam
++        posix_spawnattr_setschedpolicy
++        posix_spawnattr_setsigdefault
++        posix_spawnattr_setsigmask
++        posix_spawn_file_actions_addclose
++        posix_spawn_file_actions_adddup2
++        posix_spawn_file_actions_addopen
++        posix_spawn_file_actions_destroy
++        posix_spawn_file_actions_init
++        posix_spawnp
++
++      This option group also provides the ability for the iconv,
++      localedef, and locale programs to operate transparently on
++      compressed charset definitions.  When this option group is
++      disabled, those programs will only operate on uncompressed
++      charmap files.
++
++config EGLIBC_STREAMS
++   bool "Support for accessing STREAMS."
++   help
++      This option group includes functions for reading and writing
++      messages to and from STREAMS.  The STREAMS interface provides a
++      uniform mechanism for implementing networking services and other
++      character-based I/O.  (STREAMS are not to be confused with
++      <stdio.h> FILE objects, also called 'streams'.)
++
++      This option group includes the following functions:
++
++        getmsg          putpmsg
++        getpmsg         fattach
++        isastream       fdetach
++        putmsg
++
++config EGLIBC_SUNRPC
++   bool "Support for the Sun 'RPC' protocol."
++   depends on EGLIBC_INET
++   help
++      This option group includes support for the Sun RPC protocols,
++      including the 'rpcgen' and 'rpcinfo' programs.
++
++config EGLIBC_UTMP
++    bool "Older access functions for 'utmp' login records"
++    help
++       This option group includes the older 'utent' family of
++       functions for accessing user login records in the 'utmp' file.
++       POSIX omits these functions in favor of the 'utxent' family,
++       and they are obsolete on systems other than Linux.
++
++       This option group includes the following functions:
++
++         endutent
++         getutent
++         getutent_r
++         getutid
++         getutid_r
++         getutline
++         getutline_r
++         logwtmp
++         pututline
++         setutent
++         updwtmp
++         utmpname
++
++       This option group includes the following libraries:
++
++         libutil.so (and libutil.a)
++
++config EGLIBC_UTMPX
++    bool "POSIX access functions for 'utmp' login records"
++    depends on EGLIBC_UTMP
++    help
++       This option group includes the POSIX functions for reading and
++       writing user login records in the 'utmp' file (usually
++       '/var/run/utmp').  The POSIX functions operate on 'struct
++       utmpx' structures, as opposed to the family of older 'utent'
++       functions, which operate on 'struct utmp' structures.
++
++       This option group includes the following functions:
++
++         endutxent
++         getutmp
++         getutmpx
++         getutxent
++         getutxid
++         getutxline
++         pututxline
++         setutxent
++         updwtmpx
++         utmpxname
++
++config EGLIBC_WORDEXP
++    bool "Shell-style word expansion"
++    help
++        This option group includes the 'wordexp' function for
++        performing word expansion in the manner of the shell, and the
++        accompanying 'wordfree' function.
++
++config POSIX_C_LANG_WIDE_CHAR
++    bool "ISO C library wide character functions, excluding I/O"
++    help
++        This option group includes the functions defined by the ISO C
++        standard for working with wide and multibyte characters in
++        memory.  Functions for reading and writing wide and multibyte
++        characters from and to files call in the
++        POSIX_WIDE_CHAR_DEVICE_IO option group.
++
++        This option group includes the following functions:
++
++          btowc         mbsinit       wcscspn       wcstoll
++          iswalnum      mbsrtowcs     wcsftime      wcstombs
++          iswalpha      mbstowcs      wcslen        wcstoul
++          iswblank      mbtowc        wcsncat       wcstoull
++          iswcntrl      swprintf      wcsncmp       wcstoumax
++          iswctype      swscanf       wcsncpy       wcsxfrm
++          iswdigit      towctrans     wcspbrk       wctob
++          iswgraph      towlower      wcsrchr       wctomb
++          iswlower      towupper      wcsrtombs     wctrans
++          iswprint      vswprintf     wcsspn        wctype
++          iswpunct      vswscanf      wcsstr        wmemchr
++          iswspace      wcrtomb       wcstod        wmemcmp
++          iswupper      wcscat        wcstof        wmemcpy
++          iswxdigit     wcschr        wcstoimax     wmemmove
++          mblen         wcscmp        wcstok        wmemset
++          mbrlen        wcscoll       wcstol
++          mbrtowc       wcscpy        wcstold
++
++config POSIX_REGEXP
++    bool "Regular expressions"
++    help
++        This option group includes the POSIX regular expression
++        functions, and the associated non-POSIX extensions and
++        compatibility functions.
++
++        With POSIX_REGEXP disabled, the following functions are
++        omitted from libc:
++
++          re_comp                 re_max_failures         regcomp
++          re_compile_fastmap      re_search               regerror
++          re_compile_pattern      re_search_2             regexec
++          re_exec                 re_set_registers        regfree
++          re_match                re_set_syntax           rpmatch
++          re_match_2              re_syntax_options
++
++        Furthermore, the compatibility regexp interface defined in the
++        <regexp.h> header file, 'compile', 'step', and 'advance', is
++        omitted.
++
++config POSIX_REGEXP_GLIBC
++    bool "Regular expressions from GLIBC"
++    depends on POSIX_REGEXP
++    help
++	This option group specifies which regular expression
++        library to use.  The choice is between regex
++        implementation from GLIBC and regex implementation from
++        libiberty.  The GLIBC variant is fully POSIX conformant and
++        optimized for speed; regex from libiberty is more than twice
++        as small while still is enough for most practical purposes.
++
++config POSIX_WIDE_CHAR_DEVICE_IO
++    bool "Input and output functions for wide characters"
++    depends on POSIX_C_LANG_WIDE_CHAR
++    help
++        This option group includes functions for reading and writing
++        wide characters to and from <stdio.h> streams.
++
++        This option group includes the following functions:
++
++          fgetwc        fwprintf      putwchar      vwscanf
++          fgetws        fwscanf       ungetwc       wprintf
++          fputwc        getwc         vfwprintf     wscanf
++          fputws        getwchar      vfwscanf
++          fwide         putwc         vwprintf
++
++        This option group further includes the following unlocked
++        variants of the above functions:
++
++          fgetwc_unlocked           getwc_unlocked
++          fgetws_unlocked           getwchar_unlocked
++          fputwc_unlocked           putwc_unlocked
++          fputws_unlocked           putwchar_unlocked
++
++        Note that the GNU standard C++ library, 'libstdc++.so', uses
++        some of these functions; you will not be able to link or run
++        C++ programs if you disable this option group.
++
++        This option group also affects the behavior of the following
++        functions:
++
++          fdopen
++          fopen
++          fopen64
++          freopen
++          freopen64
++
++        These functions all take an OPENTYPE parameter which may
++        contain a string of the form ",ccs=CHARSET", indicating that
++        the underlying file uses the character set named CHARSET.
++        This produces a wide-oriented stream, which is only useful
++        when the functions included in this option group are present.
++        If the user attempts to open a file specifying a character set
++        in the OPENTYPE parameter, and EGLIBC was built with this
++        option group disabled, the function returns NULL, and sets
++        errno to EINVAL.
++
++\f
++# This helps Emacs users browse this file using the page motion commands
++# and commands like 'pages-directory'.
++# Local Variables:
++# page-delimiter: "^config\\s-"
++# End:
+diff -Naur glibc-2.20/option-groups.defaults glibc-2.20-patch/option-groups.defaults
+--- glibc-2.20/option-groups.defaults	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/option-groups.defaults	2015-02-19 03:54:24.153759771 -0600
+@@ -0,0 +1,47 @@
++# This file sets default values for all option group variables
++# mentioned in option-groups.def; see that file for a description of
++# each option group.
++#
++# Subdirectory makefiles include this file before including the user's
++# settings from option-groups.config at the top of the build tree;
++# that file need only refer to those options whose default settings
++# are to be changed.
++#
++# By default, all option groups are enabled.
++OPTION_EGLIBC_ADVANCED_INET6 = y
++OPTION_EGLIBC_BACKTRACE = y
++OPTION_EGLIBC_BIG_MACROS = y
++OPTION_EGLIBC_BSD = y
++OPTION_EGLIBC_CXX_TESTS = y
++OPTION_EGLIBC_CATGETS = y
++OPTION_EGLIBC_CHARSETS = y
++OPTION_EGLIBC_CRYPT = y
++OPTION_EGLIBC_CRYPT_UFC = y
++OPTION_EGLIBC_DB_ALIASES = y
++OPTION_EGLIBC_ENVZ = y
++OPTION_EGLIBC_FCVT = y
++OPTION_EGLIBC_FMTMSG = y
++OPTION_EGLIBC_FSTAB = y
++OPTION_EGLIBC_FTRAVERSE = y
++OPTION_EGLIBC_GETLOGIN = y
++OPTION_EGLIBC_IDN = y
++OPTION_EGLIBC_INET = y
++OPTION_EGLIBC_INET_ANL = y
++OPTION_EGLIBC_LIBM = y
++OPTION_EGLIBC_LOCALES = y
++OPTION_EGLIBC_LOCALE_CODE = y
++OPTION_EGLIBC_MEMUSAGE = y
++OPTION_EGLIBC_NIS = y
++OPTION_EGLIBC_NSSWITCH = y
++OPTION_EGLIBC_RCMD = y
++OPTION_EGLIBC_RTLD_DEBUG = y
++OPTION_EGLIBC_SPAWN = y
++OPTION_EGLIBC_STREAMS = y
++OPTION_EGLIBC_SUNRPC = y
++OPTION_EGLIBC_UTMP = y
++OPTION_EGLIBC_UTMPX = y
++OPTION_EGLIBC_WORDEXP = y
++OPTION_POSIX_C_LANG_WIDE_CHAR = y
++OPTION_POSIX_REGEXP = y
++OPTION_POSIX_REGEXP_GLIBC = y
++OPTION_POSIX_WIDE_CHAR_DEVICE_IO = y
+diff -Naur glibc-2.20/option-groups.mak glibc-2.20-patch/option-groups.mak
+--- glibc-2.20/option-groups.mak	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/option-groups.mak	2015-02-19 03:54:24.153759771 -0600
+@@ -0,0 +1,41 @@
++# Setup file for subdirectory Makefiles that define EGLIBC option groups.
++
++# EGLIBC shouldn't need to override this.  However, the
++# cross-build-friendly localedef includes this makefile to get option
++# group variable definitions; it uses a single build tree for all the
++# multilibs, and needs to be able to specify a different option group
++# configuration file for each multilib.
++option_group_config_file ?= $(objdir)/option-groups.config
++
++# Read the default settings for all options.
++# We're included before ../Rules, so we can't assume $(..) is set.
++include $(firstword $(..) ../)option-groups.defaults
++
++# Read the developer's option group selections, overriding the
++# defaults from option-groups.defaults.
++-include $(option_group_config_file)
++
++# $(call option-disabled, VAR) is 'y' if VAR is not 'y', or 'n' otherwise.
++# VAR should be a variable name, not a variable reference; this is
++# less general, but more terse for the intended use.
++# You can use it to add a file to a list if an option group is
++# disabled, like this:
++#   routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += ...
++define option-disabled
++$(firstword $(subst y,n,$(filter y,$($(strip $(1))))) y)
++endef
++
++# Establish 'routines-y', etc. as simply-expanded variables.
++aux-y	       	    :=
++extra-libs-others-y :=
++extra-libs-y   	    :=
++extra-objs-y   	    :=
++install-bin-y  	    :=
++install-others-y    :=
++install-sbin-y 	    :=
++others-y       	    :=
++others-pie-y   	    :=
++routines-y     	    :=
++test-srcs-y    	    :=
++tests-y        	    :=
++xtests-y       	    :=
+diff -Naur glibc-2.20/options-config/config-postproc.pl glibc-2.20-patch/options-config/config-postproc.pl
+--- glibc-2.20/options-config/config-postproc.pl	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/options-config/config-postproc.pl	2015-02-19 03:54:31.073759206 -0600
+@@ -0,0 +1,58 @@
++#!/usr/bin/perl
++
++$usage = "usage: $0 <default config file> <config file>\n";
++
++die "$usage" unless @ARGV;
++$defaults = shift @ARGV;
++die "$usage" unless @ARGV;
++die "Could not open $ARGV[0]" unless -T $ARGV[0];
++
++sub yank {
++    @option = grep(!($_ =~ /$_[0]\s*=/), @option);
++}
++
++open(DEFAULTS, $defaults) || die "Could not open $defaults\n";
++
++# get the full list of available options using the default config file
++$i = 0;
++while (<DEFAULTS>) {
++    if (/^\s*OPTION_(\w+\s*=.*$)/) {
++	$option[$i++] = $1;
++    }
++}
++
++# now go through the config file, making the necessary changes
++while (<>) {
++    if (/Linux Kernel Configuration/) {
++	# change title
++	s/Linux Kernel/Option Groups/;
++	print;
++    } elsif (/^\s*CONFIG_(\w+)\s*=/) {
++	# this is an explicit option set line, change CONFIG_ to OPTION_
++	# before printing and remove this option from option list
++	$opt = $1;
++	yank($opt);
++	s/CONFIG_/OPTION_/g;
++	print;
++    } elsif (/^\s*#\s+CONFIG_(\w+) is not set/) {
++	# this is a comment line for an unset boolean option, change CONFIG_
++	# to OPTION_, remove this option from option list, and convert to
++	# explicit OPTION_FOO=n
++	$opt = $1;
++	yank($opt);
++	s/CONFIG_/OPTION_/g;
++	print "OPTION_$opt=n\n";
++    } else {
++	print;
++    }
++}
++
++# any boolean options left in @options, are options that were not mentioned in
++# the config file, and implicitly that means the option must be set =n,
++# so do that here.
++foreach $opt (@option) {
++    if ($opt =~ /=\s*[yn]/) {
++	$opt =~ s/=\s*[yn]/=n/;
++	print "OPTION_$opt\n";
++    }
++}
+diff -Naur glibc-2.20/options-config/config-preproc.pl glibc-2.20-patch/options-config/config-preproc.pl
+--- glibc-2.20/options-config/config-preproc.pl	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/options-config/config-preproc.pl	2015-02-19 03:54:31.073759206 -0600
+@@ -0,0 +1,8 @@
++#!/usr/bin/perl
++
++if (@ARGV) {
++    while (<>) {
++	s/OPTION_/CONFIG_/g;
++	print;
++    }
++}
+diff -Naur glibc-2.20/options-config/Makefile glibc-2.20-patch/options-config/Makefile
+--- glibc-2.20/options-config/Makefile	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/options-config/Makefile	2015-02-19 03:54:26.748759537 -0600
+@@ -0,0 +1,55 @@
++# ===========================================================================
++# EGLIBC option-groups configuration targets
++# These targets are included from top-level makefile
++
++ifneq ($(kconfig_tools),)
++ifneq (no,$(PERL))
++
++ocdir := options-config
++
++OconfigDefaults     := option-groups.defaults
++OconfigDefaults_tmp := $(common-objpfx).tmp.defconfig
++OconfigDef          := option-groups.def
++Oconfig             := $(common-objpfx)option-groups.config
++Oconfig_tmp         := $(common-objpfx).tmp.config
++
++conf  := $(kconfig_tools)/conf
++mconf := $(kconfig_tools)/mconf
++
++preproc  := $(PERL) $(ocdir)/config-preproc.pl
++postproc := $(PERL) $(ocdir)/config-postproc.pl
++
++PHONY += defconfig config menuconfig
++
++defconfig: $(conf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(OconfigDefaults_tmp)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(OconfigDefaults) > $(OconfigDefaults_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< --defconfig=$(OconfigDefaults_tmp) \
++				$(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++	rm $(OconfigDefaults_tmp)
++
++config: $(conf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< --oldaskconfig $(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++
++menuconfig: $(mconf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< $(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++
++# Help text used by make help
++help:
++	@echo  '  defconfig	  - New config with default from default config'
++	@echo  '  config	  - Update current config utilising a line-oriented program'
++	@echo  '  menuconfig	  - Update current config utilising a menu based program'
++
++endif
++endif
+diff -Naur glibc-2.20/scripts/option-groups.awk glibc-2.20-patch/scripts/option-groups.awk
+--- glibc-2.20/scripts/option-groups.awk	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/scripts/option-groups.awk	2015-02-19 03:54:31.073759206 -0600
+@@ -0,0 +1,63 @@
++# option-groups.awk --- generate option group header file
++# Given input files containing makefile-style assignments to variables,
++# print out a header file that #defines an appropriate preprocessor
++# symbol for each variable left set to 'y'.
++
++BEGIN { FS="=" }
++
++# Trim spaces.
++{ gsub (/[[:blank:]]/, "") }
++
++# Skip comments.
++/^#/ { next }
++
++# Process assignments.
++NF == 2 {
++    vars[$1] = $2
++}
++
++# Print final values.
++END {
++    print "/* This file is automatically generated by scripts/option-groups.awk"
++    print "   in the EGLIBC source tree."
++    print ""
++    print "   It defines macros that indicate which EGLIBC option groups were"
++    print "   configured in 'option-groups.config' when this C library was"
++    print "   built.  For each option group named OPTION_foo, it #defines"
++    print "   __OPTION_foo to be 1 if the group is enabled, or #defines that"
++    print "   symbol to be 0 if the group is disabled.  */"
++    print ""
++    print "#ifndef __GNU_OPTION_GROUPS_H"
++    print "#define __GNU_OPTION_GROUPS_H"
++    print ""
++
++    # Produce a sorted list of variable names.
++    i=0
++    for (var in vars)
++        names[i++] = var
++    n = asort (names)
++
++    for (i = 1; i <= n; i++)
++    {
++        var = names[i]
++        if (var ~ /^OPTION_/)
++        {
++            if (vars[var] == "y")
++                print "#define __" var " 1"
++            else if (vars[var] == "n")
++                print "#define __" var " 0"
++	    else if (vars[var] ~ /^[0-9]+/ ||
++		     vars[var] ~ /^0x[0-9aAbBcCdDeEfF]+/ ||
++		     vars[var] ~ /^\"/)
++		 print "#define __" var " " vars[var]
++	    else
++		print "/* #undef __" var " */"
++            # Ignore variables that don't have boolean, int, hex, or
++	    # string values. Ideally, this would be driven by the types
++	    # given in option-groups.def.
++        }
++    }
++
++    print ""
++    print "#endif /* __GNU_OPTION_GROUPS_H */"
++}
diff --git a/recipes-core/glibc/glibc-fsl/00xx.glibc.rtld_debug_option_group.patch b/recipes-core/glibc/glibc-fsl/00xx.glibc.rtld_debug_option_group.patch
new file mode 100755
index 0000000..cb3deae
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/00xx.glibc.rtld_debug_option_group.patch
@@ -0,0 +1,517 @@
+# Problem Statement:
+  Remove debug print outs from the run-time linker.
+  Its controlled by __OPTION_EGLIBC_RTLD_DEBUG,
+  so we should use GLRO_dl_debug_mask
+
+# Referred from patch by:
+  Yocto Project
+  http://git.yoctoproject.org/cgit.cgi/poky/plain/meta/recipes-core/glibc/glibc/GLRO_dl_debug_mask.patch
+  Singed-off-by: Khem Raj <raj.khem@gmail.com>
+
+diff -Naur glibc-2.20/csu/libc-start.c glibc-2.20-rtld-debug/csu/libc-start.c
+--- glibc-2.20/csu/libc-start.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/csu/libc-start.c	2015-02-19 04:00:31.552729822 -0600
+@@ -238,7 +238,7 @@
+ 
+   /* Call the initializer of the program, if any.  */
+ #ifdef SHARED
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
+     GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
+ #endif
+   if (init)
+@@ -261,7 +261,7 @@
+ #endif
+ 
+ #ifdef SHARED
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+     GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
+ #endif
+ 
+diff -Naur glibc-2.20/elf/dl-cache.c glibc-2.20-rtld-debug/elf/dl-cache.c
+--- glibc-2.20/elf/dl-cache.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-cache.c	2015-02-19 04:00:31.552729822 -0600
+@@ -187,7 +187,7 @@
+   const char *best;
+ 
+   /* Print a message if the loading of libs is traced.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+     _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);
+ 
+   if (cache == NULL)
+@@ -285,7 +285,7 @@
+     }
+ 
+   /* Print our result if wanted.  */
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
+       && best != NULL)
+     _dl_debug_printf ("  trying file=%s\n", best);
+ 
+diff -Naur glibc-2.20/elf/dl-close.c glibc-2.20-rtld-debug/elf/dl-close.c
+--- glibc-2.20/elf/dl-close.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-close.c	2015-02-19 04:00:31.553729819 -0600
+@@ -125,7 +125,7 @@
+ 	dl_close_state = rerun;
+ 
+       /* There are still references to this object.  Do nothing more.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
+ 			  map->l_name, map->l_direct_opencount);
+ 
+@@ -257,7 +257,7 @@
+ 	  if (imap->l_init_called)
+ 	    {
+ 	      /* When debugging print a message first.  */
+-	      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
++	      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS,
+ 				    0))
+ 		_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+ 				  imap->l_name, nsid);
+@@ -664,7 +664,7 @@
+ 	  free (imap->l_reldeps);
+ 
+ 	  /* Print debugging message.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	    _dl_debug_printf ("\nfile=%s [%lu];  destroying link map\n",
+ 			      imap->l_name, imap->l_ns);
+ 
+diff -Naur glibc-2.20/elf/dl-conflict.c glibc-2.20-rtld-debug/elf/dl-conflict.c
+--- glibc-2.20/elf/dl-conflict.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-conflict.c	2015-02-19 04:00:31.553729819 -0600
+@@ -32,7 +32,7 @@
+ 		       ElfW(Rela) *conflictend)
+ {
+ #if ! ELF_MACHINE_NO_RELA
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
+     _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
+ 
+   {
+diff -Naur glibc-2.20/elf/dl-deps.c glibc-2.20-rtld-debug/elf/dl-deps.c
+--- glibc-2.20/elf/dl-deps.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-deps.c	2015-02-19 04:00:31.553729819 -0600
+@@ -127,7 +127,7 @@
+ 	    else							      \
+ 	      {								      \
+ 		/* This is for DT_AUXILIARY.  */			      \
+-		if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))   \
++		if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))   \
+ 		  _dl_debug_printf (N_("\
+ cannot load auxiliary `%s' because of empty dynamic string token "	      \
+ 					    "substitution\n"), __str);	      \
+@@ -303,7 +303,7 @@
+ 		args.name = name;
+ 
+ 		/* Say that we are about to load an auxiliary library.  */
+-		if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
++		if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS,
+ 				      0))
+ 		  _dl_debug_printf ("load auxiliary object=%s"
+ 				    " requested by file=%s\n",
+@@ -520,7 +520,7 @@
+       runp->map->l_reserved = 0;
+     }
+ 
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0
+       && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
+     {
+       /* If we are to compute conflicts, we have to build local scope
+diff -Naur glibc-2.20/elf/dl-error.c glibc-2.20-rtld-debug/elf/dl-error.c
+--- glibc-2.20/elf/dl-error.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-error.c	2015-02-19 04:00:31.554729815 -0600
+@@ -139,7 +139,7 @@
+ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
+ 		   const char *errstring)
+ {
+-  if (__builtin_expect (GLRO(dl_debug_mask)
++  if (__builtin_expect (GLRO_dl_debug_mask
+ 			& ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
+     _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
+ 		      errstring, receiver ? "continued" : "fatal");
+diff -Naur glibc-2.20/elf/dl-fini.c glibc-2.20-rtld-debug/elf/dl-fini.c
+--- glibc-2.20/elf/dl-fini.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-fini.c	2015-02-19 04:00:31.554729815 -0600
+@@ -234,7 +234,7 @@
+ 		  || l->l_info[DT_FINI] != NULL)
+ 		{
+ 		  /* When debugging print a message first.  */
+-		  if (__builtin_expect (GLRO(dl_debug_mask)
++		  if (__builtin_expect (GLRO_dl_debug_mask
+ 					& DL_DEBUG_IMPCALLS, 0))
+ 		    _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+ 				      DSO_FILENAME (l->l_name),
+@@ -286,7 +286,7 @@
+       goto again;
+     }
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
+     _dl_debug_printf ("\nruntime linker statistics:\n"
+ 		      "           final number of relocations: %lu\n"
+ 		      "final number of relocations from cache: %lu\n",
+diff -Naur glibc-2.20/elf/dl-init.c glibc-2.20-rtld-debug/elf/dl-init.c
+--- glibc-2.20/elf/dl-init.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-init.c	2015-02-19 04:00:31.554729815 -0600
+@@ -52,7 +52,7 @@
+     return;
+ 
+   /* Print a debug message if wanted.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+     _dl_debug_printf ("\ncalling init: %s\n\n",
+ 		      DSO_FILENAME (l->l_name));
+ 
+@@ -102,7 +102,7 @@
+       ElfW(Addr) *addrs;
+       unsigned int cnt;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+ 	_dl_debug_printf ("\ncalling preinit: %s\n\n",
+ 			  DSO_FILENAME (main_map->l_name));
+ 
+diff -Naur glibc-2.20/elf/dl-load.c glibc-2.20-rtld-debug/elf/dl-load.c
+--- glibc-2.20/elf/dl-load.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-load.c	2015-02-19 04:00:31.555729814 -0600
+@@ -957,7 +957,7 @@
+     }
+ 
+   /* Print debugging message.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("file=%s [%lu];  generating link map\n", name, nsid);
+ 
+   /* This is the ELF header.  We read it in `open_verify'.  */
+@@ -1361,7 +1361,7 @@
+ 
+   l->l_entry += l->l_addr;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("\
+   dynamic: 0x%0*lx  base: 0x%0*lx   size: 0x%0*Zx\n\
+     entry: 0x%0*lx  phdr: 0x%0*lx  phnum:   %*u\n\n",
+@@ -1787,7 +1787,7 @@
+ 
+       /* If we are debugging the search for libraries print the path
+ 	 now if it hasn't happened now.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)
+ 	  && current_what != this_dir->what)
+ 	{
+ 	  current_what = this_dir->what;
+@@ -1808,7 +1808,7 @@
+ 	     - buf);
+ 
+ 	  /* Print name we try if this is wanted.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	    _dl_debug_printf ("  trying file=%s\n", buf);
+ 
+ 	  fd = open_verify (buf, fbp, loader, whatcode, mode,
+@@ -1953,7 +1953,7 @@
+     }
+ 
+   /* Display information if we are debugging.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)
+       && loader != NULL)
+     _dl_debug_printf ((mode & __RTLD_CALLMAP) == 0
+ 		      ? "\nfile=%s [%lu];  needed by %s [%lu]\n"
+@@ -1995,7 +1995,7 @@
+ 
+       size_t namelen = strlen (name) + 1;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
+ 
+       fd = -1;
+@@ -2122,7 +2122,7 @@
+ 			&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
+ 
+       /* Add another newline when we are tracing the library loading.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("\n");
+     }
+   else
+@@ -2155,7 +2155,7 @@
+   if (__glibc_unlikely (fd == -1))
+     {
+       if (trace_mode
+-	  && __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0))
++	  && __glibc_likely ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) == 0))
+ 	{
+ 	  /* We haven't found an appropriate library.  But since we
+ 	     are only interested in the list of libraries this isn't
+diff -Naur glibc-2.20/elf/dl-lookup.c glibc-2.20-rtld-debug/elf/dl-lookup.c
+--- glibc-2.20/elf/dl-lookup.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-lookup.c	2015-02-19 04:00:31.551729823 -0600
+@@ -300,7 +300,7 @@
+ 	 hash table.  */
+       if (__glibc_unlikely (tab->size))
+ 	{
+-	  assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
++	  assert (GLRO_dl_debug_mask & DL_DEBUG_PRELINK);
+ 	  goto success;
+ 	}
+ #endif
+@@ -375,7 +375,7 @@
+ 	continue;
+ 
+       /* Print some debugging info if wanted.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS))
+ 	_dl_debug_printf ("symbol=%s;  lookup in file=%s [%lu]\n",
+ 			  undef_name, DSO_FILENAME (map->l_name),
+ 			  map->l_ns);
+@@ -698,7 +698,7 @@
+ 	}
+ 
+       /* Display information if we are debugging.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("\
+ \nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
+ 			  DSO_FILENAME (map->l_name),
+@@ -802,7 +802,7 @@
+     {
+       if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
+ 	  && skip_map == NULL
+-	  && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
++	  && !(GLRO_dl_debug_mask & DL_DEBUG_UNUSED))
+ 	{
+ 	  /* We could find no value for a strong reference.  */
+ 	  const char *reference_name = undef_map ? undef_map->l_name : "";
+@@ -873,7 +873,7 @@
+   if (__glibc_unlikely (current_value.m->l_used == 0))
+     current_value.m->l_used = 1;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask)
++  if (__glibc_unlikely (GLRO_dl_debug_mask
+ 			& (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK)))
+     _dl_debug_bindings (undef_name, undef_map, ref,
+ 			&current_value, version, type_class, protected);
+@@ -938,7 +938,7 @@
+ {
+   const char *reference_name = undef_map->l_name;
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
++  if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS)
+     {
+       _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
+ 			DSO_FILENAME (reference_name),
+@@ -952,7 +952,7 @@
+ 	_dl_debug_printf_c ("\n");
+     }
+ #ifdef SHARED
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++  if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+     {
+       int conflict = 0;
+       struct sym_val val = { NULL, NULL };
+diff -Naur glibc-2.20/elf/dl-object.c glibc-2.20-rtld-debug/elf/dl-object.c
+--- glibc-2.20/elf/dl-object.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-object.c	2015-02-19 04:00:31.555729814 -0600
+@@ -98,7 +98,7 @@
+   new->l_type = type;
+   /* If we set the bit now since we know it is never used we avoid
+      dirtying the cache line later.  */
+-  if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0)
++  if ((GLRO_dl_debug_mask & DL_DEBUG_UNUSED) == 0)
+     new->l_used = 1;
+   new->l_loader = loader;
+ #if NO_TLS_OFFSET != 0
+diff -Naur glibc-2.20/elf/dl-open.c glibc-2.20-rtld-debug/elf/dl-open.c
+--- glibc-2.20/elf/dl-open.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-open.c	2015-02-19 04:00:31.549729817 -0600
+@@ -147,7 +147,7 @@
+ 	  ns->_ns_main_searchlist->r_list[new_nlist++] = map;
+ 
+ 	  /* We modify the global scope.  Report this.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+ 	    _dl_debug_printf ("\nadd %s [%lu] to global scope\n",
+ 			      map->l_name, map->l_ns);
+ 	}
+@@ -243,7 +243,7 @@
+   if (__glibc_unlikely (new->l_searchlist.r_list != NULL))
+     {
+       /* Let the user know about the opencount.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ 			  new->l_name, new->l_ns, new->l_direct_opencount);
+ 
+@@ -294,7 +294,7 @@
+   LIBC_PROBE (map_complete, 3, args->nsid, r, new);
+ 
+   /* Print scope information.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+     _dl_show_scope (new, 0);
+ 
+   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
+@@ -511,7 +511,7 @@
+ 	}
+ 
+       /* Print scope information.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+ 	_dl_show_scope (imap, from_scope);
+     }
+ 
+@@ -584,7 +584,7 @@
+ #endif
+ 
+   /* Let the user know about the opencount.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ 		      new->l_name, new->l_ns, new->l_direct_opencount);
+ }
+diff -Naur glibc-2.20/elf/dl-reloc.c glibc-2.20-rtld-debug/elf/dl-reloc.c
+--- glibc-2.20/elf/dl-reloc.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-reloc.c	2015-02-19 04:00:31.556729815 -0600
+@@ -183,7 +183,7 @@
+       && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
+     lazy = 0;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
+     _dl_debug_printf ("\nrelocation processing: %s%s\n",
+ 		      DSO_FILENAME (l->l_name), lazy ? " (lazy)" : "");
+ 
+diff -Naur glibc-2.20/elf/dl-version.c glibc-2.20-rtld-debug/elf/dl-version.c
+--- glibc-2.20/elf/dl-version.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/dl-version.c	2015-02-19 04:00:31.556729815 -0600
+@@ -82,7 +82,7 @@
+   int result = 0;
+ 
+   /* Display information about what we are doing while debugging.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_VERSIONS))
+     _dl_debug_printf ("\
+ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
+ 		      string, DSO_FILENAME (map->l_name),
+diff -Naur glibc-2.20/elf/get-dynamic-info.h glibc-2.20-rtld-debug/elf/get-dynamic-info.h
+--- glibc-2.20/elf/get-dynamic-info.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-rtld-debug/elf/get-dynamic-info.h	2015-02-19 04:00:31.551729823 -0600
+@@ -157,7 +157,7 @@
+ 	 them. Therefore to avoid breaking existing applications the
+ 	 best we can do is add a warning during debugging with the
+ 	 intent of notifying the user of the problem.  */
+-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
++      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0)
+ 	  && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
+ 	_dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n",
+ 			  l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
+diff -Naur glibc-2.20/elf/rtld.c glibc-2.20-rtld-debug/elf/rtld.c
+--- glibc-2.20/elf/rtld.c	2015-02-19 04:00:03.365732116 -0600
++++ glibc-2.20-rtld-debug/elf/rtld.c	2015-02-19 04:00:31.550729821 -0600
+@@ -321,7 +321,7 @@
+     }
+ #endif
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
+     {
+ #ifndef HP_TIMING_NONAVAIL
+       print_statistics (&rtld_total_time);
+@@ -1699,7 +1699,7 @@
+ 	 after relocation.  */
+       struct link_map *l;
+ 
+-      if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++      if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+ 	{
+ 	  struct r_scope_elem *scope = &main_map->l_searchlist;
+ 
+@@ -1729,7 +1729,7 @@
+ 		_dl_printf ("\n");
+ 	    }
+ 	}
+-      else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
++      else if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
+ 	{
+ 	  /* Look through the dependencies of the main executable
+ 	     and determine which of them is not actually
+@@ -1837,7 +1837,7 @@
+ 		    }
+ 		}
+ 
+-	      if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++	      if ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+ 		  && rtld_multiple_ref)
+ 		{
+ 		  /* Mark the link map as not yet relocated again.  */
+@@ -1970,7 +1970,7 @@
+       if (r_list == r_listend && liblist == liblistend)
+ 	prelinked = true;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("\nprelink checking: %s\n",
+ 			  prelinked ? "ok" : "failed");
+     }
+@@ -1988,7 +1988,7 @@
+   GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
+ 
+   /* Print scope information.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+     {
+       _dl_debug_printf ("\nInitial object scopes\n");
+ 
+@@ -2262,7 +2262,7 @@
+ 	    if (debopts[cnt].len == len
+ 		&& memcmp (dl_debug, debopts[cnt].name, len) == 0)
+ 	      {
+-		GLRO(dl_debug_mask) |= debopts[cnt].mask;
++		GLRO_dl_debug_mask |= debopts[cnt].mask;
+ 		any_debug = 1;
+ 		break;
+ 	      }
+@@ -2283,7 +2283,7 @@
+       ++dl_debug;
+     }
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
++  if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
+     {
+       /* In order to get an accurate picture of whether a particular
+ 	 DT_NEEDED entry is actually used we have to process both
+@@ -2291,7 +2291,7 @@
+       GLRO(dl_lazy) = 0;
+     }
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_HELP)
++  if (GLRO_dl_debug_mask & DL_DEBUG_HELP)
+     {
+       size_t cnt;
+ 
+@@ -2490,7 +2490,7 @@
+ 	    {
+ 	      mode = trace;
+ 	      GLRO(dl_verbose) = 1;
+-	      GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
++	      GLRO_dl_debug_mask |= DL_DEBUG_PRELINK;
+ 	      GLRO(dl_trace_prelink) = &envline[17];
+ 	    }
+ 	  break;
+@@ -2537,7 +2537,7 @@
+       if (__access ("/etc/suid-debug", F_OK) != 0)
+ 	{
+ 	  unsetenv ("MALLOC_CHECK_");
+-	  GLRO(dl_debug_mask) = 0;
++	  GLRO_dl_debug_mask = 0;
+ 	}
+ 
+       if (mode != normal)
diff --git a/recipes-core/glibc/glibc-fsl/00xx.glibc.use-option-groups.patch b/recipes-core/glibc/glibc-fsl/00xx.glibc.use-option-groups.patch
new file mode 100755
index 0000000..9ba413e
--- /dev/null
+++ b/recipes-core/glibc/glibc-fsl/00xx.glibc.use-option-groups.patch
@@ -0,0 +1,16551 @@
+# Problem Statement:
+  Forward port eglibc options groups support to glibc v2.20
+
+# Referred from patch by:
+  Yocto Project
+  http://git.yoctoproject.org/cgit.cgi/poky/plain/meta/recipes-core/glibc/glibc/eglibc-use-option-groups.patch
+  Upstream-Status: Pending
+
+  * Updated patch to fix glibc test suite failures.
+
+diff -Naur glibc-2.20/argp/argp-fmtstream.c glibc-2.20-patch/argp/argp-fmtstream.c
+--- glibc-2.20/argp/argp-fmtstream.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/argp/argp-fmtstream.c	2015-03-04 00:51:32.366952005 -0600
+@@ -42,6 +42,7 @@
+ #ifdef _LIBC
+ # include <wchar.h>
+ # include <libio/libioP.h>
++# include <gnu/option-groups.h>
+ # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
+ #endif
+ 
+@@ -100,7 +101,11 @@
+   __argp_fmtstream_update (fs);
+   if (fs->p > fs->buf)
+     {
++#ifdef _LIBC
+       __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
++#else
++      fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
++#endif
+     }
+   free (fs->buf);
+   free (fs);
+@@ -145,9 +150,17 @@
+ 	      size_t i;
+ 	      for (i = 0; i < pad; i++)
+ 		{
++#ifdef _LIBC
+ 		  if (_IO_fwide (fs->stream, 0) > 0)
+-		    putwc_unlocked (L' ', fs->stream);
++                    {
++#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++                      putwc_unlocked (L' ', fs->stream);
++#else
++                      abort ();
++#endif
++                    }
+ 		  else
++#endif
+ 		    putc_unlocked (' ', fs->stream);
+ 		}
+ 	    }
+@@ -308,9 +321,17 @@
+ 	      *nl++ = ' ';
+ 	  else
+ 	    for (i = 0; i < fs->wmargin; ++i)
++#ifdef _LIBC
+ 	      if (_IO_fwide (fs->stream, 0) > 0)
+-		putwc_unlocked (L' ', fs->stream);
++                {
++#ifdef OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++                  putwc_unlocked (L' ', fs->stream);
++#else
++                  abort ();
++#endif
++                }
+ 	      else
++#endif
+ 		putc_unlocked (' ', fs->stream);
+ 
+ 	  /* Copy the tail of the original buffer into the current buffer
+diff -Naur glibc-2.20/argp/argp-help.c glibc-2.20-patch/argp/argp-help.c
+--- glibc-2.20/argp/argp-help.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/argp/argp-help.c	2015-03-04 00:51:32.366952005 -0600
+@@ -51,6 +51,7 @@
+ #ifdef _LIBC
+ # include <../libio/libioP.h>
+ # include <wchar.h>
++# include <gnu/option-groups.h>
+ #endif
+ 
+ #ifndef _
+@@ -1702,7 +1703,7 @@
+ }
+ 
+ char *
+-__argp_short_program_name (void)
++(__argp_short_program_name) (void)
+ {
+ # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+   return program_invocation_short_name;
+@@ -1873,9 +1874,17 @@
+ #endif
+ 	    }
+ 
++#ifdef _LIBC
+ 	  if (_IO_fwide (stream, 0) > 0)
+-	    putwc_unlocked (L'\n', stream);
++            {
++#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++              putwc_unlocked (L'\n', stream);
++#else
++              abort ();
++#endif
++            }
+ 	  else
++#endif
+ 	    putc_unlocked ('\n', stream);
+ 
+ #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+diff -Naur glibc-2.20/argp/argp-namefrob.h glibc-2.20-patch/argp/argp-namefrob.h
+--- glibc-2.20/argp/argp-namefrob.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/argp/argp-namefrob.h	2015-03-04 00:51:32.366952005 -0600
+@@ -76,10 +76,12 @@
+ #undef __argp_fmtstream_wmargin
+ #define __argp_fmtstream_wmargin argp_fmtstream_wmargin
+ 
++#if 0
+ #include "mempcpy.h"
+ #include "strcase.h"
+ #include "strchrnul.h"
+ #include "strndup.h"
++#endif
+ 
+ /* normal libc functions we call */
+ #undef __flockfile
+diff -Naur glibc-2.20/argp/Makefile glibc-2.20-patch/argp/Makefile
+--- glibc-2.20/argp/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/argp/Makefile	2015-03-04 00:51:32.366952005 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for argp.
+ #
++include ../option-groups.mak
++
+ subdir	:= argp
+ 
+ include ../Makeconfig
+diff -Naur glibc-2.20/catgets/Makefile glibc-2.20-patch/catgets/Makefile
+--- glibc-2.20/catgets/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/catgets/Makefile	2015-03-04 00:51:32.367952004 -0600
+@@ -22,20 +22,23 @@
+ 
+ include ../Makeconfig
+ 
++include ../option-groups.mak
++
+ headers		= nl_types.h
+-routines	= catgets open_catalog
+-others		= gencat
+-install-bin	= gencat
+-extra-objs	= $(gencat-modules:=.o)
++routines-$(OPTION_EGLIBC_CATGETS)    := catgets open_catalog
++others-$(OPTION_EGLIBC_CATGETS)      := gencat
++install-bin-$(OPTION_EGLIBC_CATGETS) := gencat
++extra-objs-$(OPTION_EGLIBC_CATGETS)  := $(gencat-modules:=.o)
+ 
+-tests = tst-catgets
+-test-srcs = test-gencat
++tests-$(OPTION_EGLIBC_CATGETS)       := tst-catgets
++test-srcs-$(OPTION_EGLIBC_CATGETS)   := test-gencat
+ 
++ifeq (y,$(OPTION_EGLIBC_CATGETS))
+ ifeq ($(run-built-tests),yes)
+ tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
+ 		 $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out
+ endif
+-
++endif
+ gencat-modules	= xmalloc
+ 
+ # To find xmalloc.c
+diff -Naur glibc-2.20/crypt/crypt_common.c glibc-2.20-patch/crypt/crypt_common.c
+--- glibc-2.20/crypt/crypt_common.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/crypt/crypt_common.c	2015-03-04 00:51:32.367952004 -0600
+@@ -0,0 +1,42 @@
++/*
++ * crypt: crypt(3) implementation
++ *
++ * Copyright (C) 1991-2014 Free Software Foundation, Inc.
++ *
++ * This 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.
++ *
++ * This 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 this library; see the file COPYING.LIB.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * General Support routines
++ *
++ */
++
++#include "crypt-private.h"
++
++/* Table with characters for base64 transformation.  */
++static const char b64t[64] =
++"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
++
++void
++__b64_from_24bit (char **cp, int *buflen,
++		  unsigned int b2, unsigned int b1, unsigned int b0,
++		  int n)
++{
++  unsigned int w = (b2 << 16) | (b1 << 8) | b0;
++  while (n-- > 0 && (*buflen) > 0)
++    {
++      *(*cp)++ = b64t[w & 0x3f];
++      --(*buflen);
++      w >>= 6;
++    }
++}
+diff -Naur glibc-2.20/crypt/crypt-entry.c glibc-2.20-patch/crypt/crypt-entry.c
+--- glibc-2.20/crypt/crypt-entry.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/crypt/crypt-entry.c	2015-03-04 00:51:32.367952004 -0600
+@@ -27,6 +27,7 @@
+ #include <stdio.h>
+ #endif
+ #include <string.h>
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <fips-private.h>
+ 
+@@ -76,9 +77,11 @@
+      const char *salt;
+      struct crypt_data * __restrict data;
+ {
++#if __OPTION_EGLIBC_CRYPT_UFC
+   ufc_long res[4];
+   char ktab[9];
+   ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
++#endif /*__OPTION_EGLIBC_CRYPT_UFC*/
+ 
+ #ifdef _LIBC
+   /* Try to find out whether we have to use MD5 encryption replacement.  */
+@@ -105,6 +108,7 @@
+ 			     sizeof (struct crypt_data));
+ #endif
+ 
++#if __OPTION_EGLIBC_CRYPT_UFC
+   /*
+    * Hack DES tables according to salt
+    */
+@@ -144,6 +148,10 @@
+    */
+   _ufc_output_conversion_r (res[0], res[1], salt, data);
+   return data->crypt_3_buf;
++#else /* __OPTION_EGLIBC_CRYPT_UFC */
++  __set_errno (ENOSYS);
++  return NULL;
++#endif /* __OPTION_EGLIBC_CRYPT_UFC */
+ }
+ weak_alias (__crypt_r, crypt_r)
+ 
+@@ -168,7 +176,12 @@
+     return __sha512_crypt (key, salt);
+ #endif
+ 
++#if __OPTION_EGLIBC_CRYPT_UFC
+   return __crypt_r (key, salt, &_ufc_foobar);
++#else /* __OPTION_EGLIBC_CRYPT_UFC */
++  __set_errno (ENOSYS);
++  return NULL;
++#endif /* __OPTION_EGLIBC_CRYPT_UFC */
+ }
+ 
+ 
+diff -Naur glibc-2.20/crypt/crypt_util.c glibc-2.20-patch/crypt/crypt_util.c
+--- glibc-2.20/crypt/crypt_util.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/crypt/crypt_util.c	2015-03-04 00:51:32.367952004 -0600
+@@ -242,10 +242,6 @@
+  */
+ static ufc_long efp[16][64][2];
+ 
+-/* Table with characters for base64 transformation.  */
+-static const char b64t[64] =
+-"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+-
+ /*
+  * For use by the old, non-reentrant routines
+  * (crypt/encrypt/setkey)
+@@ -949,17 +945,3 @@
+ {
+   __setkey_r(__key, &_ufc_foobar);
+ }
+-
+-void
+-__b64_from_24bit (char **cp, int *buflen,
+-		  unsigned int b2, unsigned int b1, unsigned int b0,
+-		  int n)
+-{
+-  unsigned int w = (b2 << 16) | (b1 << 8) | b0;
+-  while (n-- > 0 && (*buflen) > 0)
+-    {
+-      *(*cp)++ = b64t[w & 0x3f];
+-      --(*buflen);
+-      w >>= 6;
+-    }
+-}
+diff -Naur glibc-2.20/crypt/Makefile glibc-2.20-patch/crypt/Makefile
+--- glibc-2.20/crypt/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/crypt/Makefile	2015-03-04 00:51:32.367952004 -0600
+@@ -18,21 +18,25 @@
+ #
+ #	Sub-makefile for crypt() portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= crypt
+ 
+ include ../Makeconfig
+ 
+ headers := crypt.h
+ 
+-extra-libs := libcrypt
+-extra-libs-others := $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_CRYPT) := libcrypt
++extra-libs-others-y := $(extra-libs-y)
+ 
+-libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
+-		     crypt_util
++libcrypt-routines :=crypt-entry  md5-crypt sha256-crypt sha512-crypt crypt_common
++libcrypt-routines-$(OPTION_EGLIBC_CRYPT_UFC) := crypt crypt_util
++libcrypt-routines += $(libcrypt-routines-y)
+ 
+-tests := cert md5c-test sha256c-test sha512c-test badsalttest
++tests-$(OPTION_EGLIBC_CRYPT) := md5c-test sha256c-test sha512c-test badsalttest
++tests-$(OPTION_EGLIBC_CRYPT_UFC) += cert
+ 
+-ifeq ($(crypt-in-libc),yes)
++ifeq ($(crypt-in-libc)$(OPTION_EGLIBC_CRYPT),yesy)
+ routines += $(libcrypt-routines)
+ endif
+ 
+@@ -44,7 +48,7 @@
+ else
+ libcrypt-routines += md5 sha256 sha512
+ 
+-tests += md5test sha256test sha512test
++tests-$(OPTION_EGLIBC_CRYPT) += md5test sha256test sha512test
+ 
+ # The test md5test-giant uses up to 400 MB of RSS and runs on a fast
+ # machine over a minute.
+@@ -64,8 +68,10 @@
+ $(objpfx)sha512test: $(patsubst %, $(objpfx)%.o,$(sha512-routines))
+ endif
+ 
++ifeq ($(OPTION_EGLIBC_CRYPT),y)
+ ifeq (yes,$(build-shared))
+ $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so
+ else
+ $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a
+ endif
++endif # eglibc: OPTION_EGLIBC_CRYPT
+diff -Naur glibc-2.20/csu/Makefile glibc-2.20-patch/csu/Makefile
+--- glibc-2.20/csu/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/csu/Makefile	2015-03-04 00:51:32.368952005 -0600
+@@ -22,6 +22,8 @@
+ # crtn.o, special "initializer" and "finalizer" files used in the link
+ # to make the .init and .fini sections work right.
+ 
++include ../option-groups.mak
++
+ subdir := csu
+ 
+ include ../Makeconfig
+diff -Naur glibc-2.20/debug/Makefile glibc-2.20-patch/debug/Makefile
+--- glibc-2.20/debug/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/debug/Makefile	2015-03-04 00:51:32.368952005 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for debug portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= debug
+ 
+ include ../Makeconfig
+@@ -27,7 +29,7 @@
+ # Note that ptsname_r_chk and getlogin_r are not here, but in
+ # login/Makefile instead.  If that subdir is omitted from the
+ # build, its _FORTIFY_SOURCE support will be too.
+-routines  = backtrace backtracesyms backtracesymsfd noophooks \
++routines  = noophooks \
+ 	    memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
+ 	    strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \
+ 	    sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
+@@ -36,20 +38,27 @@
+ 	    read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
+ 	    readlink_chk readlinkat_chk getwd_chk getcwd_chk \
+ 	    realpath_chk fread_chk fread_u_chk \
+-	    wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
+-	    wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
+-	    wcpncpy_chk \
+-	    swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \
+-	    vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \
+ 	    confstr_chk getgroups_chk ttyname_r_chk \
+-	    gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \
+-	    wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
+-	    wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \
++	    gethostname_chk getdomainname_chk \
++	    asprintf_chk vasprintf_chk dprintf_chk \
+ 	    vdprintf_chk obprintf_chk \
+ 	    longjmp_chk ____longjmp_chk \
+ 	    fdelt_chk poll_chk ppoll_chk \
+ 	    stack_chk_fail fortify_fail \
+ 	    $(static-only-routines)
++routines-$(OPTION_EGLIBC_BACKTRACE) += backtrace backtracesyms backtracesymsfd
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)			\
++	 += wprintf_chk fwprintf_chk				\
++	    vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR)				\
++	 += wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk	\
++	    wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk	\
++	    wcpncpy_chk							\
++	    swprintf_chk vswprintf_chk					\
++	    wcrtomb_chk mbsnrtowcs_chk					\
++	    wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk	\
++	    wcstombs_chk
++
+ static-only-routines := warning-nop stack_chk_fail_local
+ 
+ CFLAGS-backtrace.c = -fno-omit-frame-pointer
+@@ -129,11 +138,15 @@
+ LDFLAGS-tst-backtrace5 = -rdynamic
+ LDFLAGS-tst-backtrace6 = -rdynamic
+ 
+-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
+-	tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
+-	tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
+-	tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
+-	tst-backtrace5 tst-backtrace6
++tests = tst-longjmp_chk test-strcpy_chk test-stpcpy_chk tst-longjmp_chk2
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++      += tst-chk1 tst-chk2 tst-chk3 tst-lfschk1 tst-lfschk2 tst-lfschk3
++tests-$(OPTION_EGLIBC_BACKTRACE) \
++      += backtrace-tst tst-backtrace2 tst-backtrace3 tst-backtrace4 \
++         tst-backtrace5 tst-backtrace6
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_EGLIBC_CXX_TESTS))
++tests += tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6
++endif
+ 
+ tests-ifunc := $(stpcpy_chk strcpy_chk:%=test-%-ifunc)
+ tests += $(tests-ifunc)
+diff -Naur glibc-2.20/debug/segfault.c glibc-2.20-patch/debug/segfault.c
+--- glibc-2.20/debug/segfault.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/debug/segfault.c	2015-03-04 00:51:32.368952005 -0600
+@@ -30,6 +30,7 @@
+ #include <unistd.h>
+ #include <_itoa.h>
+ #include <ldsodefs.h>
++#include <gnu/option-groups.h>
+ 
+ /* This file defines macros to access the content of the sigcontext element
+    passed up by the signal handler.  */
+@@ -91,6 +92,7 @@
+   REGISTER_DUMP;
+ #endif
+ 
++#if __OPTION_EGLIBC_BACKTRACE
+   WRITE_STRING ("\nBacktrace:\n");
+ 
+   /* Get the backtrace.  */
+@@ -113,6 +115,7 @@
+ 
+   /* Now generate nicely formatted output.  */
+   __backtrace_symbols_fd (arr + i, cnt - i, fd);
++#endif
+ 
+ #ifdef HAVE_PROC_SELF
+   /* Now the link map.  */
+diff -Naur glibc-2.20/debug/tst-chk1.c glibc-2.20-patch/debug/tst-chk1.c
+--- glibc-2.20/debug/tst-chk1.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/debug/tst-chk1.c	2015-03-04 00:51:32.368952005 -0600
+@@ -31,6 +31,7 @@
+ #include <sys/select.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ #define obstack_chunk_alloc malloc
+@@ -307,6 +308,7 @@
+   snprintf (buf + 8, l0 + 3, "%d", num2);
+   CHK_FAIL_END
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   CHK_FAIL_START
+   swprintf (wbuf + 8, 3, L"%d", num1);
+   CHK_FAIL_END
+@@ -314,6 +316,7 @@
+   CHK_FAIL_START
+   swprintf (wbuf + 8, l0 + 3, L"%d", num1);
+   CHK_FAIL_END
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ # endif
+ 
+   memcpy (buf, str1 + 2, l0 + 9);
+@@ -381,6 +384,7 @@
+   CHK_FAIL_END
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+ 
+   /* These ops can be done without runtime checking of object size.  */
+   wmemcpy (wbuf, L"abcdefghij", 10);
+@@ -605,6 +609,7 @@
+   CHK_FAIL_END
+ #endif
+ 
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   /* Now checks for %n protection.  */
+ 
+@@ -1192,6 +1197,7 @@
+ # endif
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
+     {
+       assert (MB_CUR_MAX <= 10);
+@@ -1348,6 +1354,7 @@
+       puts ("cannot set locale");
+       ret = 1;
+     }
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   int fd = posix_openpt (O_RDWR);
+   if (fd != -1)
+diff -Naur glibc-2.20/dlfcn/Makefile glibc-2.20-patch/dlfcn/Makefile
+--- glibc-2.20/dlfcn/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/dlfcn/Makefile	2015-03-04 00:51:32.368952005 -0600
+@@ -15,6 +15,8 @@
+ # License along with the GNU C Library; if not, see
+ # <http://www.gnu.org/licenses/>.
+ 
++include ../option-groups.mak
++
+ subdir		:= dlfcn
+ 
+ include ../Makeconfig
+@@ -36,14 +38,20 @@
+ ifeq (yes,$(build-shared))
+ tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
+ 	bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
+-	bug-atexit3 tstatexit bug-dl-leaf
++	tstatexit bug-dl-leaf
++
++tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3
+ endif
+ modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
+ 		defaultmod2 errmsg1mod modatexit modcxaatexit \
+ 		bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
+-		bug-atexit2-lib bug-atexit3-lib bug-dl-leaf-lib \
++		bug-atexit2-lib bug-dl-leaf-lib \
+ 		bug-dl-leaf-lib-cb
+ 
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++modules-names += bug-atexit3-lib
++endif
++
+ failtestmod.so-no-z-defs = yes
+ glreflib2.so-no-z-defs = yes
+ errmsg1mod.so-no-z-defs = yes
+diff -Naur glibc-2.20/elf/dl-support.c glibc-2.20-patch/elf/dl-support.c
+--- glibc-2.20/elf/dl-support.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/elf/dl-support.c	2015-03-04 00:51:32.369952006 -0600
+@@ -19,6 +19,7 @@
+ /* This file defines some things that for the dynamic linker are defined in
+    rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */
+ 
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <libintl.h>
+ #include <stdlib.h>
+@@ -42,7 +43,9 @@
+ const char *_dl_platform;
+ size_t _dl_platformlen;
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ int _dl_debug_mask;
++#endif
+ int _dl_lazy;
+ ElfW(Addr) _dl_use_load_bias = -2;
+ int _dl_dynamic_weak;
+diff -Naur glibc-2.20/elf/Makefile glibc-2.20-patch/elf/Makefile
+--- glibc-2.20/elf/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/elf/Makefile	2015-03-04 00:51:32.369952006 -0600
+@@ -17,6 +17,8 @@
+ 
+ # Makefile for elf subdirectory of GNU C Library.
+ 
++include ../option-groups.mak
++
+ subdir		:= elf
+ 
+ include ../Makeconfig
+@@ -144,10 +146,11 @@
+ 	 unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
+ 	 tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
+ 	 tst-stackguard1 tst-addr1 tst-thrlock \
+-	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
++	 tst-unique1 tst-unique2 \
+ 	 tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
+ 	 tst-ptrguard1
+ #	 reldep9
++tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-unique3 tst-unique4
+ ifeq ($(build-hardcoded-path-in-tests),yes)
+ tests += tst-dlopen-aout
+ endif
+@@ -205,8 +208,6 @@
+ 		tst-unique1mod1 tst-unique1mod2 \
+ 		tst-unique2mod1 tst-unique2mod2 \
+ 		tst-auditmod9a tst-auditmod9b \
+-		tst-unique3lib tst-unique3lib2 \
+-		tst-unique4lib \
+ 		tst-initordera1 tst-initorderb1 \
+ 		tst-initordera2 tst-initorderb2 \
+ 		tst-initordera3 tst-initordera4 \
+@@ -214,6 +215,9 @@
+ 		tst-initorder2d \
+ 		tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
+ 		tst-array5dep tst-null-argv-lib
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++modules-names += tst-unique3lib tst-unique3lib2 tst-unique4lib 
++endif
+ ifeq (yesyes,$(have-fpie)$(build-shared))
+ modules-names += tst-piemod1
+ tests += tst-pie1 tst-pie2
+diff -Naur glibc-2.20/elf/rtld.c glibc-2.20-patch/elf/rtld.c
+--- glibc-2.20/elf/rtld.c	2015-03-04 00:49:59.303952005 -0600
++++ glibc-2.20-patch/elf/rtld.c	2015-03-04 00:51:32.369952006 -0600
+@@ -16,6 +16,7 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <dlfcn.h>
+ #include <fcntl.h>
+@@ -2200,6 +2201,7 @@
+ 		    objname, errstring);
+ }
+ \f
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ /* Nonzero if any of the debugging options is enabled.  */
+ static int any_debug attribute_relro;
+ 
+@@ -2309,6 +2311,7 @@
+       _exit (0);
+     }
+ }
++#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
+ \f
+ static void
+ process_dl_audit (char *str)
+@@ -2376,12 +2379,14 @@
+ 	  break;
+ 
+ 	case 5:
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	  /* Debugging of the dynamic linker?  */
+ 	  if (memcmp (envline, "DEBUG", 5) == 0)
+ 	    {
+ 	      process_dl_debug (&envline[6]);
+ 	      break;
+ 	    }
++#endif
+ 	  if (memcmp (envline, "AUDIT", 5) == 0)
+ 	    process_dl_audit (&envline[6]);
+ 	  break;
+@@ -2490,7 +2495,9 @@
+ 	    {
+ 	      mode = trace;
+ 	      GLRO(dl_verbose) = 1;
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	      GLRO_dl_debug_mask |= DL_DEBUG_PRELINK;
++#endif
+ 	      GLRO(dl_trace_prelink) = &envline[17];
+ 	    }
+ 	  break;
+@@ -2537,12 +2544,15 @@
+       if (__access ("/etc/suid-debug", F_OK) != 0)
+ 	{
+ 	  unsetenv ("MALLOC_CHECK_");
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	  GLRO_dl_debug_mask = 0;
++#endif
+ 	}
+ 
+       if (mode != normal)
+ 	_exit (5);
+     }
++#if __OPTION_EGLIBC_RTLD_DEBUG
+   /* If we have to run the dynamic linker in debugging mode and the
+      LD_DEBUG_OUTPUT environment variable is given, we write the debug
+      messages to this file.  */
+@@ -2567,6 +2577,7 @@
+ 	/* We use standard output if opening the file failed.  */
+ 	GLRO(dl_debug_fd) = STDOUT_FILENO;
+     }
++#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
+ }
+ 
+ 
+diff -Naur glibc-2.20/extra-lib.mk glibc-2.20-patch/extra-lib.mk
+--- glibc-2.20/extra-lib.mk	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/extra-lib.mk	2015-03-04 00:51:32.370952006 -0600
+@@ -25,7 +25,9 @@
+ extra-objs := $(extra-objs)
+ 
+ # The modules that go in $(lib).
+-all-$(lib)-routines := $($(lib)-routines) $($(lib)-sysdep_routines)
++all-$(lib)-routines := $($(lib)-routines)		\
++	               $($(lib)-routines-y)		\
++		       $($(lib)-sysdep_routines)
+ 
+ # Add each flavor of library to the lists of things to build and install.
+ install-lib += $(foreach o,$(object-suffixes-$(lib)),$(lib:lib%=$(libtype$o)))
+@@ -101,7 +103,7 @@
+ endif
+ 
+ # This will define `libof-ROUTINE := LIB' for each of the routines.
+-cpp-srcs-left := $($(lib)-routines) $($(lib)-sysdep_routines)
++cpp-srcs-left := $(all-$(lib)-routines)
+ ifneq (,$(cpp-srcs-left))
+ include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
+ endif
+diff -Naur glibc-2.20/grp/Makefile glibc-2.20-patch/grp/Makefile
+--- glibc-2.20/grp/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/grp/Makefile	2015-03-04 00:51:32.370952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for grp portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= grp
+ 
+ include ../Makeconfig
+@@ -29,6 +31,9 @@
+ 	    getgrent_r getgrgid_r getgrnam_r fgetgrent_r
+ 
+ tests := testgrp
++ifneq (y,$(OPTION_EGLIBC_NSSWITCH))
++LDLIBS-testgrp += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
++endif
+ 
+ ifeq (yes,$(build-shared))
+ test-srcs :=  tst_fgetgrent
+diff -Naur glibc-2.20/hesiod/Makefile glibc-2.20-patch/hesiod/Makefile
+--- glibc-2.20/hesiod/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/hesiod/Makefile	2015-03-04 00:51:32.370952006 -0600
+@@ -18,12 +18,14 @@
+ #
+ #	Sub-makefile for hesiod portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= hesiod
+ 
+ include ../Makeconfig
+ 
+-extra-libs := libnss_hesiod
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_INET) += libnss_hesiod
++extra-libs-others-y += $(extra-libs-y)
+ 
+ subdir-dirs = nss_hesiod
+ vpath %.c nss_hesiod
+diff -Naur glibc-2.20/iconv/gconv_db.c glibc-2.20-patch/iconv/gconv_db.c
+--- glibc-2.20/iconv/gconv_db.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/iconv/gconv_db.c	2015-03-04 00:51:32.370952006 -0600
+@@ -25,6 +25,7 @@
+ #include <sys/param.h>
+ #include <bits/libc-lock.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ 
+ #include <dlfcn.h>
+ #include <gconv_int.h>
+@@ -828,9 +829,11 @@
+ /* Free all resources if necessary.  */
+ libc_freeres_fn (free_mem)
+ {
++#if __OPTION_EGLIBC_LOCALE_CODE
+   /* First free locale memory.  This needs to be done before freeing derivations,
+      as ctype cleanup functions dereference steps arrays which we free below.  */
+   _nl_locale_subfreeres ();
++#endif
+ 
+   /* finddomain.c has similar problem.  */
+   extern void _nl_finddomain_subfreeres (void) attribute_hidden;
+diff -Naur glibc-2.20/iconv/gconv_trans.c glibc-2.20-patch/iconv/gconv_trans.c
+--- glibc-2.20/iconv/gconv_trans.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/iconv/gconv_trans.c	2015-03-04 00:51:32.370952006 -0600
+@@ -23,6 +23,7 @@
+ #include <stdint.h>
+ #include <string.h>
+ #include <stdlib.h>
++#include <gnu/option-groups.h>
+ 
+ #include <bits/libc-lock.h>
+ #include "gconv_int.h"
+@@ -59,6 +60,7 @@
+     PTR_DEMANGLE (fct);
+ #endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   /* If there is no transliteration information in the locale don't do
+      anything and return the error.  */
+   size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_TAB_SIZE);
+@@ -194,6 +196,7 @@
+              sorted.  */
+ 	  break;
+     }
++#endif
+ 
+   /* One last chance: use the default replacement.  */
+   if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN) != 0)
+diff -Naur glibc-2.20/iconv/iconv_prog.c glibc-2.20-patch/iconv/iconv_prog.c
+--- glibc-2.20/iconv/iconv_prog.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/iconv/iconv_prog.c	2015-03-04 00:51:32.371952006 -0600
+@@ -35,6 +35,7 @@
+ #ifdef _POSIX_MAPPED_FILES
+ # include <sys/mman.h>
+ #endif
++#include <gnu/option-groups.h>
+ #include <charmap.h>
+ #include <gconv_int.h>
+ #include "iconv_prog.h"
+@@ -221,10 +222,17 @@
+ 	      bool to_wrong =
+ 		(iconv_open (to_code, "UTF-8") == (iconv_t) -1
+ 		 && errno == EINVAL);
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	      const char *from_pretty =
+ 		(from_code[0] ? from_code : nl_langinfo (CODESET));
+ 	      const char *to_pretty =
+ 		(orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET));
++#else
++	      const char *from_pretty =
++		(from_code[0] ? from_code : "ANSI_X3.4-1968");
++	      const char *to_pretty =
++                 (orig_to_code[0] ? orig_to_code : "ANSI_X3.4-1968");
++#endif
+ 
+ 	      if (from_wrong)
+ 		{
+diff -Naur glibc-2.20/iconv/Makefile glibc-2.20-patch/iconv/Makefile
+--- glibc-2.20/iconv/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/iconv/Makefile	2015-03-04 00:51:32.371952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for iconv.
+ #
++include ../option-groups.mak
++
+ subdir	:= iconv
+ 
+ include ../Makeconfig
+@@ -57,6 +59,9 @@
+ CPPFLAGS-strtab = -DNOT_IN_libc
+ CPPFLAGS-charmap = -DNOT_IN_libc
+ CPPFLAGS-charmap-dir = -DNOT_IN_libc
++ifneq (y,$(OPTION_EGLIBC_SPAWN))
++CPPFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
++endif
+ 
+ ifeq ($(run-built-tests),yes)
+ xtests-special += $(objpfx)test-iconvconfig.out
+diff -Naur glibc-2.20/iconvdata/Makefile glibc-2.20-patch/iconvdata/Makefile
+--- glibc-2.20/iconvdata/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/iconvdata/Makefile	2015-03-04 00:51:32.371952006 -0600
+@@ -18,12 +18,15 @@
+ #
+ #	Makefile for iconv data and code.
+ #
++include ../option-groups.mak
++
+ subdir	:= iconvdata
+ 
+ include ../Makeconfig
+ 
+ # Names of all the shared objects which implement the transformations.
+-modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
++modules-$(OPTION_EGLIBC_CHARSETS)					 \
++	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
+ 	   ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10		 \
+ 	   ISO8859-11 ISO8859-13 ISO8859-14 ISO8859-15 ISO8859-16	 \
+ 	   T.61 ISO_6937 SJIS KOI-8 HP-ROMAN8 HP-ROMAN9 EBCDIC-AT-DE	 \
+@@ -63,11 +66,13 @@
+ 	   MAC-CENTRALEUROPE KOI8-RU ISO8859-9E				 \
+ 	   CP770 CP771 CP772 CP773 CP774
+ 
+-modules.so := $(addsuffix .so, $(modules))
++modules.so := $(addsuffix .so, $(modules-y))
+ 
+ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+-	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9
++	tst-iconv6 bug-iconv5 bug-iconv8 bug-iconv9
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += bug-iconv6 tst-iconv7
++
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -130,13 +135,13 @@
+ # Rule to generate the shared objects.
+ charmaps = ../localedata/charmaps
+ -include $(objpfx)iconv-rules
+-extra-modules-left := $(modules)
++extra-modules-left := $(modules-y)
+ include extra-module.mk
+ 
+ 
+ extra-objs	+= $(modules.so)
+-install-others	= $(addprefix $(inst_gconvdir)/, $(modules.so))	\
+-		  $(inst_gconvdir)/gconv-modules
++install-others-y += $(addprefix $(inst_gconvdir)/, $(modules.so))
++install-others-$(OPTION_EGLIBC_CHARSETS) += $(inst_gconvdir)/gconv-modules
+ 
+ # We can build the conversion tables for numerous charsets automatically.
+ 
+@@ -204,7 +209,7 @@
+ ifndef avoid-generated
+ $(objpfx)iconv-rules: Makefile
+ 	$(make-target-directory)
+-	{ echo $(filter-out lib%, $(modules)); \
++	{ echo $(filter-out lib%, $(modules-y)); \
+ 	  echo 8bit $(gen-8bit-modules); \
+ 	  echo 8bit-gap $(gen-8bit-gap-modules); } | \
+ 	LC_ALL=C \
+@@ -247,7 +252,7 @@
+ 	$(do-install-program)
+ $(inst_gconvdir)/gconv-modules: gconv-modules $(+force)
+ 	$(do-install)
+-ifeq (no,$(cross-compiling))
++# eglibc: ifeq (no,$(cross-compiling))
+ # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
+ # if this libc has more gconv modules than the previously installed one.
+ 	if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \
+@@ -256,9 +261,9 @@
+ 	   $(common-objpfx)iconv/iconvconfig \
+ 	     $(addprefix --prefix=,$(install_root)); \
+ 	fi
+-else
+-	@echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
+-endif
++# eglibc: else
++# eglibc:	@echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
++# eglibc: endif
+ 
+ endif # build-shared = yes
+ 
+diff -Naur glibc-2.20/include/libc-symbols.h glibc-2.20-patch/include/libc-symbols.h
+--- glibc-2.20/include/libc-symbols.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/include/libc-symbols.h	2015-03-04 00:51:32.371952006 -0600
+@@ -60,8 +60,7 @@
+ /* Define these macros for the benefit of portable GNU code that wants to check
+    them.  Of course, STDC_HEADERS is never false when building libc!  */
+ #define STDC_HEADERS	1
+-#define HAVE_MBSTATE_T	1
+-#define HAVE_MBSRTOWCS	1
++
+ #define HAVE_LIBINTL_H	1
+ #define HAVE_WCTYPE_H	1
+ #define HAVE_ISWCTYPE	1
+diff -Naur glibc-2.20/include/netdb.h glibc-2.20-patch/include/netdb.h
+--- glibc-2.20/include/netdb.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/include/netdb.h	2015-03-04 00:51:32.372952006 -0600
+@@ -232,6 +232,10 @@
+ 		       (const char *name, int af, struct hostent *host,	      \
+ 			char *buffer, size_t buflen, int *errnop,	      \
+ 			int *h_errnop);					      \
++extern enum nss_status _nss_ ## service ## _gethostbyname3_r		      \
++		       (const char *name, int af, struct hostent *result,     \
++			char *buffer, size_t buflen, int *errnop,	      \
++			int *h_errnop, int32_t *ttlp, char **canonp);         \
+ extern enum nss_status _nss_ ## service ## _gethostbyname_r		      \
+ 		       (const char *name, struct hostent *host, char *buffer, \
+ 			size_t buflen, int *errnop, int *h_errnop);	      \
+diff -Naur glibc-2.20/inet/Makefile glibc-2.20-patch/inet/Makefile
+--- glibc-2.20/inet/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/inet/Makefile	2015-03-04 00:51:32.372952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for inet portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= inet
+ 
+ include ../Makeconfig
+@@ -27,7 +29,8 @@
+ 	   netinet/tcp.h netinet/ip.h $(wildcard arpa/*.h protocols/*.h) \
+ 	   aliases.h ifaddrs.h netinet/ip6.h netinet/icmp6.h bits/in.h
+ 
+-routines := htonl htons		\
++routines-$(OPTION_EGLIBC_INET) \
++	 += htonl htons \
+ 	    inet_lnaof inet_mkadr	\
+ 	    inet_netof inet_ntoa inet_net herrno herrno-loc \
+ 	    gethstbyad gethstbyad_r gethstbynm gethstbynm2 gethstbynm2_r \
+@@ -41,18 +44,23 @@
+ 	    getrpcent_r getrpcbyname_r getrpcbynumber_r \
+ 	    ether_aton ether_aton_r ether_hton ether_line \
+ 	    ether_ntoa ether_ntoa_r ether_ntoh \
+-	    rcmd rexec ruserpass \
+ 	    getnetgrent_r getnetgrent \
+-	    getaliasent_r getaliasent getaliasname getaliasname_r \
+-	    in6_addr getnameinfo if_index ifaddrs inet6_option \
++	    in6_addr getnameinfo if_index ifaddrs \
+ 	    getipv4sourcefilter setipv4sourcefilter \
+-	    getsourcefilter setsourcefilter inet6_opt inet6_rth
++	    getsourcefilter setsourcefilter
++routines-$(OPTION_EGLIBC_RCMD) \
++	 += rcmd rexec ruserpass
++routines-$(OPTION_EGLIBC_DB_ALIASES) \
++	 += getaliasent_r getaliasent getaliasname getaliasname_r
++routines-$(OPTION_EGLIBC_ADVANCED_INET6) \
++	 += inet6_option inet6_opt inet6_rth
+ 
+-aux := check_pf check_native ifreq
++aux-$(OPTION_EGLIBC_INET) += check_pf check_native ifreq
+ 
+ tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
+-	 tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
++	 tst-gethnm test-ifaddrs bug-if1 tst-ether_line \
+ 	 tst-getni1 tst-getni2 tst-inet6_rth tst-checks
++tests-$(OPTION_EGLIBC_ADVANCED_INET6) += test-inet6_opt
+ 
+ include ../Rules
+ 
+diff -Naur glibc-2.20/intl/dcigettext.c glibc-2.20-patch/intl/dcigettext.c
+--- glibc-2.20/intl/dcigettext.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/intl/dcigettext.c	2015-03-04 00:51:32.372952006 -0600
+@@ -77,6 +77,10 @@
+ #endif
+ #include "hash-string.h"
+ 
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ /* Thread safetyness.  */
+ #ifdef _LIBC
+ # include <bits/libc-lock.h>
+@@ -449,9 +453,11 @@
+ #endif
+ 
+ #ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+   __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
+   __libc_rwlock_rdlock (__libc_setlocale_lock);
+ #endif
++#endif
+ 
+   __libc_rwlock_rdlock (_nl_state_lock);
+ 
+@@ -470,7 +476,11 @@
+   search.category = category;
+ # ifdef HAVE_PER_THREAD_LOCALE
+ #  ifdef _LIBC
++#   if __OPTION_EGLIBC_LOCALE_CODE
+   localename = strdupa (__current_locale_name (category));
++#   else
++  localename = "C";
++#   endif
+ #  endif
+   search.localename = localename;
+ # endif
+@@ -494,7 +504,9 @@
+ 	retval = (char *) (*foundp)->translation;
+ 
+ # ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+       __libc_rwlock_unlock (__libc_setlocale_lock);
++#endif
+ # endif
+       __libc_rwlock_unlock (_nl_state_lock);
+       return retval;
+@@ -611,7 +623,9 @@
+ 	{
+ 	no_translation:
+ 	  FREE_BLOCKS (block_list);
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	  __libc_rwlock_unlock (__libc_setlocale_lock);
++#endif
+ 	  __libc_rwlock_unlock (_nl_state_lock);
+ 	  __set_errno (saved_errno);
+ 	  return (plural == 0
+@@ -730,7 +744,9 @@
+ 	      if (plural)
+ 		retval = plural_lookup (domain, n, retval, retlen);
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	      __libc_rwlock_unlock (__libc_setlocale_lock);
++#endif
+ 	      __libc_rwlock_unlock (_nl_state_lock);
+ 	      return retval;
+ 	    }
+@@ -1361,7 +1377,11 @@
+      `LC_xxx', and `LANG'.  On some systems this can be done by the
+      `setlocale' function itself.  */
+ #ifdef _LIBC
++# if __OPTION_EGLIBC_LOCALE_CODE
+   retval = __current_locale_name (category);
++# else
++  retval = "C";
++# endif
+ #else
+   retval = _nl_locale_name (category, categoryname);
+ #endif
+diff -Naur glibc-2.20/intl/Makefile glibc-2.20-patch/intl/Makefile
+--- glibc-2.20/intl/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/intl/Makefile	2015-03-04 00:51:32.372952006 -0600
+@@ -16,6 +16,7 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ # Makefile for intl subdirectory: message handling code from GNU gettext.
++include ../option-groups.mak
+ 
+ subdir = intl
+ 
+@@ -48,7 +49,7 @@
+ $(objpfx)plural.o: plural.c
+ 
+ ifeq ($(run-built-tests),yes)
+-ifeq (yes,$(build-shared))
++ifeq (yyyes,$(OPTION_EGLIBC_LOCALES)$(OPTION_EGLIBC_LOCALE_CODE)$(build-shared))
+ ifneq ($(strip $(MSGFMT)),:)
+ tests-special += $(objpfx)tst-translit.out $(objpfx)tst-gettext.out \
+ 		 $(objpfx)tst-gettext2.out $(objpfx)tst-codeset.out \
+diff -Naur glibc-2.20/io/Makefile glibc-2.20-patch/io/Makefile
+--- glibc-2.20/io/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/io/Makefile	2015-03-04 00:51:32.372952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for I/O portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= io
+ 
+ include ../Makeconfig
+@@ -36,7 +38,7 @@
+ 	fxstatat fxstatat64						\
+ 	statfs fstatfs statfs64 fstatfs64				\
+ 	statvfs fstatvfs statvfs64 fstatvfs64				\
+-	umask chmod fchmod lchmod fchmodat				\
++	umask chmod fchmod fchmodat					\
+ 	mkdir mkdirat							\
+ 	open open_2 open64 open64_2 openat openat_2 openat64 openat64_2	\
+ 	read write lseek lseek64 access euidaccess faccessat		\
+@@ -49,11 +51,13 @@
+ 	ttyname ttyname_r isatty					\
+ 	link linkat symlink symlinkat readlink readlinkat		\
+ 	unlink unlinkat rmdir						\
+-	ftw ftw64 fts poll ppoll					\
++	poll ppoll							\
+ 	posix_fadvise posix_fadvise64					\
+ 	posix_fallocate posix_fallocate64				\
+ 	sendfile sendfile64 \
+ 	utimensat futimens
++routines-$(OPTION_EGLIBC_BSD) += lchmod
++routines-$(OPTION_EGLIBC_FTRAVERSE) += ftw ftw64 fts
+ 
+ aux := have_o_cloexec
+ 
+@@ -64,18 +68,22 @@
+ 		       fstatat fstatat64 mknod mknodat
+ 
+ others		:= pwd
+-test-srcs	:= ftwtest
++test-srcs-$(OPTION_EGLIBC_FTRAVERSE) := ftwtest
+ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
+-		   tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \
++		   tst-fcntl tst-statvfs \
+ 		   tst-openat tst-unlinkat tst-fstatat tst-futimesat \
+ 		   tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
+ 		   tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
+-		   tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
++		   tst-mknodat tst-mkfifoat tst-ttyname_r \
+ 		   tst-posix_fallocate
++tests-$(OPTION_EGLIBC_FTRAVERSE) += bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 \
++				    bug-ftw5
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_EGLIBC_FTRAVERSE))
+ tests-special += $(objpfx)ftwtest.out
+ endif
++endif
+ 
+ include ../Rules
+ 
+diff -Naur glibc-2.20/libidn/Makefile glibc-2.20-patch/libidn/Makefile
+--- glibc-2.20/libidn/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libidn/Makefile	2015-03-04 00:51:32.372952006 -0600
+@@ -16,6 +16,7 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ # Makefile for libidn subdirectory of GNU C Library.
++include ../option-groups.mak
+ 
+ subdir	:= libidn
+ 
+@@ -23,8 +24,8 @@
+ 
+ routines = idn-stub
+ 
+-extra-libs		= libcidn
+-extra-libs-others	= $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_IDN) = libcidn
++extra-libs-others-y = $(extra-libs-y)
+ 
+ libcidn-routines := punycode toutf8 nfkc stringprep rfc3454 profiles idna \
+ 		    iconvme
+diff -Naur glibc-2.20/libidn/toutf8.c glibc-2.20-patch/libidn/toutf8.c
+--- glibc-2.20/libidn/toutf8.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libidn/toutf8.c	2015-03-04 00:51:32.373952006 -0600
+@@ -33,6 +33,11 @@
+ /* Get strlen. */
+ #include <string.h>
+ 
++/* Get __OPTION_EGLIBC_LOCALE_CODE.  */
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ /* Get iconv_string. */
+ #include "iconvme.h"
+ 
+@@ -47,7 +52,11 @@
+ #endif
+ 
+ #ifdef _LIBC
+-# define stringprep_locale_charset() nl_langinfo (CODESET)
++# if __OPTION_EGLIBC_LOCALE_CODE
++#  define stringprep_locale_charset() nl_langinfo (CODESET)
++# else
++#  define stringprep_locale_charset() "ANSI_X3.4-1968"
++# endif
+ #else
+ /**
+  * stringprep_locale_charset - return charset used in current locale
+diff -Naur glibc-2.20/libio/fileops.c glibc-2.20-patch/libio/fileops.c
+--- glibc-2.20/libio/fileops.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/fileops.c	2015-03-04 00:51:32.373952006 -0600
+@@ -38,6 +38,7 @@
+ #include <string.h>
+ #include <errno.h>
+ #include <unistd.h>
++#include <gnu/option-groups.h>
+ #include <stdlib.h>
+ #if _LIBC
+ # include "../wcsmbs/wcsmbsload.h"
+@@ -174,7 +175,7 @@
+ 
+   /* Free buffer. */
+ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
+-  if (fp->_mode > 0)
++  if (_IO_is_wide (fp))
+     {
+       if (_IO_have_wbackup (fp))
+ 	_IO_free_wbackup_area (fp);
+@@ -359,6 +360,7 @@
+       cs = strstr (last_recognized + 1, ",ccs=");
+       if (cs != NULL)
+ 	{
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ 	  /* Yep.  Load the appropriate conversions and set the orientation
+ 	     to wide.  */
+ 	  struct gconv_fcts fcts;
+@@ -423,6 +425,12 @@
+ 
+ 	  /* Set the mode now.  */
+ 	  result->_mode = 1;
++#else
++          /* Treat this as if we couldn't find the given character set.  */
++          (void) _IO_file_close_it (fp);
++          __set_errno (EINVAL);
++          return NULL;
++#endif
+ 	}
+     }
+ 
+diff -Naur glibc-2.20/libio/__fpurge.c glibc-2.20-patch/libio/__fpurge.c
+--- glibc-2.20/libio/__fpurge.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/__fpurge.c	2015-03-04 00:51:32.373952006 -0600
+@@ -21,7 +21,7 @@
+ void
+ __fpurge (FILE *fp)
+ {
+-  if (fp->_mode > 0)
++  if (_IO_is_wide (fp))
+     {
+       /* Wide-char stream.  */
+       if (_IO_in_backup (fp))
+diff -Naur glibc-2.20/libio/iofwide.c glibc-2.20-patch/libio/iofwide.c
+--- glibc-2.20/libio/iofwide.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/iofwide.c	2015-03-04 00:51:32.373952006 -0600
+@@ -26,6 +26,7 @@
+ 
+ #include <libioP.h>
+ #ifdef _LIBC
++# include <gnu/option-groups.h>
+ # include <dlfcn.h>
+ # include <wchar.h>
+ #endif
+@@ -43,6 +44,8 @@
+ #endif
+ 
+ 
++#if ! defined _LIBC || __OPTION_POSIX_C_LANG_WIDE_CHAR
++
+ /* Prototypes of libio's codecvt functions.  */
+ static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
+ 				     __mbstate_t *statep,
+@@ -513,3 +516,26 @@
+   return MB_CUR_MAX;
+ #endif
+ }
++
++#else
++/* OPTION_POSIX_C_LANG_WIDE_CHAR is disabled.  */
++
++#undef _IO_fwide
++int
++_IO_fwide (fp, mode)
++     _IO_FILE *fp;
++     int mode;
++{
++  /* Die helpfully if the user tries to create a wide stream; I
++     disbelieve that most users check the return value from
++     'fwide (fp, 1)'.  */
++  assert (mode <= 0);
++
++  /* We can only make streams byte-oriented, which is trivial.  */
++  if (mode < 0)
++    fp->_mode = -1;
++
++  return fp->_mode;
++}
++
++#endif
+diff -Naur glibc-2.20/libio/ioseekoff.c glibc-2.20-patch/libio/ioseekoff.c
+--- glibc-2.20/libio/ioseekoff.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/ioseekoff.c	2015-03-04 00:51:32.373952006 -0600
+@@ -60,7 +60,7 @@
+ 	  else
+ 	    abort ();
+ 	}
+-      if (_IO_fwide (fp, 0) < 0)
++      if (! _IO_is_wide (fp))
+ 	_IO_free_backup_area (fp);
+       else
+ 	_IO_free_wbackup_area (fp);
+diff -Naur glibc-2.20/libio/ioseekpos.c glibc-2.20-patch/libio/ioseekpos.c
+--- glibc-2.20/libio/ioseekpos.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/ioseekpos.c	2015-03-04 00:51:32.374952006 -0600
+@@ -35,7 +35,7 @@
+   /* If we have a backup buffer, get rid of it, since the __seekoff
+      callback may not know to do the right thing about it.
+      This may be over-kill, but it'll do for now. TODO */
+-  if (_IO_fwide (fp, 0) <= 0)
++  if (! _IO_is_wide (fp))
+     {
+       if (_IO_have_backup (fp))
+ 	_IO_free_backup_area (fp);
+diff -Naur glibc-2.20/libio/iosetbuffer.c glibc-2.20-patch/libio/iosetbuffer.c
+--- glibc-2.20/libio/iosetbuffer.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/iosetbuffer.c	2015-03-04 00:51:32.374952006 -0600
+@@ -24,6 +24,8 @@
+    This exception applies to code released by its copyright holders
+    in files containing the exception.  */
+ 
++#include <gnu/option-groups.h>
++
+ #include "libioP.h"
+ 
+ void
+@@ -38,9 +40,11 @@
+   if (!buf)
+     size = 0;
+   (void) _IO_SETBUF (fp, buf, size);
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp))
+     /* We also have to set the buffer using the wide char function.  */
+     (void) _IO_WSETBUF (fp, buf, size);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+   _IO_release_lock (fp);
+ }
+ libc_hidden_def (_IO_setbuffer)
+diff -Naur glibc-2.20/libio/libioP.h glibc-2.20-patch/libio/libioP.h
+--- glibc-2.20/libio/libioP.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/libioP.h	2015-03-04 00:51:32.374952006 -0600
+@@ -42,6 +42,10 @@
+ /*# include <comthread.h>*/
+ #endif
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #include <math_ldbl_opt.h>
+ 
+ #include "iolibio.h"
+@@ -508,8 +512,20 @@
+ 
+ 
+ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
++
++/* _IO_is_wide (fp) is roughly equivalent to '_IO_fwide (fp, 0) > 0',
++   except that when OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, it
++   expands to a constant, allowing the compiler to realize that it can
++   eliminate code that references wide stream handling functions.
++   This, in turn, allows us to omit them.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define _IO_is_wide(_f) ((_f)->_mode > 0)
++#else
++# define _IO_is_wide(_f) (0)
++#endif
++
+ # define _IO_do_flush(_f) \
+-  ((_f)->_mode <= 0							      \
++  (! _IO_is_wide (_f)                                                         \
+    ? _IO_do_write(_f, (_f)->_IO_write_base,				      \
+ 		  (_f)->_IO_write_ptr-(_f)->_IO_write_base)		      \
+    : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base,		      \
+diff -Naur glibc-2.20/libio/Makefile glibc-2.20-patch/libio/Makefile
+--- glibc-2.20/libio/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/libio/Makefile	2015-03-04 00:51:32.375952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Specific makefile for libio.
+ #
++include ../option-groups.mak
++
+ subdir	:= libio
+ 
+ include ../Makeconfig
+@@ -27,16 +29,13 @@
+ 
+ routines	:=							      \
+ 	filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
+-	iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc	      \
++	iofopncook iofputs iofread iofsetpos ioftell			      \
+ 	iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs	      \
+ 	ioseekoff ioseekpos iosetbuffer iosetvbuf ioungetc		      \
+ 	iovsprintf iovsscanf						      \
+ 	iofgetpos64 iofopen64 iofsetpos64				      \
+-	fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
+-	iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u	      \
+-	putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf      \
+-	wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops   \
+-	wstrops wfileops iofwide fwide wmemstream			      \
++	putchar putchar_u						      \
++	iofwide								      \
+ 									      \
+ 	clearerr feof ferror fileno fputc freopen fseek getc getchar	      \
+ 	memstream pclose putc putchar rewind setbuf setlinebuf vasprintf      \
+@@ -47,25 +46,48 @@
+ 	__fpurge __fpending __fsetlocking				      \
+ 									      \
+ 	libc_fatal fmemopen
+-
+-tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
+-	tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \
+-	tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf	      \
+-	tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof          \
+-	tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
+-	tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \
+-	tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \
+-	bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \
+-	tst-memstream1 tst-memstream2 \
+-	tst-wmemstream1 tst-wmemstream2 \
+-	bug-memstream1 bug-wmemstream1 \
+-	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
+-	tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
+-	tst-ftell-append
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	wfiledoalloc							      \
++	iowpadn								      \
++	swprintf							      \
++	vswprintf iovswscanf swscanf wgenops				      \
++	wstrops wfileops wmemstream
++routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) +=	      \
++	wdummyfileops
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) +=				      \
++	fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
++	iofputws iofputws_u iogetwline ioungetwc putwc putwc_u		      \
++	putwchar putwchar_u fwprintf vwprintf				      \
++	wprintf wscanf fwscanf vwscanf					      \
++	fwide
++
++tests = test-fmemopen tst-ext tst-ext2				\
++	tst-mmap-setvbuf tst-atime tst-eof			\
++	tst-freopen bug-ungetc bug-fseek			\
++	tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush	\
++	tst-mmap2-eofsync tst-mmap-offend bug-fopena+		\
++	bug-ungetc2 bug-ungetc3 bug-ungetc4			\
++	tst-memstream1 tst-memstream2				\
++	bug-memstream1 tst-popen1 tst-fwrite-error              \
++	tst-ftell-active-handler tst-ftell-append
++tests-$(OPTION_EGLIBC_LOCALE_CODE)				\
++     += tst-swscanf tst-fgetws tst-setvbuf1			\
++	tst-ungetwc1 tst-ungetwc2 bug-ftell bug-ungetwc2	\
++	tst-widetext
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)		\
++     += bug-rewind bug-rewind2 bug-ungetwc1		\
++	bug-wfflush bug-wmemstream1 tst-fopenloc2	\
++	tst_getwc					\
++	tst_putwc tst_wprintf tst_wprintf2 tst_wscanf	\
++	tst-fgetwc bug-wsetpos tst-fseek tst-ftell-partial-wide
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR)			\
++     += tst_swprintf tst_swscanf			\
++	tst-sscanf					\
++	tst-wmemstream1 tst-wmemstream2
+ ifeq (yes,$(build-shared))
+ # Add test-fopenloc only if shared library is enabled since it depends on
+ # shared localedata objects.
+-tests += tst-fopenloc
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-fopenloc
+ endif
+ test-srcs = test-freopen
+ 
+@@ -164,13 +186,17 @@
+ 		       oldiofsetpos64
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
+ tests-special += $(objpfx)test-freopen.out
++endif
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ ifeq (yes,$(build-shared))
+ # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
+ # library is enabled since they depend on tst-fopenloc.out.
+ tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out
+ endif
+ endif
++endif
+ 
+ include ../Rules
+ 
+diff -Naur glibc-2.20/libio/wdummyfileops.c glibc-2.20-patch/libio/wdummyfileops.c
+--- glibc-2.20/libio/wdummyfileops.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/libio/wdummyfileops.c	2015-03-04 00:51:32.375952006 -0600
+@@ -0,0 +1,161 @@
++/* 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.
++
++   As a special exception, if you link the code in this file with
++   files compiled with a GNU compiler to produce an executable,
++   that does not cause the resulting executable to be covered by
++   the GNU Lesser General Public License.  This exception does not
++   however invalidate any other reasons why the executable file
++   might be covered by the GNU Lesser General Public License.
++   This exception applies to code released by its copyright holders
++   in files containing the exception.  */
++
++#include <assert.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <libioP.h>
++
++static void __THROW __attribute__ ((__noreturn__))
++_IO_wfile_wide_char_support_disabled (void)
++{
++  static const char errstr[]
++    = ("The application tried to use wide character I/O, but libc.so"
++       " was compiled\n"
++       "with the OPTION_POSIX_C_LANG_WIDE_CHAR option group disabled.\n");
++  __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
++  abort ();
++}
++
++static void
++_IO_wfile_disabled_void_int (_IO_FILE *fp, int x)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_int_int (_IO_FILE *fp, int x)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_int_none (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_size_t
++_IO_wfile_disabled_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_size_t
++_IO_wfile_disabled_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seekoff (_IO_FILE *fp, _IO_off64_t off, int dir, int mode)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seekpos (_IO_FILE *fp, _IO_off64_t pos, int flags)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_FILE *
++_IO_wfile_disabled_setbuf (_IO_FILE *fp, char *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_ssize_t
++_IO_wfile_disabled_read (_IO_FILE *fp, void *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_ssize_t
++_IO_wfile_disabled_write (_IO_FILE *fp, const void *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seek (_IO_FILE *fp, _IO_off64_t offset, int mode)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_close (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_stat (_IO_FILE *fp, void *buf)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_showmanyc (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static void
++_IO_wfile_disabled_imbue (_IO_FILE *fp, void *locale)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static const struct _IO_jump_t _IO_wfile_jumps_disabled =
++{
++  JUMP_INIT_DUMMY,
++  JUMP_INIT(finish, _IO_wfile_disabled_void_int),
++  JUMP_INIT(overflow, _IO_wfile_disabled_int_int),
++  JUMP_INIT(underflow, _IO_wfile_disabled_int_none),
++  JUMP_INIT(uflow, _IO_wfile_disabled_int_none),
++  JUMP_INIT(pbackfail, _IO_wfile_disabled_int_int),
++  JUMP_INIT(xsputn, _IO_wfile_disabled_xsputn),
++  JUMP_INIT(xsgetn, _IO_wfile_disabled_xsgetn),
++  JUMP_INIT(seekoff, _IO_wfile_disabled_seekoff),
++  JUMP_INIT(seekpos, _IO_wfile_disabled_seekpos),
++  JUMP_INIT(setbuf, _IO_wfile_disabled_setbuf),
++  JUMP_INIT(sync, _IO_wfile_disabled_int_none),
++  JUMP_INIT(doallocate, _IO_wfile_disabled_int_none),
++  JUMP_INIT(read, _IO_wfile_disabled_read),
++  JUMP_INIT(write, _IO_wfile_disabled_write),
++  JUMP_INIT(seek, _IO_wfile_disabled_seek),
++  JUMP_INIT(close, _IO_wfile_disabled_close),
++  JUMP_INIT(stat, _IO_wfile_disabled_stat),
++  JUMP_INIT(showmanyc, _IO_wfile_disabled_showmanyc),
++  JUMP_INIT(imbue, _IO_wfile_disabled_imbue)
++};
++
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps)
++libc_hidden_data_def (_IO_wfile_jumps)
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_mmap)
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_maybe_mmap)
+diff -Naur glibc-2.20/locale/catnames.c glibc-2.20-patch/locale/catnames.c
+--- glibc-2.20/locale/catnames.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/locale/catnames.c	2015-03-04 00:51:32.375952006 -0600
+@@ -0,0 +1,48 @@
++/* Copyright (C) 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 "localeinfo.h"
++
++/* Define an array of category names (also the environment variable names).  */
++const union catnamestr_t _nl_category_names attribute_hidden =
++  {
++    {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++      category_name,
++#include "categories.def"
++#undef DEFINE_CATEGORY
++    }
++  };
++
++const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
++  {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
++#include "categories.def"
++#undef DEFINE_CATEGORY
++  };
++
++/* An array of their lengths, for convenience.  */
++const uint8_t _nl_category_name_sizes[] attribute_hidden =
++  {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++    [category] = sizeof (category_name) - 1,
++#include "categories.def"
++#undef	DEFINE_CATEGORY
++    [LC_ALL] = sizeof ("LC_ALL") - 1
++  };
+diff -Naur glibc-2.20/locale/C-ctype.c glibc-2.20-patch/locale/C-ctype.c
+--- glibc-2.20/locale/C-ctype.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/C-ctype.c	2015-03-04 00:51:32.375952006 -0600
+@@ -19,8 +19,11 @@
+ #include "localeinfo.h"
+ #include <endian.h>
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ #include "C-translit.h"
++#endif
+ 
+ /* This table's entries are taken from POSIX.2 Table 2-6
+    ``LC_CTYPE Category Definition in the POSIX Locale''.
+@@ -647,6 +650,7 @@
+     { .word = L'7' },
+     { .word = L'8' },
+     { .word = L'9' },
++#if __OPTION_EGLIBC_LOCALE_CODE
+     /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
+     { .word = NTRANSLIT },
+     /* _NL_CTYPE_TRANSLIT_FROM_IDX */
+@@ -657,6 +661,22 @@
+     { .wstr = translit_to_idx },
+     /* _NL_CTYPE_TRANSLIT_TO_TBL */
+     { .wstr = (uint32_t *) translit_to_tbl },
++#else
++    /* If the locale code isn't enabled, we don't have the
++       transliteration code in iconv/gconv_trans.c anyway, so there's
++       no need for the transliteration tables here.  We'll fall back
++       on the default missing replacement, '?'.  */
++    /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
++    { .word = 0 },
++    /* _NL_CTYPE_TRANSLIT_FROM_IDX */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_FROM_TBL */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_TO_IDX */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_TO_TBL */
++    { .wstr = NULL },
++#endif
+     /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN */
+     { .word = 1 },
+     /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING */
+diff -Naur glibc-2.20/locale/dummy-setlocale.c glibc-2.20-patch/locale/dummy-setlocale.c
+--- glibc-2.20/locale/dummy-setlocale.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/locale/dummy-setlocale.c	2015-03-04 00:51:32.375952006 -0600
+@@ -0,0 +1,33 @@
++/* Copyright (C) 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 <string.h>
++#include <locale.h>
++
++char *
++setlocale (int category, const char *locale)
++{
++  if (! locale
++      || locale[0] == '\0'
++      || strcmp (locale, "C") == 0
++      || strcmp (locale, "POSIX") == 0)
++    return (char *) "C";
++  else
++    return NULL;
++}
++libc_hidden_def (setlocale)
+diff -Naur glibc-2.20/locale/localeinfo.h glibc-2.20-patch/locale/localeinfo.h
+--- glibc-2.20/locale/localeinfo.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/localeinfo.h	2015-03-04 00:51:32.375952006 -0600
+@@ -224,7 +224,7 @@
+    unused.  We can manage this playing some tricks with weak references.
+    But with thread-local locale settings, it becomes quite ungainly unless
+    we can use __thread variables.  So only in that case do we attempt this.  */
+-#ifndef SHARED
++#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF
+ # include <tls.h>
+ # define NL_CURRENT_INDIRECT	1
+ #endif
+diff -Naur glibc-2.20/locale/Makefile glibc-2.20-patch/locale/Makefile
+--- glibc-2.20/locale/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/Makefile	2015-03-04 00:51:32.375952006 -0600
+@@ -18,27 +18,43 @@
+ #
+ #	Makefile for locales.
+ #
++include ../option-groups.mak
++
+ subdir	:= locale
+ 
+ include ../Makeconfig
+ 
+ headers		= locale.h bits/locale.h langinfo.h xlocale.h
+-routines	= setlocale findlocale loadlocale loadarchive \
+-		  localeconv nl_langinfo nl_langinfo_l mb_cur_max \
+-		  newlocale duplocale freelocale uselocale
+-tests		= tst-C-locale tst-locname tst-duplocale
++# catnames is needed by OPTION_EGLIBC_LOCALE_CODE and by the 'intl' code.
++# If we put the latter in an option group, too, we can omit catnames
++# when both option groups are disabled.  libstdc++-v3 needs mb_cur_max.
++routines-y      := catnames mb_cur_max
++routines-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= setlocale findlocale loadlocale loadarchive \
++		   localeconv nl_langinfo nl_langinfo_l \
++		   newlocale duplocale freelocale uselocale
++ifneq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++routines-y	+= dummy-setlocale
++endif
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-C-locale tst-locname tst-duplocale
+ categories	= ctype messages monetary numeric time paper name \
+ 		  address telephone measurement identification collate
+-aux		= $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \
+-		  xlocale localename global-locale coll-lookup
+-others		= localedef locale
++# C-messages belongs in an intl option group.
++aux-y		:= C-ctype C-time \
++		   SYS_libc C_name xlocale global-locale coll-lookup
++aux-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= $(filter-out $(aux-y), \
++	                        $(categories:%=lc-%) $(categories:%=C-%)) \
++	           localename
++others-$(OPTION_EGLIBC_LOCALE_CODE) = localedef locale
+ #others-static	= localedef locale
+-install-bin	= localedef locale
+-extra-objs	= $(localedef-modules:=.o) $(localedef-aux:=.o) \
++install-bin	= $(others-y)
++extra-objs-$(OPTION_EGLIBC_LOCALE_CODE) \
++		= $(localedef-modules:=.o) $(localedef-aux:=.o) \
+ 		  $(locale-modules:=.o) $(lib-modules:=.o)
+ 
+-extra-libs	= libBrokenLocale
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_LOCALE_CODE) = libBrokenLocale
++extra-libs-others = $(extra-libs-y)
+ 
+ libBrokenLocale-routines = broken_cur_max
+ 
+@@ -94,6 +110,9 @@
+ CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts
+ CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts
+ CFLAGS-charmap-dir.c = -Wno-write-strings
++ifneq (y,$(OPTION_EGLIBC_SPAWN))
++CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
++endif
+ 
+ # This makes sure -DNOT_IN_libc et al are passed for all these modules.
+ cpp-srcs-left := $(addsuffix .c,$(localedef-modules) $(localedef-aux) \
+diff -Naur glibc-2.20/locale/programs/charmap-dir.c glibc-2.20-patch/locale/programs/charmap-dir.c
+--- glibc-2.20/locale/programs/charmap-dir.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/charmap-dir.c	2015-03-04 00:51:32.376952006 -0600
+@@ -19,7 +19,9 @@
+ #include <error.h>
+ #include <fcntl.h>
+ #include <libintl.h>
++#ifndef NO_UNCOMPRESS
+ #include <spawn.h>
++#endif
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -156,6 +158,7 @@
+   return closedir (dir);
+ }
+ 
++#ifndef NO_UNCOMPRESS
+ /* Creates a subprocess decompressing the given pathname, and returns
+    a stream reading its output (the decompressed data).  */
+ static
+@@ -204,6 +207,7 @@
+     }
+   return NULL;
+ }
++#endif
+ 
+ /* Opens a charmap for reading, given its name (not an alias name).  */
+ FILE *
+@@ -226,6 +230,7 @@
+   if (stream != NULL)
+     return stream;
+ 
++#ifndef NO_UNCOMPRESS
+   memcpy (p, ".gz", 4);
+   stream = fopen_uncompressed (pathname, "gzip");
+   if (stream != NULL)
+@@ -235,6 +240,7 @@
+   stream = fopen_uncompressed (pathname, "bzip2");
+   if (stream != NULL)
+     return stream;
++#endif
+ 
+   return NULL;
+ }
+@@ -263,8 +269,8 @@
+       char *alias = NULL;
+       char junk[BUFSIZ];
+ 
+-      if (fscanf (stream, " <code_set_name> %ms", &alias) == 1
+-          || fscanf (stream, "%% alias %ms", &alias) == 1)
++      if (fscanf (stream, " <code_set_name> %as", &alias) == 1
++          || fscanf (stream, "%% alias %as", &alias) == 1)
+         {
+           aliases = (char **) xrealloc (aliases,
+                                         (naliases + 2) * sizeof (char *));
+diff -Naur glibc-2.20/locale/programs/ld-collate.c glibc-2.20-patch/locale/programs/ld-collate.c
+--- glibc-2.20/locale/programs/ld-collate.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/ld-collate.c	2015-03-04 00:51:32.376952006 -0600
+@@ -350,7 +350,7 @@
+     }
+   if (wcs != NULL)
+     {
+-      size_t nwcs = wcslen ((wchar_t *) wcs);
++      size_t nwcs = wcslen_uint32 (wcs);
+       uint32_t zero = 0;
+       /* Handle <U0000> as a single character.  */
+       if (nwcs == 0)
+@@ -1776,8 +1776,7 @@
+ 
+ 	      if ((*eptr)->nwcs == runp->nwcs)
+ 		{
+-		  int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
+-				   (wchar_t *) runp->wcs, runp->nwcs);
++		  int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs);
+ 
+ 		  if (c == 0)
+ 		    {
+@@ -2010,9 +2009,9 @@
+ 	     one consecutive entry.  */
+ 	  if (runp->wcnext != NULL
+ 	      && runp->nwcs == runp->wcnext->nwcs
+-	      && wmemcmp ((wchar_t *) runp->wcs,
+-			  (wchar_t *)runp->wcnext->wcs,
+-			  runp->nwcs - 1) == 0
++	      && wmemcmp_uint32 (runp->wcs,
++				 runp->wcnext->wcs,
++				 runp->nwcs - 1) == 0
+ 	      && (runp->wcs[runp->nwcs - 1]
+ 		  == runp->wcnext->wcs[runp->nwcs - 1] + 1))
+ 	    {
+@@ -2036,9 +2035,9 @@
+ 		runp = runp->wcnext;
+ 	      while (runp->wcnext != NULL
+ 		     && runp->nwcs == runp->wcnext->nwcs
+-		     && wmemcmp ((wchar_t *) runp->wcs,
+-				 (wchar_t *)runp->wcnext->wcs,
+-				 runp->nwcs - 1) == 0
++		     && wmemcmp_uint32 (runp->wcs,
++					runp->wcnext->wcs,
++					runp->nwcs - 1) == 0
+ 		     && (runp->wcs[runp->nwcs - 1]
+ 			 == runp->wcnext->wcs[runp->nwcs - 1] + 1));
+ 
+diff -Naur glibc-2.20/locale/programs/ld-ctype.c glibc-2.20-patch/locale/programs/ld-ctype.c
+--- glibc-2.20/locale/programs/ld-ctype.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/ld-ctype.c	2015-03-04 00:51:32.377952006 -0600
+@@ -957,7 +957,7 @@
+   allocate_arrays (ctype, charmap, ctype->repertoire);
+ 
+   default_missing_len = (ctype->default_missing
+-			 ? wcslen ((wchar_t *) ctype->default_missing)
++			 ? wcslen_uint32 (ctype->default_missing)
+ 			 : 0);
+ 
+   init_locale_data (&file, nelems);
+@@ -1968,7 +1968,7 @@
+ 	    ignore = 1;
+ 	  else
+ 	    /* This value is usable.  */
+-	    obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4);
++	    obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4);
+ 
+ 	  first = 0;
+ 	}
+@@ -2516,8 +2516,8 @@
+ 	    }
+ 
+ 	handle_tok_digit:
+-	  class_bit = _ISwdigit;
+-	  class256_bit = _ISdigit;
++	  class_bit = BITw (tok_digit);
++	  class256_bit = BIT (tok_digit);
+ 	  handle_digits = 1;
+ 	  goto read_charclass;
+ 
+@@ -4001,8 +4001,7 @@
+ 
+ 	  while (idx < number)
+ 	    {
+-	      int res = wcscmp ((const wchar_t *) sorted[idx]->from,
+-				(const wchar_t *) runp->from);
++	      int res = wcscmp_uint32 (sorted[idx]->from, runp->from);
+ 	      if (res == 0)
+ 		{
+ 		  replace = 1;
+@@ -4039,11 +4038,11 @@
+       for (cnt = 0; cnt < number; ++cnt)
+ 	{
+ 	  struct translit_to_t *srunp;
+-	  from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
++	  from_len += wcslen_uint32 (sorted[cnt]->from) + 1;
+ 	  srunp = sorted[cnt]->to;
+ 	  while (srunp != NULL)
+ 	    {
+-	      to_len += wcslen ((const wchar_t *) srunp->str) + 1;
++	      to_len += wcslen_uint32 (srunp->str) + 1;
+ 	      srunp = srunp->next;
+ 	    }
+ 	  /* Plus one for the extra NUL character marking the end of
+@@ -4067,18 +4066,18 @@
+ 	  ctype->translit_from_idx[cnt] = from_len;
+ 	  ctype->translit_to_idx[cnt] = to_len;
+ 
+-	  len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
+-	  wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len],
+-		   (const wchar_t *) sorted[cnt]->from, len);
++	  len = wcslen_uint32 (sorted[cnt]->from) + 1;
++	  wmemcpy_uint32 (&ctype->translit_from_tbl[from_len],
++			  sorted[cnt]->from, len);
+ 	  from_len += len;
+ 
+ 	  ctype->translit_to_idx[cnt] = to_len;
+ 	  srunp = sorted[cnt]->to;
+ 	  while (srunp != NULL)
+ 	    {
+-	      len = wcslen ((const wchar_t *) srunp->str) + 1;
+-	      wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len],
+-		       (const wchar_t *) srunp->str, len);
++	      len = wcslen_uint32 (srunp->str) + 1;
++	      wmemcpy_uint32 (&ctype->translit_to_tbl[to_len],
++			      srunp->str, len);
+ 	      to_len += len;
+ 	      srunp = srunp->next;
+ 	    }
+diff -Naur glibc-2.20/locale/programs/ld-messages.c glibc-2.20-patch/locale/programs/ld-messages.c
+--- glibc-2.20/locale/programs/ld-messages.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/ld-messages.c	2015-03-04 00:51:32.377952006 -0600
+@@ -25,6 +25,7 @@
+ #include <string.h>
+ #include <stdint.h>
+ #include <sys/uio.h>
++#include <gnu/option-groups.h>
+ 
+ #include <assert.h>
+ 
+@@ -124,6 +125,7 @@
+     }
+   else
+     {
++#if __OPTION_POSIX_REGEXP
+       int result;
+       regex_t re;
+ 
+@@ -140,6 +142,7 @@
+ 	}
+       else if (result != 0)
+ 	regfree (&re);
++#endif
+     }
+ 
+   if (messages->noexpr == NULL)
+@@ -158,6 +161,7 @@
+     }
+   else
+     {
++#if __OPTION_POSIX_REGEXP
+       int result;
+       regex_t re;
+ 
+@@ -174,6 +178,7 @@
+ 	}
+       else if (result != 0)
+ 	regfree (&re);
++#endif
+     }
+ }
+ 
+diff -Naur glibc-2.20/locale/programs/ld-time.c glibc-2.20-patch/locale/programs/ld-time.c
+--- glibc-2.20/locale/programs/ld-time.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/ld-time.c	2015-03-04 00:51:32.378952006 -0600
+@@ -215,8 +215,10 @@
+ 	}
+       else
+ 	{
++	  static const uint32_t wt_fmt_ampm[]
++	    = { '%','I',':','%','M',':','%','S',' ','%','p',0 };
+ 	  time->t_fmt_ampm = "%I:%M:%S %p";
+-	  time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
++	  time->wt_fmt_ampm = wt_fmt_ampm;
+ 	}
+     }
+ 
+@@ -226,7 +228,7 @@
+       const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
+ 				       31, 31, 30, 31 ,30, 31 };
+       size_t idx;
+-      wchar_t *wstr;
++      uint32_t *wstr;
+ 
+       time->era_entries =
+ 	(struct era_data *) xmalloc (time->num_era
+@@ -464,18 +466,18 @@
+ 	    }
+ 
+ 	  /* Now generate the wide character name and format.  */
+-	  wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end offset */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end start */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end end */
++	  wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */
+ 	  if (wstr != NULL)
+ 	    {
+-	      time->era_entries[idx].wname = (uint32_t *) wstr + 1;
+-	      wstr = wcschr (wstr + 1, L':');	/* end name */
++	      time->era_entries[idx].wname = wstr + 1;
++	      wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */
+ 	      if (wstr != NULL)
+ 		{
+ 		  *wstr = L'\0';
+-		  time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
++		  time->era_entries[idx].wformat = wstr + 1;
+ 		}
+ 	      else
+ 		time->era_entries[idx].wname =
+@@ -530,7 +532,16 @@
+   if (time->date_fmt == NULL)
+     time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
+   if (time->wdate_fmt == NULL)
+-    time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
++    {
++      static const uint32_t wdate_fmt[] =
++	{ '%','a',' ',
++	  '%','b',' ',
++	  '%','e',' ',
++	  '%','H',':','%','M',':','%','S',' ',
++	  '%','Z',' ',
++	  '%','Y',0 };
++      time->wdate_fmt = wdate_fmt;
++    }
+ }
+ 
+ 
+diff -Naur glibc-2.20/locale/programs/linereader.c glibc-2.20-patch/locale/programs/linereader.c
+--- glibc-2.20/locale/programs/linereader.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/linereader.c	2015-03-04 00:51:32.378952006 -0600
+@@ -595,7 +595,7 @@
+ {
+   int return_widestr = lr->return_widestr;
+   char *buf;
+-  wchar_t *buf2 = NULL;
++  uint32_t *buf2 = NULL;
+   size_t bufact;
+   size_t bufmax = 56;
+ 
+diff -Naur glibc-2.20/locale/programs/localedef.c glibc-2.20-patch/locale/programs/localedef.c
+--- glibc-2.20/locale/programs/localedef.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/localedef.c	2015-03-04 00:51:32.378952006 -0600
+@@ -114,6 +114,7 @@
+ #define OPT_LIST_ARCHIVE 309
+ #define OPT_LITTLE_ENDIAN 400
+ #define OPT_BIG_ENDIAN 401
++#define OPT_UINT32_ALIGN 402
+ 
+ /* Definitions of arguments for argp functions.  */
+ static const struct argp_option options[] =
+@@ -150,6 +151,8 @@
+     N_("Generate little-endian output") },
+   { "big-endian", OPT_BIG_ENDIAN, NULL, 0,
+     N_("Generate big-endian output") },
++  { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0,
++    N_("Set the target's uint32_t alignment in bytes (default 4)") },
+   { NULL, 0, NULL, 0, NULL }
+ };
+ 
+@@ -239,12 +242,14 @@
+      ctype locale.  (P1003.2 4.35.5.2)  */
+   setlocale (LC_CTYPE, "POSIX");
+ 
++#ifndef NO_SYSCONF
+   /* Look whether the system really allows locale definitions.  POSIX
+      defines error code 3 for this situation so I think it must be
+      a fatal error (see P1003.2 4.35.8).  */
+   if (sysconf (_SC_2_LOCALEDEF) < 0)
+     WITH_CUR_LOCALE (error (3, 0, _("\
+ FATAL: system does not define `_POSIX2_LOCALEDEF'")));
++#endif
+ 
+   /* Process charmap file.  */
+   charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1);
+@@ -338,6 +343,9 @@
+     case OPT_BIG_ENDIAN:
+       set_big_endian (true);
+       break;
++    case OPT_UINT32_ALIGN:
++      uint32_align_mask = strtol (arg, NULL, 0) - 1;
++      break;
+     case 'c':
+       force_output = 1;
+       break;
+diff -Naur glibc-2.20/locale/programs/locfile.c glibc-2.20-patch/locale/programs/locfile.c
+--- glibc-2.20/locale/programs/locfile.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/locfile.c	2015-03-04 00:51:32.378952006 -0600
+@@ -544,6 +544,9 @@
+    machine running localedef.  */
+ bool swap_endianness_p;
+ 
++/* The target's value of __align__(uint32_t) - 1.  */
++unsigned int uint32_align_mask = 3;
++
+ /* When called outside a start_locale_structure/end_locale_structure
+    or start_locale_prelude/end_locale_prelude block, record that the
+    next byte in FILE's obstack will be the first byte of a new element.
+@@ -621,7 +624,7 @@
+ void
+ add_locale_wstring (struct locale_file *file, const uint32_t *string)
+ {
+-  add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
++  add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1);
+ }
+ 
+ /* Record that FILE's next element is the 32-bit integer VALUE.  */
+diff -Naur glibc-2.20/locale/programs/locfile.h glibc-2.20-patch/locale/programs/locfile.h
+--- glibc-2.20/locale/programs/locfile.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/programs/locfile.h	2015-03-04 00:51:32.379952006 -0600
+@@ -71,6 +71,8 @@
+ 
+ extern bool swap_endianness_p;
+ 
++extern unsigned int uint32_align_mask;
++
+ /* Change the output to be big-endian if BIG_ENDIAN is true and
+    little-endian otherwise.  */
+ static inline void
+@@ -275,4 +277,49 @@
+ 				   const struct charmap_t *charmap,
+ 				   const char *output_path);
+ 
++static inline size_t
++wcslen_uint32 (const uint32_t *str)
++{
++  size_t len = 0;
++  while (str[len] != 0)
++    len++;
++  return len;
++}
++
++static inline int
++wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n)
++{
++  while (n-- != 0)
++    {
++      int diff = *s1++ - *s2++;
++      if (diff != 0)
++	return diff;
++    }
++  return 0;
++}
++
++static inline int
++wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2)
++{
++  while (*s1 != 0 && *s1 == *s2)
++    s1++, s2++;
++  return *s1 - *s2;
++}
++
++static inline uint32_t *
++wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n)
++{
++  return memcpy (s1, s2, n * sizeof (uint32_t));
++}
++
++static inline uint32_t *
++wcschr_uint32 (const uint32_t *s, uint32_t ch)
++{
++  do
++    if (*s == ch)
++      return (uint32_t *) s;
++  while (*s++ != 0);
++  return 0;
++}
++
+ #endif /* locfile.h */
+diff -Naur glibc-2.20/locale/setlocale.c glibc-2.20-patch/locale/setlocale.c
+--- glibc-2.20/locale/setlocale.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/setlocale.c	2015-03-04 00:51:32.379952006 -0600
+@@ -64,36 +64,6 @@
+ #endif
+ 
+ 
+-/* Define an array of category names (also the environment variable names).  */
+-const union catnamestr_t _nl_category_names attribute_hidden =
+-  {
+-    {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-      category_name,
+-#include "categories.def"
+-#undef DEFINE_CATEGORY
+-    }
+-  };
+-
+-const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
+-  {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
+-#include "categories.def"
+-#undef DEFINE_CATEGORY
+-  };
+-
+-/* An array of their lengths, for convenience.  */
+-const uint8_t _nl_category_name_sizes[] attribute_hidden =
+-  {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-    [category] = sizeof (category_name) - 1,
+-#include "categories.def"
+-#undef	DEFINE_CATEGORY
+-    [LC_ALL] = sizeof ("LC_ALL") - 1
+-  };
+-
+-
+ #ifdef NL_CURRENT_INDIRECT
+ # define WEAK_POSTLOAD(postload) weak_extern (postload)
+ #else
+diff -Naur glibc-2.20/locale/xlocale.c glibc-2.20-patch/locale/xlocale.c
+--- glibc-2.20/locale/xlocale.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/locale/xlocale.c	2015-03-04 00:51:32.379952006 -0600
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <locale.h>
++#include <gnu/option-groups.h>
+ #include "localeinfo.h"
+ 
+ #define DEFINE_CATEGORY(category, category_name, items, a) \
+@@ -25,6 +26,19 @@
+ #include "categories.def"
+ #undef	DEFINE_CATEGORY
+ 
++/* If the locale support code isn't enabled, don't generate strong
++   reference to the C locale_data structures here; let the Makefile
++   decide which ones to include.  (In the static linking case, the
++   strong reference to the 'class', 'toupper', and 'tolower' tables
++   will cause C-ctype.o to be brought in, as it should be, even when
++   the reference to _nl_C_LC_CTYPE will be weak.)  */
++#if ! __OPTION_EGLIBC_LOCALE_CODE
++# define DEFINE_CATEGORY(category, category_name, items, a) \
++  weak_extern (_nl_C_##category)
++# include "categories.def"
++# undef	DEFINE_CATEGORY
++#endif
++
+ /* Defined in locale/C-ctype.c.  */
+ extern const char _nl_C_LC_CTYPE_class[] attribute_hidden;
+ extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden;
+@@ -52,3 +66,26 @@
+     .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
+     .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
+   };
++
++
++#if ! __OPTION_EGLIBC_LOCALE_CODE
++/* When locale code is enabled, these are each defined in the
++   appropriate lc-CATEGORY.c file, so that static links (when __thread
++   is supported) bring in only those lc-CATEGORY.o files for
++   categories the program actually uses; look for NL_CURRENT_INDIRECT
++   in localeinfo.h.
++
++   When locale code is disabled, the _nl_C_CATEGORY objects are the
++   only possible referents.  At the moment, there isn't a way to get
++   __OPTION_EGLIBC_LOCALE_CODE defined in every compilation unit that
++   #includes localeinfo.h, so we can't just turn off
++   NL_CURRENT_INDIRECT.  So we'll define the _nl_current_CATEGORY
++   pointers here.  */
++#if defined (NL_CURRENT_INDIRECT)
++#define DEFINE_CATEGORY(category, category_name, items, a)      \
++  __thread struct __locale_data * const *_nl_current_##category   \
++  attribute_hidden = &_nl_C_locobj.__locales[category];
++#include "categories.def"
++#undef DEFINE_CATEGORY
++#endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+diff -Naur glibc-2.20/localedata/Makefile glibc-2.20-patch/localedata/Makefile
+--- glibc-2.20/localedata/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/localedata/Makefile	2015-03-04 00:51:32.379952006 -0600
+@@ -21,12 +21,22 @@
+ 
+ include ../Makeconfig
+ 
+-# List with all available character set descriptions.
+-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
++include ../option-groups.mak
+ 
+ # List with all available character set descriptions.
+-locales := $(wildcard locales/*)
++all-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
++
++all-locales := $(wildcard locales/*)
+ 
++# If the EGLIBC_LOCALES option group is not enabled, trim the
++# list of charmap and locale source files.
++ifeq ($(OPTION_EGLIBC_LOCALES),y)
++charmaps := $(all-charmaps)
++locales  := $(all-locales)
++else
++charmaps :=
++locales  := locales/POSIX
++endif
+ 
+ subdir-dirs = tests-mbwc
+ vpath %.c tests-mbwc
+@@ -71,14 +81,20 @@
+ 		     tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans      \
+ 		     tst_wctype tst_wcwidth
+ 
+-tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
++# Since these tests build their own locale files, they're not
++# dependent on the OPTION_EGLIBC_LOCALES option group.  But they do
++# need the locale functions to be present.
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++     += $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
+ 	tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \
+ 	tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
+ 	tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \
+ 	tst-wctype
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ tests-static = bug-setlocale1-static
+ tests += $(tests-static)
+-ifeq (yes,$(build-shared))
++endif
++ifeq (yesy,$(build-shared)$(OPTION_EGLIBC_LOCALE_CODE))
+ ifneq (no,$(PERL))
+ tests-special += $(objpfx)mtrace-tst-leaks.out
+ endif
+@@ -92,12 +108,14 @@
+ 
+ tests: $(objdir)/iconvdata/gconv-modules
+ 
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ tests-special += $(objpfx)sort-test.out $(objpfx)tst-fmon.out \
+ 		 $(objpfx)tst-locale.out $(objpfx)tst-rpmatch.out \
+ 		 $(objpfx)tst-trans.out $(objpfx)tst-ctype.out \
+ 		 $(objpfx)tst-langinfo.out $(objpfx)tst-langinfo-static.out \
+ 		 $(objpfx)tst-numeric.out
+ tests-static += tst-langinfo-static
++endif
+ 
+ ifeq ($(run-built-tests),yes)
+ # We have to generate locales
+@@ -213,6 +231,11 @@
+ 
+ include SUPPORTED
+ 
++# Only install locale data if OPTION_EGLIBC_LOCALES is selected.
++ifneq ($(OPTION_EGLIBC_LOCALES),y)
++SUPPORTED-LOCALES :=
++endif
++
+ INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES))
+ 
+ # Sometimes the whole collection of locale files should be installed.
+diff -Naur glibc-2.20/login/Makefile glibc-2.20-patch/login/Makefile
+--- glibc-2.20/login/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/login/Makefile	2015-03-04 00:51:32.379952006 -0600
+@@ -18,6 +18,7 @@
+ #
+ #	Sub-makefile for login portion of the library.
+ #
++include ../option-groups.mak
+ 
+ subdir	:= login
+ 
+@@ -25,14 +26,16 @@
+ 
+ headers	:= utmp.h bits/utmp.h lastlog.h pty.h
+ 
+-routines := getlogin getlogin_r setlogin getlogin_r_chk \
+-	    getutent getutent_r getutid getutline getutid_r getutline_r \
+-	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
+-	    ptsname_r_chk
++routines := getpt grantpt unlockpt ptsname ptsname_r_chk
++routines-$(OPTION_EGLIBC_UTMP) \
++	 += getutent getutent_r getutid getutline getutid_r getutline_r \
++	    utmp_file utmpname updwtmp
++routines-$(OPTION_EGLIBC_GETLOGIN) += getlogin getlogin_r getlogin_r_chk
++routines-$(OPTION_EGLIBC_BSD) += setlogin
+ 
+ CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"'
+ 
+-others = utmpdump
++others-$(OPTION_EGLIBC_UTMP) += utmpdump
+ 
+ ifeq (yes,$(build-pt-chown))
+ others += pt_chown
+@@ -46,8 +49,8 @@
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname
+ 
+ # Build the -lutil library with these extra functions.
+-extra-libs      := libutil
+-extra-libs-others := $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_UTMP) := libutil
++extra-libs-others := $(extra-libs-y)
+ 
+ libutil-routines:= login login_tty logout logwtmp openpty forkpty
+ 
+diff -Naur glibc-2.20/Makeconfig glibc-2.20-patch/Makeconfig
+--- glibc-2.20/Makeconfig	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/Makeconfig	2015-03-04 00:51:32.380952006 -0600
+@@ -582,7 +582,7 @@
+ # and run on the build system, causes that program with those
+ # arguments to be run on the host for which the library is built.
+ ifndef test-wrapper
+-test-wrapper =
++test-wrapper = $(cross-test-wrapper)
+ endif
+ # Likewise, but the name of the program is preceded by
+ # <variable>=<value> assignments for environment variables.
+@@ -1057,6 +1057,24 @@
+ libm = $(common-objpfx)math/libm.a
+ endif
+ 
++# Generate a header file that #defines preprocessor symbols indicating
++# which option groups are enabled.  Note that the option-groups.config file
++# may not exist at all.
++before-compile += $(common-objpfx)gnu/option-groups.h
++common-generated += gnu/option-groups.h gnu/option-groups.stmp
++headers += gnu/option-groups.h
++$(common-objpfx)gnu/option-groups.h: $(common-objpfx)gnu/option-groups.stmp; @:
++$(common-objpfx)gnu/option-groups.stmp:					\
++		$(..)scripts/option-groups.awk				\
++		$(..)option-groups.defaults				\
++		$(wildcard $(common-objpfx)option-groups.config)
++	$(make-target-directory)
++	@rm -f ${@:stmp=T} $@
++	LC_ALL=C $(AWK) -f $^ > ${@:stmp=T}
++	$(move-if-change) ${@:stmp=T} ${@:stmp=h}
++	touch $@
++
++
+ # These are the subdirectories containing the library source.  The order
+ # is more or less arbitrary.  The sorting step will take care of the
+ # dependencies.
+diff -Naur glibc-2.20/Makerules glibc-2.20-patch/Makerules
+--- glibc-2.20/Makerules	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/Makerules	2015-03-04 00:51:32.380952006 -0600
+@@ -379,6 +379,25 @@
+ endef
+ endif
+ \f
++# Include targets in the selected option groups.
++aux                  += $(aux-y)
++extra-libs           += $(extra-libs-y)
++extra-libs-others    += $(extra-libs-others-y)
++extra-objs           += $(extra-objs-y)
++install-bin          += $(install-bin-y)
++install-others       += $(install-others-y)
++install-sbin         += $(install-sbin-y)
++modules              += $(modules-y)
++others               += $(others-y)
++others-pie           += $(others-pie-y)
++routines             += $(routines-y)
++static-only-routines += $(static-only-routines-y)
++sysdep_routines      += $(sysdep_routines-y)
++test-srcs            += $(test-srcs-y)
++tests                += $(tests-y)
++xtests               += $(xtests-y)
++
++\f
+ # Modify the list of routines we build for different targets
+ 
+ ifeq (yes,$(build-shared))
+diff -Naur glibc-2.20/malloc/Makefile glibc-2.20-patch/malloc/Makefile
+--- glibc-2.20/malloc/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/malloc/Makefile	2015-03-04 00:51:32.380952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for malloc routines
+ #
++include ../option-groups.mak
++
+ subdir	:= malloc
+ 
+ include ../Makeconfig
+@@ -36,9 +38,15 @@
+ non-lib.a := libmcheck.a
+ 
+ # Additional library.
++ifeq ($(OPTION_EGLIBC_MEMUSAGE),y)
+ extra-libs = libmemusage
+ extra-libs-others = $(extra-libs)
+ 
++ifdef OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++CPPFLAGS-memusage += -D__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE=$(OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE)
++endif
++endif
++
+ libmemusage-routines = memusage
+ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
+ 
+@@ -67,7 +75,7 @@
+ # Unless we get a test for the availability of libgd which also works
+ # for cross-compiling we disable the memusagestat generation in this
+ # situation.
+-ifneq ($(cross-compiling),yes)
++ifeq ($(cross-compiling)$(OPTION_EGLIBC_MEMUSAGE),noy)
+ # If the gd library is available we build the `memusagestat' program.
+ ifneq ($(LIBGD),no)
+ others: $(objpfx)memusage
+diff -Naur glibc-2.20/malloc/memusage.c glibc-2.20-patch/malloc/memusage.c
+--- glibc-2.20/malloc/memusage.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/malloc/memusage.c	2015-03-04 00:51:32.380952006 -0600
+@@ -33,6 +33,7 @@
+ #include <stdint.h>
+ #include <sys/mman.h>
+ #include <sys/time.h>
++#include <gnu/option-groups.h>
+ 
+ #include <memusage.h>
+ 
+@@ -93,7 +94,11 @@
+ #define peak_stack      peak_use[1]
+ #define peak_total      peak_use[2]
+ 
+-#define DEFAULT_BUFFER_SIZE     32768
++#ifndef __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++# define DEFAULT_BUFFER_SIZE	32768
++#else
++# define DEFAULT_BUFFER_SIZE	__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++#endif
+ static size_t buffer_size;
+ 
+ static int fd = -1;
+diff -Naur glibc-2.20/malloc/memusage.sh glibc-2.20-patch/malloc/memusage.sh
+--- glibc-2.20/malloc/memusage.sh	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/malloc/memusage.sh	2015-03-04 00:51:32.381952006 -0600
+@@ -35,7 +35,7 @@
+ 
+ # Print help message
+ do_help() {
+-  echo $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
++  printf $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
+ Profile memory usage of PROGRAM.
+ 
+    -n,--progname=NAME     Name of the program file to profile
+diff -Naur glibc-2.20/math/Makefile glibc-2.20-patch/math/Makefile
+--- glibc-2.20/math/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/math/Makefile	2015-03-04 00:51:32.381952006 -0600
+@@ -21,6 +21,8 @@
+ 
+ include ../Makeconfig
+ 
++include ../option-groups.mak
++
+ # Installed header files.
+ headers		:= math.h bits/mathcalls.h bits/mathinline.h bits/huge_val.h \
+ 		   bits/huge_valf.h bits/huge_vall.h bits/inf.h bits/nan.h \
+@@ -33,8 +35,8 @@
+ 
+ # Build the -lm library.
+ 
+-extra-libs	:= libm
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_LIBM) := libm
++extra-libs-others-$(OPTION_EGLIBC_LIBM) = $(extra-libs-$(OPTION_EGLIBC_LIBM))
+ 
+ libm-support = k_standard s_lib_version s_matherr s_signgam		\
+ 	       fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg		\
+diff -Naur glibc-2.20/misc/err.c glibc-2.20-patch/misc/err.c
+--- glibc-2.20/misc/err.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/misc/err.c	2015-03-04 00:51:32.381952006 -0600
+@@ -22,6 +22,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <stdio.h>
++#include <gnu/option-groups.h>
+ 
+ #include <wchar.h>
+ #define flockfile(s) _IO_flockfile (s)
+@@ -37,6 +38,7 @@
+   va_end (ap);								      \
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ static void
+ convert_and_print (const char *format, __gnuc_va_list ap)
+ {
+@@ -81,6 +83,7 @@
+ 
+   __vfwprintf (stderr, wformat, ap);
+ }
++#endif
+ 
+ void
+ vwarnx (const char *format, __gnuc_va_list ap)
+@@ -88,9 +91,13 @@
+   flockfile (stderr);
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       __fwprintf (stderr, L"%s: ", __progname);
+       convert_and_print (format, ap);
+       putwc_unlocked (L'\n', stderr);
++#else
++      abort ();
++#endif
+     }
+   else
+     {
+@@ -111,6 +118,7 @@
+   flockfile (stderr);
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       __fwprintf (stderr, L"%s: ", __progname);
+       if (format)
+ 	{
+@@ -119,6 +127,9 @@
+ 	}
+       __set_errno (error);
+       __fwprintf (stderr, L"%m\n");
++#else
++      abort ();
++#endif
+     }
+   else
+     {
+diff -Naur glibc-2.20/misc/error.c glibc-2.20-patch/misc/error.c
+--- glibc-2.20/misc/error.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/misc/error.c	2015-03-04 00:51:32.381952006 -0600
+@@ -35,6 +35,7 @@
+ #endif
+ 
+ #ifdef _LIBC
++# include <gnu/option-groups.h>
+ # include <libintl.h>
+ # include <stdbool.h>
+ # include <stdint.h>
+@@ -205,6 +206,7 @@
+ #if _LIBC
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       size_t len = strlen (message) + 1;
+       wchar_t *wmessage = NULL;
+       mbstate_t st;
+@@ -265,6 +267,9 @@
+ 
+       if (use_malloc)
+ 	free (wmessage);
++#else
++      abort ();
++#endif
+     }
+   else
+ #endif
+diff -Naur glibc-2.20/misc/Makefile glibc-2.20-patch/misc/Makefile
+--- glibc-2.20/misc/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/misc/Makefile	2015-03-04 00:51:32.381952006 -0600
+@@ -19,6 +19,10 @@
+ #	Sub-makefile for misc portion of the library.
+ #
+ 
++# Some system-dependent implementations of these functions use option
++# groups (see sysdeps/unix/sysv/linux/Makefile, for example).
++include ../option-groups.mak
++
+ subdir	:= misc
+ 
+ include ../Makeconfig
+@@ -46,40 +50,47 @@
+ 	    select pselect \
+ 	    acct chroot fsync sync fdatasync syncfs reboot \
+ 	    gethostid sethostid \
+-	    revoke vhangup \
++	    vhangup \
+ 	    swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
+ 	    mkostemp mkostemp64 mkstemps mkstemps64 mkostemps mkostemps64 \
+ 	    ualarm usleep \
+ 	    gtty stty \
+ 	    ptrace \
+-	    fstab mntent mntent_r \
++	    mntent mntent_r \
+ 	    utimes lutimes futimes futimesat \
+ 	    truncate ftruncate truncate64 ftruncate64 \
+-	    chflags fchflags \
+ 	    insremque getttyent getusershell getpass ttyslot \
+ 	    syslog syscall daemon \
+ 	    mmap mmap64 munmap mprotect msync madvise mincore remap_file_pages\
+ 	    mlock munlock mlockall munlockall \
+-	    efgcvt efgcvt_r qefgcvt qefgcvt_r \
+ 	    hsearch hsearch_r tsearch lsearch \
+ 	    err error ustat \
+-	    getsysstats dirname regexp \
++	    getsysstats dirname \
+ 	    getloadavg getclktck \
+ 	    fgetxattr flistxattr fremovexattr fsetxattr getxattr \
+ 	    listxattr lgetxattr llistxattr lremovexattr lsetxattr \
+ 	    removexattr setxattr getauxval ifunc-impl-list
+ 
++routines-$(OPTION_POSIX_REGEXP) += regexp
++routines-$(OPTION_EGLIBC_FSTAB) += fstab
++routines-$(OPTION_EGLIBC_BSD) += chflags fchflags revoke
++routines-$(OPTION_EGLIBC_FCVT) += efgcvt efgcvt_r qefgcvt qefgcvt_r
++
+ generated += tst-error1.mtrace tst-error1-mem.out
+ 
+ aux := init-misc
+ install-lib := libg.a
+ gpl2lgpl := error.c error.h
+ 
+-tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
+-	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
++tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
++	 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += tst-error1
++tests-$(OPTION_EGLIBC_FCVT) += tst-efgcvt
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
+ tests-special += $(objpfx)tst-error1-mem.out
+ endif
++endif
+ 
+ CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables
+ CFLAGS-tsearch.c = $(uses-callbacks)
+diff -Naur glibc-2.20/misc/sys/xattr.h glibc-2.20-patch/misc/sys/xattr.h
+--- glibc-2.20/misc/sys/xattr.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/misc/sys/xattr.h	2015-03-04 00:51:32.382952006 -0600
+@@ -26,7 +26,6 @@
+ 
+ /* The following constants should be used for the fifth parameter of
+    `*setxattr'.  */
+-#ifndef __USE_KERNEL_XATTR_DEFS
+ enum
+ {
+   XATTR_CREATE = 1,	/* set value, fail if attr already exists.  */
+@@ -34,7 +33,6 @@
+   XATTR_REPLACE = 2	/* set value, fail if attr does not exist.  */
+ #define XATTR_REPLACE	XATTR_REPLACE
+ };
+-#endif
+ 
+ /* Set the attribute NAME of the file pointed to by PATH to VALUE (which
+    is SIZE bytes long).  Return 0 on success, -1 for errors.  */
+diff -Naur glibc-2.20/misc/tst-efgcvt.c glibc-2.20-patch/misc/tst-efgcvt.c
+--- glibc-2.20/misc/tst-efgcvt.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/misc/tst-efgcvt.c	2015-03-04 00:51:32.382952006 -0600
+@@ -59,7 +59,7 @@
+   { 123.01, -4, 3, "" },
+   { 126.71, -4, 3, "" },
+   { 0.0, 4, 1, "0000" },
+-#if DBL_MANT_DIG == 53
++#if DBL_MANT_DIG == 53 && !(defined __powerpc__ && defined __NO_FPRS__ && !defined _SOFT_FLOAT && !defined _SOFT_DOUBLE)
+   { 0x1p-1074, 3, -323, "494" },
+   { -0x1p-1074, 3, -323, "494" },
+ #endif
+diff -Naur glibc-2.20/nis/Makefile glibc-2.20-patch/nis/Makefile
+--- glibc-2.20/nis/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nis/Makefile	2015-03-04 00:51:32.382952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for NIS/NIS+ part.
+ #
++include ../option-groups.mak
++
+ subdir	:= nis
+ 
+ include ../Makeconfig
+@@ -30,19 +32,26 @@
+ 
+ # These are the databases available for the nis (and perhaps later nisplus)
+ # service.  This must be a superset of the services in nss.
+-databases		= proto service hosts network grp pwd rpc ethers \
+-			  spwd netgrp alias publickey
++databases-y		:= proto service hosts network grp pwd rpc ethers \
++			   spwd netgrp publickey
++databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
+ 
+ # Specify rules for the nss_* modules.
+-services		:= nis nisplus compat
++# The 'compat' module includes nis support, and the 'nss' directory
++# includes a bare-bones "files" library, so we'll include 'compat' in
++# OPTION_EGLIBC_NIS.
++services-y		:=
++services-$(OPTION_EGLIBC_NIS) += nis nisplus compat
++
++extra-libs-$(OPTION_EGLIBC_NIS) += libnsl
++extra-libs-y		+= $(services-y:%=libnss_%)
+ 
+-extra-libs		= libnsl $(services:%=libnss_%)
+ # These libraries will be built in the `others' pass rather than
+ # the `lib' pass, because they depend on libc.so being built already.
+-extra-libs-others	= $(extra-libs)
++extra-libs-others-y	+= $(extra-libs-y)
+ 
+ # The sources are found in the appropriate subdir.
+-subdir-dirs = $(services:%=nss_%)
++subdir-dirs = $(services-y:%=nss_%)
+ vpath %.c $(subdir-dirs)
+ 
+ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
+@@ -60,11 +69,11 @@
+ libnss_compat-routines	:= $(addprefix compat-,grp pwd spwd initgroups)
+ libnss_compat-inhibit-o	= $(filter-out .os,$(object-suffixes))
+ 
+-libnss_nis-routines	:= $(addprefix nis-,$(databases)) nis-initgroups \
++libnss_nis-routines	:= $(addprefix nis-,$(databases-y)) nis-initgroups \
+ 			   nss-nis
+ libnss_nis-inhibit-o	= $(filter-out .os,$(object-suffixes))
+ 
+-libnss_nisplus-routines	:= $(addprefix nisplus-,$(databases)) nisplus-parser \
++libnss_nisplus-routines	:= $(addprefix nisplus-,$(databases-y)) nisplus-parser \
+ 			   nss-nisplus nisplus-initgroups
+ libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes))
+ 
+@@ -80,12 +89,12 @@
+ # Target-specific variable setting to link objects using deprecated
+ # RPC interfaces with the version of libc.so that makes them available
+ # for new links:
+-$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
++$(services-y:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
+   libc-for-link = $(libnsl-libc)
+ 
+ 
+ ifeq ($(build-shared),yes)
+-$(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
++$(others-y:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
+ else
+-$(others:%=$(objpfx)%): $(objpfx)libnsl.a
++$(others-y:%=$(objpfx)%): $(objpfx)libnsl.a
+ endif
+diff -Naur glibc-2.20/nptl/Makefile glibc-2.20-patch/nptl/Makefile
+--- glibc-2.20/nptl/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nptl/Makefile	2015-03-04 00:51:32.382952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for NPTL portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= nptl
+ 
+ include ../Makeconfig
+@@ -116,7 +118,7 @@
+ 		      pt-raise pt-system \
+ 		      flockfile ftrylockfile funlockfile \
+ 		      sigaction \
+-		      herrno res pt-allocrtsig \
++		      pt-allocrtsig \
+ 		      pthread_kill_other_threads \
+ 		      pthread_getaffinity pthread_setaffinity \
+ 		      pthread_attr_getaffinity pthread_attr_setaffinity \
+@@ -136,6 +138,8 @@
+ #		      pthread_setgid pthread_setegid pthread_setregid \
+ #		      pthread_setresgid
+ 
++libpthread-routines-$(OPTION_EGLIBC_INET) := herrno res
++
+ libpthread-shared-only-routines = version pt-allocrtsig unwind-forcedunwind
+ libpthread-static-only-routines = pthread_atfork
+ 
+@@ -210,7 +214,7 @@
+ 	tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
+ 	tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
+ 	tst-mutexpi9 \
+-	tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
++	tst-spin1 tst-spin2 tst-spin3 \
+ 	tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
+ 	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
+ 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
+@@ -244,14 +248,14 @@
+ 	tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
+ 	tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
+ 	tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
+-	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
++	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel25 \
+ 	tst-cancel-self tst-cancel-self-cancelstate \
+ 	tst-cancel-self-canceltype tst-cancel-self-testcancel \
+ 	tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
+ 	tst-flock1 tst-flock2 \
+ 	tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
+ 	tst-signal6 tst-signal7 \
+-	tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
++	tst-exec2 tst-exec3 tst-exec4 \
+ 	tst-exit1 tst-exit2 tst-exit3 \
+ 	tst-stdio1 tst-stdio2 \
+ 	tst-stack1 tst-stack2 tst-stack3 tst-pthread-getattr \
+@@ -259,13 +263,12 @@
+ 	tst-unload \
+ 	tst-dlsym1 \
+ 	tst-sysconf \
+-	tst-locale1 tst-locale2 \
++	tst-locale2 \
+ 	tst-umask1 \
+ 	tst-popen1 \
+ 	tst-clock1 \
+ 	tst-context1 \
+ 	tst-sched1 \
+-	tst-backtrace1 \
+ 	tst-abstime \
+ 	tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
+ 	tst-getpid1 tst-getpid2 tst-getpid3 \
+@@ -275,6 +278,17 @@
+ 	tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
+ test-srcs = tst-oddstacklimit
+ 
++# This test uses the posix_spawn functions.
++tests-$(OPTION_EGLIBC_SPAWN) += tst-exec1
++
++# This test uses the 'backtrace' functions.
++tests-$(OPTION_EGLIBC_BACKTRACE) += tst-backtrace1
++
++# This test is written in C++.
++tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24
++
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-locale1
++
+ # Files which must not be linked with libpthread.
+ tests-nolibpthread = tst-unload
+ 
+@@ -363,12 +377,18 @@
+ 		    $(common-objpfx)libc.a
+ 
+ tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \
+-		tst-cancel21-static tst-cancel24-static tst-cond8-static \
++		tst-cancel21-static tst-cond8-static \
+ 		tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
+ 		tst-sem12-static
+-tests += tst-stackguard1-static tst-cancel21-static tst-cancel24-static \
++
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++tests-static += tst-cancel24-static
++endif
++
++tests += tst-stackguard1-static tst-cancel21-static \
+ 	 tst-cond8-static tst-mutex8-static tst-mutexpi8-static \
+ 	 tst-sem11-static tst-sem12-static
++tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24-static
+ xtests-static += tst-setuid1-static
+ 
+ # These tests are linked with libc before libpthread
+diff -Naur glibc-2.20/nptl/pthread_create.c glibc-2.20-patch/nptl/pthread_create.c
+--- glibc-2.20/nptl/pthread_create.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nptl/pthread_create.c	2015-03-04 00:51:32.382952006 -0600
+@@ -31,6 +31,7 @@
+ #include <kernel-features.h>
+ #include <exit-thread.h>
+ 
++#include <gnu/option-groups.h>
+ #include <shlib-compat.h>
+ 
+ #include <stap-probe.h>
+@@ -240,8 +241,10 @@
+   THREAD_SETMEM (pd, cpuclock_offset, now);
+ #endif
+ 
++#if __OPTION_EGLIBC_INET
+   /* Initialize resolver state pointer.  */
+   __resp = &pd->res;
++#endif
+ 
+   /* Initialize pointers to locale data.  */
+   __ctype_init ();
+@@ -322,8 +325,10 @@
+   /* Run the destructor for the thread-local data.  */
+   __nptl_deallocate_tsd ();
+ 
++#if __OPTION_EGLIBC_INET
+   /* Clean up any state libc stored in thread-local variables.  */
+   __libc_thread_freeres ();
++#endif
+ 
+   /* If this is the last thread we terminate the process now.  We
+      do not notify the debugger, it might just irritate it if there
+diff -Naur glibc-2.20/nscd/Makefile glibc-2.20-patch/nscd/Makefile
+--- glibc-2.20/nscd/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nscd/Makefile	2015-03-04 00:51:32.383952006 -0600
+@@ -18,14 +18,17 @@
+ #
+ #	Sub-makefile for nscd portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= nscd
+ 
+ include ../Makeconfig
+ 
+ ifneq ($(use-nscd),no)
+-routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
++routines-$(OPTION_EGLIBC_INET) += \
++	     nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
+ 	    nscd_initgroups nscd_getserv_r nscd_netgroup
+-aux	:= nscd_helper
++aux-$(OPTION_EGLIBC_INET) += nscd_helper
+ endif
+ 
+ # To find xmalloc.c
+@@ -37,14 +40,18 @@
+ 		dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
+ 		xmalloc xstrdup aicache initgrcache gai res_hconf \
+ 		netgroupcache
+-
++ifneq (y,$(OPTION_EGLIBC_NIS))
++# If we haven't build libnsl.so, then we'll need to include our
++# own copy of nis_hash.
++nscd-modules += nis_hash
++endif
+ ifeq ($(build-nscd)$(have-thread-library),yesyes)
+ 
+-others += nscd
+-others-pie += nscd
+-install-sbin := nscd
++others-$(OPTION_EGLIBC_INET) += nscd
++others-pie-$(OPTION_EGLIBC_INET) += nscd
++install-sbin-$(OPTION_EGLIBC_INET) += nscd
+ 
+-extra-objs = $(nscd-modules:=.o)
++extra-objs-$(OPTION_EGLIBC_INET) += $(nscd-modules:=.o)
+ 
+ endif
+ 
+@@ -101,7 +108,15 @@
+ $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o)
+ 
+ ifeq ($(build-shared),yes)
+-$(objpfx)nscd: $(shared-thread-library) $(common-objpfx)nis/libnsl.so
++$(objpfx)nscd: $(shared-thread-library)
++else
++$(objpfx)nscd: $(static-thread-library)
++endif
++
++ifeq (y,$(OPTION_EGLIBC_NIS))
++ifeq ($(build-shared),yes)
++$(objpfx)nscd: $(common-objpfx)nis/libnsl.so
+ else
+-$(objpfx)nscd: $(static-thread-library) $(common-objpfx)nis/libnsl.a
++$(objpfx)nscd: $(common-objpfx)nis/libnsl.a
++endif
+ endif
+diff -Naur glibc-2.20/nscd/nis_hash.c glibc-2.20-patch/nscd/nis_hash.c
+--- glibc-2.20/nscd/nis_hash.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/nscd/nis_hash.c	2015-03-04 00:51:32.383952006 -0600
+@@ -0,0 +1,3 @@
++/* If OPTION_EGLIBC_NIS is disabled, nscd can't get this from libnsl.so;
++   we need our own copy.  */
++#include "../nis/nis_hash.c"
+diff -Naur glibc-2.20/nss/fixed-nsswitch.conf glibc-2.20-patch/nss/fixed-nsswitch.conf
+--- glibc-2.20/nss/fixed-nsswitch.conf	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/nss/fixed-nsswitch.conf	2015-03-04 00:51:32.383952006 -0600
+@@ -0,0 +1,22 @@
++# /etc/nsswitch.conf
++#
++# Example configuration for fixed name service.
++# See the description of OPTION_EGLIBC_NSSWITCH in option-groups.def
++# for details.
++#
++
++aliases:        files
++
++passwd:         files
++group:          files
++shadow:         files
++
++hosts:          files dns
++networks:       files dns
++
++protocols:      files
++services:       files
++ethers:         files
++rpc:            files
++
++netgroup:       files
+diff -Naur glibc-2.20/nss/fixed-nsswitch.functions glibc-2.20-patch/nss/fixed-nsswitch.functions
+--- glibc-2.20/nss/fixed-nsswitch.functions	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/nss/fixed-nsswitch.functions	2015-03-04 00:51:32.383952006 -0600
+@@ -0,0 +1,121 @@
++/* List of functions defined for fixed NSS in GNU C Library.
++   Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   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.  */
++
++/* When OPTION_EGLIBC_NSSWITCH is disabled (see option-groups.def),
++   EGLIBC does not use the 'dlopen' and 'dlsym' functions to look for
++   database query functions in the individual name service libraries.
++   Instead, it uses a set of functions chosen at compile time, as
++   directed by the OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS file.  This
++   file is a sample of what you might use there.
++
++   This file is C source code; it should only contain invocations of
++   the following macros:
++
++   - DEFINE_ENT (DATABASE, SERVICE, X)
++
++     Declare the 'setXent', 'getXent_r', and 'endXent' functions that
++     query DATABASE using the service library 'libnss_SERVICE.so.2'.
++     DATABASE should be the full name of the database as it appears in
++     'nsswitch.conf', like 'passwd' or 'aliases'.
++
++     (The non-reentrant 'getXent' functions are implemented in terms
++     of the reentrant 'getXent_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++   - DEFINE_GETBY (DATABASE, SERVICE, X, KEY)
++
++     Declare the 'getXbyKEY_r' functions that query DATABASE using
++     SERVICE.  DATABASE and SERVICE are as described above.
++
++     (The non-reentrant 'getXbyKEY' functions are implemented in terms
++     of the reentrant 'getXbyKEY_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++     Use the special key 'name3' for the service library function that
++     implements the 'getaddrinfo' function.
++
++   - DEFINE_GET (DATABASE, SERVICE, QUERY)
++
++     Declare the 'getQUERY_r' functions that query DATABASE using
++     SERVICE.  This is used for functions like 'getpwnam'.
++
++     (The non-reentrant 'getQUERY' functions are implemented in terms
++     of the reentrant 'getQUERY_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++   This sample file only includes functions that consult the files in
++   '/etc', and the Domain Name System (DNS).  */
++
++/* aliases */
++DEFINE_ENT (aliases, files, alias)
++DEFINE_GETBY (aliases, files, alias, name)
++
++/* ethers */
++DEFINE_ENT (ethers, files, ether)
++
++/* group */
++DEFINE_ENT (group, files, gr)
++DEFINE_GET (group, files, grgid)
++DEFINE_GET (group, files, grnam)
++
++/* hosts */
++DEFINE_ENT (hosts, files, host)
++DEFINE_GETBY (hosts, files, host, addr)
++DEFINE_GETBY (hosts, files, host, name)
++DEFINE_GETBY (hosts, files, host, name2)
++DEFINE_GET (hosts, files, hostton)
++DEFINE_GET (hosts, files, ntohost)
++DEFINE_GETBY (hosts, dns, host, addr)
++DEFINE_GETBY (hosts, dns, host, name)
++DEFINE_GETBY (hosts, dns, host, name2)
++DEFINE_GETBY (hosts, dns, host, name3)
++
++/* netgroup */
++DEFINE_ENT (netgroup, files, netgr)
++
++/* networks */
++DEFINE_ENT (networks, files, net)
++DEFINE_GETBY (networks, files, net, name)
++DEFINE_GETBY (networks, files, net, addr)
++DEFINE_GETBY (networks, dns, net, name)
++DEFINE_GETBY (networks, dns, net, addr)
++
++/* protocols */
++DEFINE_ENT (protocols, files, proto)
++DEFINE_GETBY (protocols, files, proto, name)
++DEFINE_GETBY (protocols, files, proto, number)
++
++/* passwd */
++DEFINE_ENT (passwd, files, pw)
++DEFINE_GET (passwd, files, pwnam)
++DEFINE_GET (passwd, files, pwuid)
++
++/* rpc */
++DEFINE_ENT (rpc, files, rpc)
++DEFINE_GETBY (rpc, files, rpc, name)
++DEFINE_GETBY (rpc, files, rpc, number)
++
++/* services */
++DEFINE_ENT (services, files, serv)
++DEFINE_GETBY (services, files, serv, name)
++DEFINE_GETBY (services, files, serv, port)
++
++/* shadow */
++DEFINE_ENT (shadow, files, sp)
++DEFINE_GET (shadow, files, spnam)
+diff -Naur glibc-2.20/nss/gen-fixed-nsswitch.c glibc-2.20-patch/nss/gen-fixed-nsswitch.c
+--- glibc-2.20/nss/gen-fixed-nsswitch.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/nss/gen-fixed-nsswitch.c	2015-03-04 00:51:32.383952006 -0600
+@@ -0,0 +1,803 @@
++/* gen-fixed-nsswitch.c --- generate fixed name service data structures
++   Copyright (C) 1996-1999, 2001-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.  */
++
++#define _GNU_SOURCE
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <errno.h>
++#include <string.h>
++#include <stdarg.h>
++#include <assert.h>
++#include <ctype.h>
++
++#include "gnu/lib-names.h"
++#include "nss.h"
++
++/* Provide a fallback definition to allow this file to be compiled outside
++   libc.  */
++#ifndef internal_function
++# define internal_function
++#endif
++
++\f
++/* Simple utilities.  */
++
++void __attribute__ ((noreturn))
++error (const char *message)
++{
++  fprintf (stderr, "%s\n", message);
++  exit (1);
++}
++
++
++void *
++check_alloc (void *p)
++{
++  if (p)
++    return p;
++  else
++    error ("out of memory");
++}
++
++void *
++xmalloc (size_t size)
++{
++  return check_alloc (malloc (size));
++}
++
++
++/* Format ARGS according to FORMAT, and return the result as a
++   malloc'ed string.  */
++char *
++saprintf (const char *format, ...)
++{
++  va_list args;
++  size_t len;
++  char *buf;
++
++  va_start (args, format);
++  len = vsnprintf (NULL, 0, format, args);
++  va_end (args);
++
++  buf = xmalloc (len + 1);
++  va_start (args, format);
++  assert (len == vsnprintf (buf, len + 1, format, args));
++  va_end (args);
++
++  return buf;
++}
++
++
++\f
++/* Data structures representing the configuration file in memory.  */
++
++/* These are copied from nsswitch.h.
++
++   We could simply #include that file, but this program runs on the
++   build machine and links against the build machine's libraries,
++   whereas that header is meant for use by target code; it uses
++   'libc_hidden_proto', 'internal_function', and related hair.  Since
++   we've copied the parsing code, we might as well copy the data
++   structure definitions as well.  */
++
++/* Actions performed after lookup finished.  */
++typedef enum
++{
++  NSS_ACTION_CONTINUE,
++  NSS_ACTION_RETURN
++} lookup_actions;
++
++
++typedef struct service_library
++{
++  /* Name of service (`files', `dns', `nis', ...).  */
++  const char *name;
++  /* Pointer to the loaded shared library.  */
++  void *lib_handle;
++  /* And the link to the next entry.  */
++  struct service_library *next;
++} service_library;
++
++
++/* For mapping a function name to a function pointer.  It is known in
++   nsswitch.c:nss_lookup_function that a string pointer for the lookup key
++   is the first member.  */
++typedef struct
++{
++  const char *fct_name;
++  void *fct_ptr;
++} known_function;
++
++
++typedef struct service_user
++{
++  /* And the link to the next entry.  */
++  struct service_user *next;
++  /* Action according to result.  */
++  lookup_actions actions[5];
++  /* Link to the underlying library object.  */
++  service_library *library;
++  /* Collection of known functions.
++
++     With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
++     'tsearch'-style tree.
++
++     With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
++     pointers to known_function structures, NULL-terminated.  */
++  union
++  {
++    void *tree;
++    const known_function **array;
++  } known;
++  /* Name of the service (`files', `dns', `nis', ...).  */
++  const char *name;
++} service_user;
++
++/* To access the action based on the status value use this macro.  */
++#define nss_next_action(ni, status) ((ni)->actions[2 + status])
++
++
++typedef struct name_database_entry
++{
++  /* And the link to the next entry.  */
++  struct name_database_entry *next;
++  /* List of service to be used.  */
++  service_user *service;
++  /* Name of the database.  */
++  const char *name;
++} name_database_entry;
++
++
++typedef struct name_database
++{
++  /* List of all known databases.  */
++  name_database_entry *entry;
++  /* List of libraries with service implementation.  */
++  service_library *library;
++} name_database;
++
++
++\f
++/* Gathering the contents of the FIXED_FUNCTIONS file.  */
++
++/* It should be possible to generate this list automatically by
++   looking at the services and databases used in the nsswitch.conf
++   file, and having a hard-coded set of queries supported on each
++   database.  */
++
++/* We #include the FIXED_FUNCTIONS file several times to build an
++   array of function structures holding its data.  */
++enum function_kind {
++  fk_end = 0,                   /* Last entry.  */
++  fk_setent,                    /* Like setpwent.  */
++  fk_getent,                    /* Like getpwent.  */
++  fk_endent,                    /* Like endpwent.  */
++  fk_getby,                     /* Like gethostbyname.  */
++  fk_get                        /* Like getpwnam.  */
++};
++
++
++struct function {
++  /* What kind of function this is.  */
++  enum function_kind kind;
++
++  /* The database and service of the function being hardwired in.  */
++  char *database, *service;
++
++  /* The kind of entry being queried, for 'fk_setent', 'fk_getent',
++     'fk_endent', and 'fk_getby' functions.  */
++  char *entry;
++
++  /* The key, for 'fk_getby' entries.  */
++  char *key;
++
++  /* The value and key, for 'fk_get' entries.  */
++  char *value_and_key;
++};
++
++
++const struct function functions[] =
++  {
++
++#define DEFINE_ENT(database, service, entry)    \
++    { fk_setent, #database, #service, #entry }, \
++    { fk_getent, #database, #service, #entry }, \
++    { fk_endent, #database, #service, #entry },
++#define DEFINE_GETBY(database, service, entry, key)   \
++    { fk_getby, #database, #service, #entry, #key },
++#define DEFINE_GET(database, service, value_and_key)     \
++    { fk_get, #database, #service, NULL, NULL, #value_and_key },
++
++#include FIXED_FUNCTIONS
++
++#undef DEFINE_ENT
++#undef DEFINE_GETBY
++#undef DEFINE_GET
++
++    { fk_end }
++  };
++
++\f
++/* Parsing the config file.  Functions copied from nsswitch.c.  */
++
++#define __strchrnul strchrnul
++#define __getline getline
++#define __strncasecmp strncasecmp
++
++/* Prototypes for the local functions.  */
++static name_database *nss_parse_file (const char *fname) internal_function;
++static name_database_entry *nss_getline (char *line) internal_function;
++static service_user *nss_parse_service_list (const char *line)
++     internal_function;
++
++static name_database *
++internal_function
++nss_parse_file (const char *fname)
++{
++  FILE *fp;
++  name_database *result;
++  name_database_entry *last;
++  char *line;
++  size_t len;
++
++  /* Open the configuration file.  */
++  fp = fopen (fname, "rc");
++  if (fp == NULL)
++    return NULL;
++
++  // /* No threads use this stream.  */
++  // __fsetlocking (fp, FSETLOCKING_BYCALLER);
++
++  result = (name_database *) xmalloc (sizeof (name_database));
++
++  result->entry = NULL;
++  result->library = NULL;
++  last = NULL;
++  line = NULL;
++  len = 0;
++  do
++    {
++      name_database_entry *this;
++      ssize_t n;
++
++      n = __getline (&line, &len, fp);
++      if (n < 0)
++	break;
++      if (line[n - 1] == '\n')
++	line[n - 1] = '\0';
++
++      /* Because the file format does not know any form of quoting we
++	 can search forward for the next '#' character and if found
++	 make it terminating the line.  */
++      *__strchrnul (line, '#') = '\0';
++
++      /* If the line is blank it is ignored.  */
++      if (line[0] == '\0')
++	continue;
++
++      /* Each line completely specifies the actions for a database.  */
++      this = nss_getline (line);
++      if (this != NULL)
++	{
++	  if (last != NULL)
++	    last->next = this;
++	  else
++	    result->entry = this;
++
++	  last = this;
++	}
++    }
++  while (!feof_unlocked (fp));
++
++  /* Free the buffer.  */
++  free (line);
++  /* Close configuration file.  */
++  fclose (fp);
++
++  return result;
++}
++
++
++/* Read the source names:
++	`( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
++   */
++static service_user *
++internal_function
++nss_parse_service_list (const char *line)
++{
++  service_user *result = NULL, **nextp = &result;
++
++  while (1)
++    {
++      service_user *new_service;
++      const char *name;
++
++      while (isspace (line[0]))
++	++line;
++      if (line[0] == '\0')
++	/* No source specified.  */
++	return result;
++
++      /* Read <source> identifier.  */
++      name = line;
++      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
++	++line;
++      if (name == line)
++	return result;
++
++
++      new_service = (service_user *) xmalloc (sizeof (*new_service));
++      new_service->name = (char *) xmalloc (line - name + 1);
++
++      *((char *) __mempcpy ((char *) new_service->name, name, line - name))
++        = '\0';
++
++      /* Set default actions.  */
++      new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
++      new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
++      new_service->library = NULL;
++      new_service->known.tree = NULL;
++      new_service->next = NULL;
++
++      while (isspace (line[0]))
++	++line;
++
++      if (line[0] == '[')
++	{
++	  /* Read criterions.  */
++	  do
++	    ++line;
++	  while (line[0] != '\0' && isspace (line[0]));
++
++	  do
++	    {
++	      int not;
++	      enum nss_status status;
++	      lookup_actions action;
++
++	      /* Grok ! before name to mean all statii but that one.  */
++	      not = line[0] == '!';
++	      if (not)
++		++line;
++
++	      /* Read status name.  */
++	      name = line;
++	      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
++		     && line[0] != ']')
++		++line;
++
++	      /* Compare with known statii.  */
++	      if (line - name == 7)
++		{
++		  if (__strncasecmp (name, "SUCCESS", 7) == 0)
++		    status = NSS_STATUS_SUCCESS;
++		  else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
++		    status = NSS_STATUS_UNAVAIL;
++		  else
++		    return result;
++		}
++	      else if (line - name == 8)
++		{
++		  if (__strncasecmp (name, "NOTFOUND", 8) == 0)
++		    status = NSS_STATUS_NOTFOUND;
++		  else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
++		    status = NSS_STATUS_TRYAGAIN;
++		  else
++		    return result;
++		}
++	      else
++		return result;
++
++	      while (isspace (line[0]))
++		++line;
++	      if (line[0] != '=')
++		return result;
++	      do
++		++line;
++	      while (isspace (line[0]));
++
++	      name = line;
++	      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
++		     && line[0] != ']')
++		++line;
++
++	      if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
++		action = NSS_ACTION_RETURN;
++	      else if (line - name == 8
++		       && __strncasecmp (name, "CONTINUE", 8) == 0)
++		action = NSS_ACTION_CONTINUE;
++	      else
++		return result;
++
++	      if (not)
++		{
++		  /* Save the current action setting for this status,
++		     set them all to the given action, and reset this one.  */
++		  const lookup_actions save = new_service->actions[2 + status];
++		  new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action;
++		  new_service->actions[2 + NSS_STATUS_UNAVAIL] = action;
++		  new_service->actions[2 + NSS_STATUS_NOTFOUND] = action;
++		  new_service->actions[2 + NSS_STATUS_SUCCESS] = action;
++		  new_service->actions[2 + status] = save;
++		}
++	      else
++		new_service->actions[2 + status] = action;
++
++	      /* Skip white spaces.  */
++	      while (isspace (line[0]))
++		++line;
++	    }
++	  while (line[0] != ']');
++
++	  /* Skip the ']'.  */
++	  ++line;
++	}
++
++      *nextp = new_service;
++      nextp = &new_service->next;
++    }
++}
++
++static name_database_entry *
++internal_function
++nss_getline (char *line)
++{
++  const char *name;
++  name_database_entry *result;
++  size_t len;
++
++  /* Ignore leading white spaces.  ATTENTION: this is different from
++     what is implemented in Solaris.  The Solaris man page says a line
++     beginning with a white space character is ignored.  We regard
++     this as just another misfeature in Solaris.  */
++  while (isspace (line[0]))
++    ++line;
++
++  /* Recognize `<database> ":"'.  */
++  name = line;
++  while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':')
++    ++line;
++  if (line[0] == '\0' || name == line)
++    /* Syntax error.  */
++    return NULL;
++  *line++ = '\0';
++
++  len = strlen (name) + 1;
++
++  result = (name_database_entry *) xmalloc (sizeof (*result));
++  result->name = (char *) xmalloc (len);
++
++  /* Save the database name.  */
++  memcpy ((char *) result->name, name, len);
++
++  /* Parse the list of services.  */
++  result->service = nss_parse_service_list (line);
++
++  result->next = NULL;
++  return result;
++}
++
++
++\f
++/* Generating code for statically initialized nsswitch structures.  */
++
++
++/* Return the service-neutral suffix of the name of the service
++   library function referred to by the function F.  The result is
++   allocated with malloc.  */
++char *
++known_function_suffix (const struct function *f)
++{
++  switch (f->kind)
++    {
++    case fk_setent:
++      return saprintf ("set%sent", f->entry);
++
++    case fk_getent:
++      return saprintf ("get%sent_r", f->entry);
++
++    case fk_endent:
++      return saprintf ("end%sent", f->entry);
++
++    case fk_getby:
++      return saprintf ("get%sby%s_r", f->entry, f->key);
++
++    case fk_get:
++      return saprintf ("get%s_r", f->value_and_key);
++
++    default:
++      abort ();
++    }
++}
++
++
++/* Return the name of the service library function referred to by the
++   function F.  The result is allocated with malloc.  */
++char *
++known_function_name (const struct function *f)
++{
++  return saprintf ("_nss_%s_%s", f->service, known_function_suffix (f));
++}
++
++
++/* Write initialized known_function structures to OUT for
++   all the functions we'll use.  */
++void
++generate_known_functions (FILE *out)
++{
++  int i;
++
++  /* First, generate weak references to the functions.  The service
++     libraries depend on libc, and if these references weren't weak,
++     we'd be making libc depend circularly on the service
++     libraries.  */
++  for (i = 0; functions[i].kind; i++)
++    {
++      char *name = known_function_name (&functions[i]);
++      fprintf (out, "typeof (%s) %s __attribute__ ((weak));\n",
++               name, name);
++    }
++  fputs ("\n", out);
++
++  /* Then, a table mapping names to functions.  */
++  fputs ("static const known_function fixed_known_functions[] = {\n",
++         out);
++  for (i = 0; functions[i].kind; i++)
++    {
++      const struct function *f = &functions[i];
++      char *suffix = known_function_suffix (f);
++
++      fprintf (out, "  /* %2d */ { \"%s\", _nss_%s_%s },\n",
++               i, suffix, f->service, suffix);
++    }
++  fputs ("};\n", out);
++  fputs ("\n", out);
++}
++
++
++/* Print code to OUT for an initialized array of pointers to the
++   'known_function' structures needed for USER, which is for
++   DATABASE.  Return its name, allocated with malloc.  */
++char *
++generate_known_function_list (FILE *out,
++                              const name_database_entry *database,
++                              const service_user *user)
++{
++  char *list_name = saprintf ("fixed_%s_%s_known_funcs",
++                              database->name, user->name);
++  fprintf (out, "static const known_function *%s[] = {\n",
++           list_name);
++  int i;
++  for (i = 0; functions[i].kind; i++)
++    if (strcmp (functions[i].database, database->name) == 0
++        && strcmp (functions[i].service, user->name) == 0)
++      fprintf (out, "  &fixed_known_functions[%d], /* %s */\n",
++               i, known_function_name (&functions[i]));
++  fputs ("  NULL\n", out);
++  fputs ("};\n", out);
++  fputs ("\n", out);
++
++  return list_name;
++}
++
++
++/* Return the name of the status value STATUS, as a statically
++   allocated string.  */
++const char *
++lookup_status_name (enum nss_status status)
++{
++  switch (status)
++    {
++    case NSS_STATUS_TRYAGAIN: return "NSS_STATUS_TRYAGAIN";
++    case NSS_STATUS_UNAVAIL: return "NSS_STATUS_UNAVAIL";
++    case NSS_STATUS_NOTFOUND: return "NSS_STATUS_NOTFOUND";
++    case NSS_STATUS_SUCCESS: return "NSS_STATUS_SUCCESS";
++    case NSS_STATUS_RETURN: return "NSS_STATUS_RETURN";
++    default: abort ();
++    };
++}
++
++
++/* Return the name of ACTION as a statically allocated string.  */
++const char *
++lookup_action_name (lookup_actions action)
++{
++  switch (action)
++    {
++    case NSS_ACTION_CONTINUE: return "NSS_ACTION_CONTINUE";
++    case NSS_ACTION_RETURN: return "NSS_ACTION_RETURN";
++    default: abort ();
++    }
++}
++
++
++/* Print code to OUT for the list of service_user structures starting
++   with USER, which are all for DATABASE.  Return the name of the
++   first structure in that list, or zero if USER is NULL.  */
++char *
++generate_service_user_list (FILE *out,
++                            name_database_entry *database,
++                            service_user *user)
++{
++  if (user)
++    {
++      /* Generate the tail of the list.  */
++      char *next_name = generate_service_user_list (out, database, user->next);
++      /* Generate our known function list.  */
++      char *known_function_list_name =
++        generate_known_function_list (out, database, user);
++
++      char *name = saprintf ("fixed_%s_%s_user", database->name, user->name);
++
++      fprintf (out, "static const service_user %s = {\n", name);
++      if (next_name)
++        fprintf (out, "  (service_user *) &%s,\n", next_name);
++      else
++        fprintf (out, "  NULL, /* no next entry */\n");
++      fputs ("  {\n", out);
++      int i;
++      for (i = 0; i < sizeof (user->actions) / sizeof (user->actions[0]); i++)
++        fprintf (out, "    %s, /* %s */\n",
++                 lookup_action_name (user->actions[i]),
++                 lookup_status_name (i - 2));
++      fputs ("  },\n", out);
++      fprintf (out, "  NULL,  /* we never need the service library */\n");
++      fprintf (out, "  { .array = %s },\n", known_function_list_name);
++      fprintf (out, "  \"%s\"\n", user->name);
++      fputs ("};\n", out);
++      fputs ("\n", out);
++
++      return name;
++    }
++  else
++    return NULL;
++}
++
++
++/* Print code to OUT for the list of name_database_entry structures
++   starting with DATABASE.  Return the name of the first structure
++   in that list, or zero if DATABASE is NULL.  */
++char *
++generate_name_database_entries (FILE *out, name_database_entry *database)
++{
++  if (database)
++    {
++      char *next_name = generate_name_database_entries (out, database->next);
++      char *service_user_name
++        = generate_service_user_list (out, database, database->service);
++      char *name = saprintf ("fixed_%s_name_database", database->name);
++
++      fprintf (out, "static const name_database_entry %s = {\n", name);
++
++      if (next_name)
++        fprintf (out, "  (name_database_entry *) &%s,\n", next_name);
++      else
++        fprintf (out, "  NULL,\n");
++
++      if (service_user_name)
++        fprintf (out, "  (service_user *) &%s,\n", service_user_name);
++      else
++        fprintf (out, "  NULL,\n");
++
++      fprintf (out, "  \"%s\"\n", database->name);
++      fprintf (out, "};\n");
++      fputs ("\n", out);
++
++      return name;
++    }
++  else
++    return NULL;
++}
++
++
++void
++generate_name_database (FILE *out, name_database *service_table)
++{
++  /* Produce a linked list of the known name_database_entry
++     structures.  */
++  char *entries = generate_name_database_entries (out, service_table->entry);
++
++  /* Now produce the main structure that points to them all.  */
++  fprintf (out, "static const name_database fixed_name_database = {\n");
++  if (entries)
++    fprintf (out, "  (name_database_entry *) &%s,\n", entries);
++  else
++    fprintf (out, "  NULL,\n");
++  fputs ("  NULL /* we don't need the libraries */\n"
++         "};\n",
++         out);
++}
++
++
++\f
++/* Generating the list of service libraries we generate references to.  */
++
++/* String with revision number of the shared object files.  */
++static const char *const nss_shlib_revision = LIBNSS_FILES_SO + 15;
++
++void
++generate_service_lib_list (FILE *out, name_database *service_table)
++{
++  int i, j;
++  int printed_any = 0;
++
++  for (i = 0; functions[i].kind; i++)
++    {
++      /* Mention each service library only once.  */
++      for (j = 0; j < i; j++)
++        if (strcmp (functions[i].service, functions[j].service) == 0)
++          break;
++
++      if (j >= i)
++        {
++          if (printed_any)
++            putc (' ', out);
++          fprintf (out, "-lnss_%s",
++                   functions[i].service,
++                   nss_shlib_revision);
++          printed_any = 1;
++        }
++    }
++}
++
++\f
++/* Main.  */
++
++int
++main (int argc, char **argv)
++{
++  if (argc != 4)
++    {
++      fprintf (stderr, "usage: gen-fixed-nsswitch HEADER SERVLIBS CONFIG\n");
++      exit (1);
++    }
++
++  name_database *service_table = nss_parse_file (argv[3]);
++
++  FILE *header = fopen (argv[1], "w");
++  if (! header)
++    {
++      fprintf (stderr,
++               "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
++               argv[1], strerror (errno));
++      exit (1);
++    }
++  fputs ("/* Generated by nss/gen-fixed-nsswitch.c.  */\n", header);
++  fputs ("\n", header);
++  generate_known_functions (header);
++  generate_name_database (header, service_table);
++  fclose (header);
++
++  FILE *service_lib_list = fopen (argv[2], "w");
++  if (! service_lib_list)
++    {
++      fprintf (stderr,
++               "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
++               argv[2], strerror (errno));
++      exit (1);
++    }
++  generate_service_lib_list (service_lib_list, service_table);
++  fclose (service_lib_list);
++
++  return 0;
++}
+diff -Naur glibc-2.20/nss/getent.c glibc-2.20-patch/nss/getent.c
+--- glibc-2.20/nss/getent.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nss/getent.c	2015-03-04 00:51:32.384952006 -0600
+@@ -39,6 +39,7 @@
+ #include <netinet/ether.h>
+ #include <netinet/in.h>
+ #include <sys/socket.h>
++#include <gnu/option-groups.h>
+ 
+ /* Get libc version number.  */
+ #include <version.h>
+@@ -91,6 +92,7 @@
+   fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
+ }
+ 
++#if __OPTION_EGLIBC_DB_ALIASES
+ /* This is for aliases */
+ static void
+ print_aliases (struct aliasent *alias)
+@@ -135,7 +137,9 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_DB_ALIASES */
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for ethers */
+ static int
+ ethers_keys (int number, char *key[])
+@@ -179,6 +183,7 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* This is for group */
+ static void
+@@ -301,6 +306,7 @@
+   return result;
+ }
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for hosts */
+ static void
+ print_hosts (struct hostent *host)
+@@ -598,6 +604,7 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* Now is all for passwd */
+ static void
+@@ -650,6 +657,7 @@
+   return result;
+ }
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for protocols */
+ static void
+ print_protocols (struct protoent *proto)
+@@ -805,6 +813,7 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* This is for shadow */
+ static void
+@@ -871,21 +880,34 @@
+   } databases[] =
+   {
+ #define D(name) { #name, name ## _keys },
+-D(ahosts)
+-D(ahostsv4)
+-D(ahostsv6)
+-D(aliases)
+-D(ethers)
++
++#if __OPTION_EGLIBC_INET
++#define DN(name) D(name)
++#else
++#define DN(name)
++#endif
++
++#if __OPTION_EGLIBC_DB_ALIASES
++#define DA(name) D(name)
++#else
++#define DA(name)
++#endif
++
++DN(ahosts)
++DN(ahostsv4)
++DN(ahostsv6)
++DA(aliases)
++DN(ethers)
+ D(group)
+ D(gshadow)
+-D(hosts)
++DN(hosts)
+ D(initgroups)
+-D(netgroup)
+-D(networks)
++DN(netgroup)
++DN(networks)
+ D(passwd)
+-D(protocols)
+-D(rpc)
+-D(services)
++DN(protocols)
++DN(rpc)
++DN(services)
+ D(shadow)
+ #undef D
+     { NULL, NULL }
+diff -Naur glibc-2.20/nss/getnssent_r.c glibc-2.20-patch/nss/getnssent_r.c
+--- glibc-2.20/nss/getnssent_r.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nss/getnssent_r.c	2015-03-04 00:51:32.384952006 -0600
+@@ -16,6 +16,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <errno.h>
++#include <gnu/option-groups.h>
+ #include <netdb.h>
+ #include "nsswitch.h"
+ 
+@@ -59,11 +60,13 @@
+   } fct;
+   int no_more;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       __set_h_errno (NETDB_INTERNAL);
+       return;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Cycle through the services and run their `setXXent' functions until
+      we find an available service.  */
+@@ -101,11 +104,13 @@
+   } fct;
+   int no_more;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       __set_h_errno (NETDB_INTERNAL);
+       return;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Cycle through all the services and run their endXXent functions.  */
+   no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
+@@ -141,12 +146,14 @@
+   int no_more;
+   enum nss_status status;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       *h_errnop = NETDB_INTERNAL;
+       *result = NULL;
+       return errno;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Initialize status to return if no more functions are found.  */
+   status = NSS_STATUS_NOTFOUND;
+@@ -161,7 +168,7 @@
+       int is_last_nip = *nip == *last_nip;
+ 
+       status = DL_CALL_FCT (fct.f,
+-			    (resbuf, buffer, buflen, &errno, &h_errno));
++			    (resbuf, buffer, buflen, &errno, h_errnop));
+ 
+       /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
+ 	 provided buffer is too small.  In this case we should give
+diff -Naur glibc-2.20/nss/Makefile glibc-2.20-patch/nss/Makefile
+--- glibc-2.20/nss/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nss/Makefile	2015-03-04 00:51:32.384952006 -0600
+@@ -18,29 +18,36 @@
+ #
+ #	Makefile for name service switch.
+ #
++include ../option-groups.mak
++
+ subdir	:= nss
+ 
+ include ../Makeconfig
+ 
+ headers			:= nss.h
+ 
+-# This is the trivial part which goes into libc itself.
+-routines		= nsswitch getnssent getnssent_r digits_dots \
+-			  $(addsuffix -lookup,$(databases))
+-
+ # These are the databases that go through nss dispatch.
+ # Caution: if you add a database here, you must add its real name
+ # in databases.def, too.
+-databases		= proto service hosts network grp pwd rpc ethers \
+-			  spwd netgrp key alias sgrp
++databases-y		= grp pwd spwd sgrp
++databases-$(OPTION_EGLIBC_INET) \
++			+= proto service hosts network rpc ethers \
++			   netgrp key
++databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
++
++# This is the trivial part which goes into libc itself.
++routines-y		+= nsswitch getnssent getnssent_r \
++			  $(addsuffix -lookup,$(databases-y))
++routines-$(OPTION_EGLIBC_INET) += digits_dots
+ 
+ others                  := getent makedb
+ install-bin             := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs		+= $(makedb-modules:=.o)
+ 
+-tests			= test-netdb tst-nss-test1 test-digits-dots
+-xtests			= bug-erange
++tests			= tst-nss-test1
++tests-$(OPTION_EGLIBC_INET) += test-netdb test-digits-dots
++xtests-$(OPTION_EGLIBC_INET) += bug-erange
+ 
+ # Specify rules for the nss_* modules.  We have some services.
+ services		:= files db
+@@ -55,7 +62,7 @@
+ vpath %.c $(subdir-dirs) ../locale/programs ../intl
+ 
+ 
+-libnss_files-routines	:= $(addprefix files-,$(databases)) \
++libnss_files-routines	:= $(addprefix files-,$(databases-y)) \
+ 			   files-initgroups files-have_o_cloexec files-init
+ 
+ libnss_db-dbs		:= $(addprefix db-,\
+@@ -78,6 +85,45 @@
+ tests			+= $(tests-static)
+ endif
+ 
++ifneq ($(OPTION_EGLIBC_NSSWITCH),y)
++
++ifndef OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG
++$(error OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG variable left unset)
++endif
++
++ifndef OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS
++$(error OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS variable left unset)
++endif
++
++ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)))
++$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed config file)
++$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG))
++endif
++
++ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)))
++$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed functions file)
++$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS))
++endif
++
++before-compile := $(objpfx)fixed-nsswitch.h
++generated := fixed-nsswitch.h
++$(objpfx)fixed-nsswitch.h $(objfpx)fixed-nsswitch-libs:	\
++    $(objpfx)gen-fixed-nsswitch				\
++    $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
++	$< $(objpfx)fixed-nsswitch.h			\
++	   $(objpfx)fixed-nsswitch-libs			\
++	   $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
++
++$(objpfx)gen-fixed-nsswitch: gen-fixed-nsswitch.c	\
++    $(common-objpfx)option-groups.config		\
++    $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)
++	$(native-compile)
++gen-fixed-nsswitch-CFLAGS =						\
++	-g3 -O -Wall							\
++	-I $(objpfx)							\
++	-DFIXED_FUNCTIONS='"$(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)"'
++endif
++
+ include ../Rules
+ 
+ ifeq (yes,$(have-selinux))
+diff -Naur glibc-2.20/nss/nsswitch.c glibc-2.20-patch/nss/nsswitch.c
+--- glibc-2.20/nss/nsswitch.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nss/nsswitch.c	2015-03-04 00:51:32.384952006 -0600
+@@ -26,6 +26,7 @@
+ #include <stdio_ext.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ #include <aliases.h>
+ #include <grp.h>
+@@ -41,6 +42,15 @@
+ #include "../nscd/nscd_proto.h"
+ #include <sysdep.h>
+ 
++/* When OPTION_EGLIBC_NSSWITCH is disabled, we use fixed tables of
++   databases and services, generated at library build time.  Thus:
++   - We can't reconfigure individual databases, so we don't need a
++     name-to-database map.
++   - We never add databases or service libraries, or look up functions
++     at runtime, so there's no need for a lock to protect our tables.
++   See ../option-groups.def for the details.  */
++#if __OPTION_EGLIBC_NSSWITCH
++
+ /* Prototypes for the local functions.  */
+ static name_database *nss_parse_file (const char *fname) internal_function;
+ static name_database_entry *nss_getline (char *line) internal_function;
+@@ -79,6 +89,9 @@
+ 
+ __libc_lock_define_initialized (static, lock)
+ 
++#define lock_nsswitch __libc_lock_lock (lock)
++#define unlock_nsswitch __libc_lock_unlock (lock)
++
+ #if !defined DO_STATIC_NSS || defined SHARED
+ /* String with revision number of the shared object files.  */
+ static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
+@@ -93,6 +106,20 @@
+    __libc_freeres.  */
+ static name_database_entry *defconfig_entries;
+ 
++#else /* __OPTION_EGLIBC_NSSWITCH */
++
++/* Bring in the statically initialized service table we generated at
++   build time.  */
++#include "fixed-nsswitch.h"
++
++const static name_database *service_table = &fixed_name_database;
++
++/* Nothing ever changes, so there's no need to lock anything.  */
++#define lock_nsswitch (0)
++#define unlock_nsswitch (0)
++
++#endif /* __OPTION_EGLIBC_NSSWITCH */
++
+ 
+ #ifdef USE_NSCD
+ /* Nonzero if this is the nscd process.  */
+@@ -109,20 +136,22 @@
+ 		       const char *defconfig, service_user **ni)
+ {
+   /* Prevent multiple threads to change the service table.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Reconsider database variable in case some other thread called
+      `__nss_configure_lookup' while we waited for the lock.  */
+   if (*ni != NULL)
+     {
+-      __libc_lock_unlock (lock);
++      unlock_nsswitch;
+       return 0;
+     }
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+   /* Are we initialized yet?  */
+   if (service_table == NULL)
+     /* Read config file.  */
+     service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
++#endif
+ 
+   /* Test whether configuration data is available.  */
+   if (service_table != NULL)
+@@ -144,6 +173,7 @@
+ 	    *ni = entry->service;
+     }
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+   /* No configuration data is available, either because nsswitch.conf
+      doesn't exist or because it doesn't have a line for this database.
+ 
+@@ -166,13 +196,23 @@
+ 	    {
+ 	      entry->next = defconfig_entries;
+ 	      entry->service = *ni;
+-	      entry->name[0] = '\0';
++	      entry->name = "";
+ 	      defconfig_entries = entry;
+ 	    }
+ 	}
+     }
++#else
++  /* Without the dynamic behavior, we can't process defconfig.  The
++     databases the user specified at library build time are all you
++     get.  */
++  if (*ni == NULL)
++    {
++      unlock_nsswitch;
++      return -1;
++    }
++#endif
+ 
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return *ni != NULL ? 0 : -1;
+ }
+@@ -252,6 +292,7 @@
+ libc_hidden_def (__nss_next2)
+ 
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+ int
+ attribute_compat_text_section
+ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
+@@ -300,13 +341,13 @@
+     }
+ 
+   /* Prevent multiple threads to change the service table.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Install new rules.  */
+   *databases[cnt].dbp = new_db;
+   __nss_database_custom[cnt] = true;
+ 
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return 0;
+ }
+@@ -402,7 +443,7 @@
+   void **found, *result;
+ 
+   /* We now modify global data.  Protect it.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Search the tree of functions previously requested.  Data in the
+      tree are `known_function' structures, whose first member is a
+@@ -413,7 +454,7 @@
+      enough to a pointer to our structure to use as a lookup key that
+      will be passed to `known_compare' (above).  */
+ 
+-  found = __tsearch (&fct_name, &ni->known, &known_compare);
++  found = __tsearch (&fct_name, &ni->known.tree, &known_compare);
+   if (found == NULL)
+     /* This means out-of-memory.  */
+     result = NULL;
+@@ -440,7 +481,7 @@
+ #endif
+ 	  /* Oops.  We can't instantiate this node properly.
+ 	     Remove it from the tree.  */
+-	  __tdelete (&fct_name, &ni->known, &known_compare);
++	  __tdelete (&fct_name, &ni->known.tree, &known_compare);
+ 	  free (known);
+ 	  result = NULL;
+ 	}
+@@ -520,13 +561,43 @@
+     }
+ 
+   /* Remove the lock.  */
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return result;
+ }
+ libc_hidden_def (__nss_lookup_function)
+ 
+ 
++#else /* below if ! __OPTION_EGLIBC_NSSWITCH */
++
++
++int
++__nss_configure_lookup (const char *dbname, const char *service_line)
++{
++  /* We can't dynamically configure lookup without
++     OPTION_EGLIBC_NSSWITCH.  */
++  __set_errno (EINVAL);
++  return -1;
++}
++
++
++void *
++__nss_lookup_function (service_user *ni, const char *fct_name)
++{
++  int i;
++  const known_function **known = ni->known.array;
++
++  for (i = 0; known[i]; i++)
++    if (strcmp (fct_name, known[i]->fct_name) == 0)
++      return known[i]->fct_ptr;
++
++  return NULL;
++}
++libc_hidden_def (__nss_lookup_function)
++#endif
++
++
++#if __OPTION_EGLIBC_NSSWITCH
+ static name_database *
+ internal_function
+ nss_parse_file (const char *fname)
+@@ -632,8 +703,10 @@
+ 					     + (line - name + 1));
+       if (new_service == NULL)
+ 	return result;
++      new_service->name = (char *) (new_service + 1);
+ 
+-      *((char *) __mempcpy (new_service->name, name, line - name)) = '\0';
++      *((char *) __mempcpy ((char *) new_service->name, name, line - name))
++        = '\0';
+ 
+       /* Set default actions.  */
+       new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
+@@ -642,7 +715,7 @@
+       new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
+       new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
+       new_service->library = NULL;
+-      new_service->known = NULL;
++      new_service->known.tree = NULL;
+       new_service->next = NULL;
+ 
+       while (isspace (line[0]))
+@@ -778,9 +851,10 @@
+   result = (name_database_entry *) malloc (sizeof (name_database_entry) + len);
+   if (result == NULL)
+     return NULL;
++  result->name = (char *) (result + 1);
+ 
+   /* Save the database name.  */
+-  memcpy (result->name, name, len);
++  memcpy ((char *) result->name, name, len);
+ 
+   /* Parse the list of services.  */
+   result->service = nss_parse_service_list (line);
+@@ -816,6 +890,7 @@
+   return *currentp;
+ }
+ #endif
++#endif /* __OPTION_EGLIBC_NSSWITCH */
+ 
+ 
+ #if defined SHARED && defined USE_NSCD
+@@ -834,6 +909,7 @@
+ }
+ 
+ 
++#if __OPTION_EGLIBC_INET
+ /* Called by nscd and nscd alone.  */
+ void
+ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
+@@ -857,8 +933,10 @@
+   __nss_not_use_nscd_services = -1;
+   __nss_not_use_nscd_netgroup = -1;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ #endif
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+ static void
+ free_database_entries (name_database_entry *entry)
+ {
+@@ -871,8 +949,8 @@
+ 	{
+ 	  service_user *olds = service;
+ 
+-	  if (service->known != NULL)
+-	    __tdestroy (service->known, free);
++	  if (service->known.tree != NULL)
++	    __tdestroy (service->known.tree, free);
+ 
+ 	  service = service->next;
+ 	  free (olds);
+@@ -926,3 +1004,4 @@
+ 
+   free (top);
+ }
++#endif /* __OPTION_EGLIBC_NSSWITCH */
+diff -Naur glibc-2.20/nss/nsswitch.h glibc-2.20-patch/nss/nsswitch.h
+--- glibc-2.20/nss/nsswitch.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/nss/nsswitch.h	2015-03-04 00:51:32.385952006 -0600
+@@ -65,10 +65,20 @@
+   lookup_actions actions[5];
+   /* Link to the underlying library object.  */
+   service_library *library;
+-  /* Collection of known functions.  */
+-  void *known;
++  /* Collection of known functions.
++
++     With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
++     'tsearch'-style tree.
++
++     With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
++     pointers to known_function structures, NULL-terminated.  */
++  union
++  {
++    void *tree;
++    const known_function **array;
++  } known;
+   /* Name of the service (`files', `dns', `nis', ...).  */
+-  char name[0];
++  const char *name;
+ } service_user;
+ 
+ /* To access the action based on the status value use this macro.  */
+@@ -82,7 +92,7 @@
+   /* List of service to be used.  */
+   service_user *service;
+   /* Name of the database.  */
+-  char name[0];
++  const char *name;
+ } name_database_entry;
+ 
+ 
+diff -Naur glibc-2.20/posix/bug-regex1.c glibc-2.20-patch/posix/bug-regex1.c
+--- glibc-2.20/posix/bug-regex1.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/bug-regex1.c	2015-03-04 00:51:32.385952006 -0600
+@@ -4,6 +4,7 @@
+ #include <string.h>
+ #include <regex.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ int
+ main (void)
+@@ -17,7 +18,9 @@
+   memset (&regex, '\0', sizeof (regex));
+ 
+   setlocale (LC_ALL, "de_DE.ISO-8859-1");
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+   fwide (stdout, -1);
++#endif
+ 
+   re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_DEBUG);
+ 
+diff -Naur glibc-2.20/posix/bug-regex6.c glibc-2.20-patch/posix/bug-regex6.c
+--- glibc-2.20/posix/bug-regex6.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/bug-regex6.c	2015-03-04 00:51:32.385952006 -0600
+@@ -22,6 +22,7 @@
+ #include <string.h>
+ #include <sys/types.h>
+ #include <regex.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -30,7 +31,12 @@
+   regex_t re;
+   regmatch_t mat[10];
+   int i, j, ret = 0;
+-  const char *locales[] = { "C", "de_DE.UTF-8" };
++  const char *locales[] = {
++    "C",
++#if __OPTION_EGLIBC_LOCALE_CODE
++    "de_DE.UTF-8"
++#endif
++  };
+   const char *string = "http://www.regex.com/pattern/matching.html#intro";
+   regmatch_t expect[10] = {
+     { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 },
+diff -Naur glibc-2.20/posix/fnmatch.c glibc-2.20-patch/posix/fnmatch.c
+--- glibc-2.20/posix/fnmatch.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/fnmatch.c	2015-03-04 00:51:32.385952006 -0600
+@@ -30,6 +30,10 @@
+ #include <ctype.h>
+ #include <string.h>
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined STDC_HEADERS || defined _LIBC
+ # include <stdlib.h>
+ #endif
+@@ -131,7 +135,7 @@
+ #   define ISWCTYPE(WC, WT)	iswctype (WC, WT)
+ #  endif
+ 
+-#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
++#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || (_LIBC && __OPTION_EGLIBC_LOCALE_CODE)
+ /* In this case we are implementing the multibyte character handling.  */
+ #   define HANDLE_MULTIBYTE	1
+ #  endif
+diff -Naur glibc-2.20/posix/fnmatch_loop.c glibc-2.20-patch/posix/fnmatch_loop.c
+--- glibc-2.20/posix/fnmatch_loop.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/fnmatch_loop.c	2015-03-04 00:51:32.385952006 -0600
+@@ -15,6 +15,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
++
+ #include <stdint.h>
+ 
+ struct STRUCT
+@@ -54,10 +56,15 @@
+   const char *collseq = (const char *)
+     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+ # else
++#  if __OPTION_EGLIBC_LOCALE_CODE
+   const UCHAR *collseq = (const UCHAR *)
+     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+-# endif
+-#endif
++#   define COLLSEQ_BYTE_LOOKUP(ix) (collseq[(ix)])
++#  else
++#   define COLLSEQ_BYTE_LOOKUP(ix) (ix)
++#  endif /* __OPTION_EGLIBC_LOCALE_CODE */
++# endif /* WIDE_CHAR_VERSION */
++#endif /* _LIBC */
+ 
+   while ((c = *p++) != L('\0'))
+     {
+@@ -277,7 +284,7 @@
+ 		    /* Leave room for the null.  */
+ 		    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
+ 		    size_t c1 = 0;
+-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
++#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ 		    wctype_t wt;
+ #endif
+ 		    const CHAR *startp = p;
+@@ -307,7 +314,7 @@
+ 		      }
+ 		    str[c1] = L('\0');
+ 
+-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
++#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ 		    wt = IS_CHAR_CLASS (str);
+ 		    if (wt == 0)
+ 		      /* Invalid character class name.  */
+@@ -681,8 +688,10 @@
+ 			else
+ 			  lcollseq = __collseq_table_lookup (collseq, cold);
+ # else
+-			fcollseq = collseq[fn];
+-			lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
++			fcollseq = COLLSEQ_BYTE_LOOKUP (fn);
++			lcollseq = (is_seqval
++                                    ? cold
++                                    : COLLSEQ_BYTE_LOOKUP ((UCHAR) cold));
+ # endif
+ 
+ 			is_seqval = 0;
+@@ -858,7 +867,7 @@
+ 				    goto matched;
+ 				  }
+ # else
+-				hcollseq = collseq[cend];
++				hcollseq = COLLSEQ_BYTE_LOOKUP (cend);
+ # endif
+ 			      }
+ 
+diff -Naur glibc-2.20/posix/glob.c glibc-2.20-patch/posix/glob.c
+--- glibc-2.20/posix/glob.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/glob.c	2015-03-04 00:51:32.386952006 -0600
+@@ -25,6 +25,9 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stddef.h>
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
+ 
+ /* Outcomment the following line for production quality code.  */
+ /* #define NDEBUG 1 */
+@@ -607,6 +610,7 @@
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    home_dir = "c:/users/default"; /* poor default */
+ #  else
++#   if ! _LIBC || __OPTION_EGLIBC_GETLOGIN
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    {
+ 	      int success;
+@@ -623,19 +627,19 @@
+ 	      if (success)
+ 		{
+ 		  struct passwd *p;
+-#   if defined HAVE_GETPWNAM_R || defined _LIBC
++#    if defined HAVE_GETPWNAM_R || defined _LIBC
+ 		  long int pwbuflen = GETPW_R_SIZE_MAX ();
+ 		  char *pwtmpbuf;
+ 		  struct passwd pwbuf;
+ 		  int malloc_pwtmpbuf = 0;
+ 		  int save = errno;
+ 
+-#    ifndef _LIBC
++#     ifndef _LIBC
+ 		  if (pwbuflen == -1)
+ 		    /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
+ 		       Try a moderate value.  */
+ 		    pwbuflen = 1024;
+-#    endif
++#     endif
+ 		  if (__libc_use_alloca (alloca_used + pwbuflen))
+ 		    pwtmpbuf = alloca_account (pwbuflen, alloca_used);
+ 		  else
+@@ -682,9 +686,9 @@
+ 			}
+ 		      __set_errno (save);
+ 		    }
+-#   else
++#    else
+ 		  p = getpwnam (name);
+-#   endif
++#    endif
+ 		  if (p != NULL)
+ 		    {
+ 		      if (!malloc_pwtmpbuf)
+@@ -713,6 +717,7 @@
+ 		    }
+ 		}
+ 	    }
++#   endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    {
+ 	      if (flags & GLOB_TILDE_CHECK)
+diff -Naur glibc-2.20/posix/Makefile glibc-2.20-patch/posix/Makefile
+--- glibc-2.20/posix/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/Makefile	2015-03-04 00:51:32.386952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for POSIX portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= posix
+ 
+ include ../Makeconfig
+@@ -43,13 +45,24 @@
+ 	getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid	      \
+ 	getresuid getresgid setresuid setresgid				      \
+ 	pathconf sysconf fpathconf					      \
+-	glob glob64 fnmatch regex					      \
++	glob glob64 fnmatch						      \
+ 	confstr								      \
+ 	getopt getopt1 getopt_init					      \
+ 	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
+ 	sched_primin sched_rr_gi sched_getaffinity sched_setaffinity	      \
+-	getaddrinfo gai_strerror wordexp				      \
+ 	pread pwrite pread64 pwrite64					      \
++	posix_madvise							      \
++	get_child_max sched_cpucount sched_cpualloc sched_cpufree
++
++routines-$(OPTION_EGLIBC_INET) += getaddrinfo gai_strerror
++
++ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
++routines-$(OPTION_POSIX_REGEXP) += regex
++else
++routines-$(OPTION_POSIX_REGEXP) += xregex
++endif
++
++routines-$(OPTION_EGLIBC_SPAWN) +=					      \
+ 	spawn_faction_init spawn_faction_destroy spawn_faction_addclose	      \
+ 	spawn_faction_addopen spawn_faction_adddup2			      \
+ 	spawnattr_init spawnattr_destroy				      \
+@@ -57,41 +70,53 @@
+ 	spawnattr_getflags spawnattr_setflags				      \
+ 	spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni	      \
+ 	spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \
+-	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
+-	posix_madvise							      \
+-	get_child_max sched_cpucount sched_cpualloc sched_cpufree
++	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam
++routines-$(OPTION_EGLIBC_WORDEXP) += wordexp
+ 
+ aux		:= init-posix environ
+-tests		:= tstgetopt testfnm runtests runptests	     \
++tests		:= tstgetopt testfnm runtests	     \
+ 		   tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \
+-		   tst-getlogin tst-mmap tst-getaddrinfo tst-truncate \
+-		   tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \
+-		   tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \
+-		   tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \
+-		   bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \
+-		   bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
+-		   bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
+-		   bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
+-		   bug-regex25 bug-regex26 bug-regex27 bug-regex28 \
+-		   bug-regex29 bug-regex30 bug-regex31 bug-regex32 \
+-		   bug-regex33 tst-nice tst-nanosleep tst-regex2 \
+-		   transbug tst-rxspencer tst-pcre tst-boost \
+-		   bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
+-		   tst-getaddrinfo2 bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
++		   tst-getlogin tst-mmap tst-truncate \
++		   tst-truncate64 tst-fork tst-dir \
++		   tst-chmod bug-regex2 bug-regex3 bug-regex4 \
++		   tst-gnuglob bug-regex6 bug-regex7 \
++		   bug-regex8 bug-regex9 bug-regex10 bug-regex12 \
++		   bug-regex14 bug-regex15 \
++		   bug-regex21 bug-regex24 \
++		   bug-regex27 bug-regex28 bug-regex29 bug-regex30 \
++		   bug-regex31 \
++		   tst-nice tst-nanosleep \
++		   transbug \
++		   tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
++		   bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
+ 		   tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
+ 		   tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
+ 		   tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
+-		   tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
+-		   tst-rfc3484-3 \
+-		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
++		   tst-execvp3 tst-execvp4 \
++		   tst-fnmatch2 tst-cpucount tst-cpuset \
+ 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
+ 		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
+ 		   tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
+ 		   tst-fnmatch3 bug-regex36
+-xtests		:= bug-ga2
++tests-$(OPTION_EGLIBC_LOCALE_CODE)					    \
++		+= tst-fnmatch tst-regexloc bug-regex1 bug-regex5 \
++		   bug-regex23 bug-regex25 bug-regex32 bug-regex33
++tests-$(OPTION_EGLIBC_INET) \
++	        += tst-getaddrinfo bug-ga1 tst-getaddrinfo2 \
++		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 tst-getaddrinfo3
++tests-$(OPTION_POSIX_REGEXP_GLIBC) \
++		+= runptests bug-regex11 bug-regex13 bug-regex16 \
++		   tst-regex2 tst-rxspencer tst-pcre tst-boost
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP_GLIBC))
++tests           += tst-regex bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
++		   bug-regex22 bug-regex26
++endif
++xtests-$(OPTION_EGLIBC_INET) += bug-ga2
+ ifeq (yes,$(build-shared))
+ test-srcs	:= globtest
+-tests           += wordexp-test tst-exec tst-spawn
++tests           += tst-exec
++tests-$(OPTION_EGLIBC_SPAWN) += tst-spawn
++tests-$(OPTION_EGLIBC_WORDEXP) += wordexp-test
+ endif
+ tests-static	= tst-exec-static tst-spawn-static
+ tests		+= $(tests-static)
+@@ -117,7 +142,10 @@
+ 
+ ifeq ($(run-built-tests),yes)
+ ifeq (yes,$(build-shared))
+-tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
++tests-special += $(objpfx)globtest.out
++ifeq (y,$(OPTION_EGLIBC_WORDEXP))
++tests-special += $(objpfx)wordexp-tst.out
++endif
+ endif
+ endif
+ 
+@@ -125,12 +153,16 @@
+ # XXX Please note that for now we ignore the result of this test.
+ tests-special += $(objpfx)annexc.out
+ ifeq ($(run-built-tests),yes)
+-tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
++tests-special += $(objpfx)bug-regex2-mem.out \
+ 		 $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
+-		 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
+-		 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
++		 $(objpfx)tst-getconf.out \
+ 		 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
+ 		 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
++ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
++tests-special += $(objpfx)bug-regex14-mem.out $(objpfx)tst-rxspencer-no-utf8-mem.out \
++  		 $(objpfx)tst-pcre-mem.out $(objpfx)tst-boost-mem.out
++endif
++
+ xtests-special += $(objpfx)bug-ga2-mem.out
+ endif
+ 
+@@ -143,6 +175,8 @@
+ 	$(SHELL) $< $(common-objpfx) '$(test-via-rtld-prefix)' \
+ 		'$(test-program-prefix)' '$(test-wrapper-env)'; \
+ 	$(evaluate-test)
++LDLIBS-globtest += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
++
+ $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
+ 	$(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \
+ 		 '$(run-program-env)' '$(test-program-prefix-after-env)'; \
+@@ -205,7 +239,10 @@
+ tst-chmod-ARGS = $(objdir)
+ tst-vfork3-ARGS = --test-dir=$(objpfx)
+ 
+-tst-rxspencer-ARGS = --utf8 rxspencer/tests
++tst-rxspencer-ARGS = rxspencer/tests
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++tst-rxspencer-ARGS += --utf8
++endif
+ tst-rxspencer-no-utf8-ARGS = rxspencer/tests
+ tst-pcre-ARGS = PCRE.tests
+ tst-boost-ARGS = BOOST.tests
+diff -Naur glibc-2.20/posix/regcomp.c glibc-2.20-patch/posix/regcomp.c
+--- glibc-2.20/posix/regcomp.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/regcomp.c	2015-03-04 00:51:32.387952006 -0600
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
+ static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
+ 					  size_t length, reg_syntax_t syntax);
+@@ -305,7 +306,7 @@
+ {
+   re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+   int node_cnt;
+-  int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
++  int icase = (dfa_mb_cur_max (dfa) == 1 && (bufp->syntax & RE_ICASE));
+   for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
+     {
+       int node = init_state->nodes.elems[node_cnt];
+@@ -315,9 +316,9 @@
+ 	{
+ 	  re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
+ #ifdef RE_ENABLE_I18N
+-	  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
++	  if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
+ 	    {
+-	      unsigned char *buf = alloca (dfa->mb_cur_max), *p;
++	      unsigned char *buf = alloca (dfa_mb_cur_max (dfa)), *p;
+ 	      wchar_t wc;
+ 	      mbstate_t state;
+ 
+@@ -348,7 +349,11 @@
+ 		  re_set_fastmap (fastmap, icase, ch);
+ 	    }
+ 	}
+-#ifdef RE_ENABLE_I18N
++
++      /* When OPTION_EGLIBC_LOCALE_CODE is disabled, the current
++         locale is always C, which has no rules and no multi-byte
++         characters.  */
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+       else if (type == COMPLEX_BRACKET)
+ 	{
+ 	  re_charset_t *cset = dfa->nodes[node].opr.mbcset;
+@@ -376,7 +381,7 @@
+ 	     i.e. where we would not find an invalid sequence.  This only
+ 	     applies to multibyte character sets; for single byte character
+ 	     sets, the SIMPLE_BRACKET again suffices.  */
+-	  if (dfa->mb_cur_max > 1
++	  if (dfa_mb_cur_max (dfa) > 1
+ 	      && (cset->nchar_classes || cset->non_match || cset->nranges
+ # ifdef _LIBC
+ 		  || cset->nequiv_classes
+@@ -404,7 +409,7 @@
+ 		  memset (&state, '\0', sizeof (state));
+ 		  if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
+ 		    re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+-		  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
++		  if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
+ 		    {
+ 		      if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
+ 			  != (size_t) -1)
+@@ -413,7 +418,7 @@
+ 		}
+ 	    }
+ 	}
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+       else if (type == OP_PERIOD
+ #ifdef RE_ENABLE_I18N
+ 	       || type == OP_UTF8_PERIOD
+@@ -856,11 +861,15 @@
+ 
+   dfa->mb_cur_max = MB_CUR_MAX;
+ #ifdef _LIBC
+-  if (dfa->mb_cur_max == 6
++  if (dfa_mb_cur_max (dfa) == 6
+       && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
+     dfa->is_utf8 = 1;
++# if __OPTION_EGLIBC_LOCALE_CODE
+   dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
+ 		       != 0);
++# else
++  dfa->map_notascii = 0;
++# endif
+ #else
+ # ifdef HAVE_LANGINFO_CODESET
+   codeset_name = nl_langinfo (CODESET);
+@@ -886,7 +895,7 @@
+ #endif
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     {
+       if (dfa->is_utf8)
+ 	dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
+@@ -1784,7 +1793,7 @@
+   token->word_char = 0;
+ #ifdef RE_ENABLE_I18N
+   token->mb_partial = 0;
+-  if (input->mb_cur_max > 1 &&
++  if (string_mb_cur_max (input) > 1 &&
+       !re_string_first_byte (input, re_string_cur_idx (input)))
+     {
+       token->type = CHARACTER;
+@@ -1805,7 +1814,7 @@
+       token->opr.c = c2;
+       token->type = CHARACTER;
+ #ifdef RE_ENABLE_I18N
+-      if (input->mb_cur_max > 1)
++      if (string_mb_cur_max (input) > 1)
+ 	{
+ 	  wint_t wc = re_string_wchar_at (input,
+ 					  re_string_cur_idx (input) + 1);
+@@ -1919,7 +1928,7 @@
+ 
+   token->type = CHARACTER;
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1)
++  if (string_mb_cur_max (input) > 1)
+     {
+       wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
+       token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+@@ -2019,7 +2028,7 @@
+   token->opr.c = c;
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1 &&
++  if (string_mb_cur_max (input) > 1 &&
+       !re_string_first_byte (input, re_string_cur_idx (input)))
+     {
+       token->type = CHARACTER;
+@@ -2242,7 +2251,7 @@
+ 	  return NULL;
+ 	}
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  while (!re_string_eoi (regexp)
+ 		 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
+@@ -2380,7 +2389,7 @@
+ 	  *err = REG_ESPACE;
+ 	  return NULL;
+ 	}
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	dfa->has_mb_node = 1;
+       break;
+     case OP_WORD:
+@@ -2686,7 +2695,7 @@
+        However, for !_LIBC we have no collation elements: if the
+        character set is single byte, the single byte character set
+        that we build below suffices.  parse_bracket_exp passes
+-       no MBCSET if dfa->mb_cur_max == 1.  */
++       no MBCSET if dfa_mb_cur_max (dfa) == 1.  */
+     if (mbcset)
+       {
+ 	/* Check the space of the arrays.  */
+@@ -2782,7 +2791,13 @@
+ 		   reg_syntax_t syntax, reg_errcode_t *err)
+ {
+ #ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+   const unsigned char *collseqmb;
++# define COLLSEQMB_LOOKUP(ix) (collseqmb[(ix)])
++#else
++# define COLLSEQMB_LOOKUP(ix) (ix)
++#endif
++
+   const char *collseqwc;
+   uint32_t nrules;
+   int32_t table_size;
+@@ -2830,18 +2845,20 @@
+ 	  if (MB_CUR_MAX == 1)
+ 	  */
+ 	  if (nrules == 0)
+-	    return collseqmb[br_elem->opr.ch];
++	    return COLLSEQMB_LOOKUP (br_elem->opr.ch);
+ 	  else
+ 	    {
+ 	      wint_t wc = __btowc (br_elem->opr.ch);
+ 	      return __collseq_table_lookup (collseqwc, wc);
+ 	    }
+ 	}
++#if __OPTION_EGLIBC_LOCALE_CODE
+       else if (br_elem->type == MB_CHAR)
+ 	{
+ 	  if (nrules != 0)
+ 	    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+ 	}
++#endif
+       else if (br_elem->type == COLL_SYM)
+ 	{
+ 	  size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+@@ -2872,11 +2889,11 @@
+ 		{
+ 		  /* No valid character.  Match it as a single byte
+ 		     character.  */
+-		  return collseqmb[br_elem->opr.name[0]];
++		  return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
+ 		}
+ 	    }
+ 	  else if (sym_name_len == 1)
+-	    return collseqmb[br_elem->opr.name[0]];
++	    return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
+ 	}
+       return UINT_MAX;
+     }
+@@ -2916,7 +2933,7 @@
+ 	 However, if we have no collation elements, and the character set
+ 	 is single byte, the single byte character set that we
+ 	 build below suffices. */
+-      if (nrules > 0 || dfa->mb_cur_max > 1)
++      if (nrules > 0 || dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  /* Check the space of the arrays.  */
+ 	  if (BE (*range_alloc == mbcset->nranges, 0))
+@@ -2953,7 +2970,7 @@
+ 	  if (MB_CUR_MAX == 1)
+ 	  */
+ 	  if (nrules == 0)
+-	    ch_collseq = collseqmb[ch];
++	    ch_collseq = COLLSEQMB_LOOKUP (ch);
+ 	  else
+ 	    ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+ 	  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+@@ -3031,7 +3048,10 @@
+   re_bitset_ptr_t sbcset;
+ #ifdef RE_ENABLE_I18N
+   re_charset_t *mbcset;
+-  int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
++  int coll_sym_alloc = 0, range_alloc = 0;
++#if __OPTION_EGLIBC_LOCALE_CODE
++  int mbchar_alloc = 0;
++#endif
+   int equiv_class_alloc = 0, char_class_alloc = 0;
+ #endif /* not RE_ENABLE_I18N */
+   int non_match = 0;
+@@ -3039,9 +3059,15 @@
+   int token_len;
+   int first_round = 1;
+ #ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+   collseqmb = (const unsigned char *)
+     _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+   nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++#else
++  /* This is true when OPTION_EGLIBC_LOCALE_CODE is disabled, but the
++     compiler can't figure that out.  */
++  nrules = 0;
++#endif
+   if (nrules)
+     {
+       /*
+@@ -3169,7 +3195,7 @@
+ #else
+ # ifdef RE_ENABLE_I18N
+ 	  *err = build_range_exp (sbcset,
+-				  dfa->mb_cur_max > 1 ? mbcset : NULL,
++				  dfa_mb_cur_max (dfa) > 1 ? mbcset : NULL,
+ 				  &range_alloc, &start_elem, &end_elem);
+ # else
+ 	  *err = build_range_exp (sbcset, &start_elem, &end_elem);
+@@ -3185,7 +3211,7 @@
+ 	    case SB_CHAR:
+ 	      bitset_set (sbcset, start_elem.opr.ch);
+ 	      break;
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+ 	    case MB_CHAR:
+ 	      /* Check whether the array has enough space.  */
+ 	      if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+@@ -3203,7 +3229,7 @@
+ 		}
+ 	      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
+ 	      break;
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+ 	    case EQUIV_CLASS:
+ 	      *err = build_equiv_class (sbcset,
+ #ifdef RE_ENABLE_I18N
+@@ -3253,11 +3279,11 @@
+ 
+ #ifdef RE_ENABLE_I18N
+   /* Ensure only single byte characters are set.  */
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     bitset_mask (sbcset, dfa->sb_char);
+ 
+   if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
+-      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
++      || mbcset->nranges || (dfa_mb_cur_max (dfa) > 1 && (mbcset->nchar_classes
+ 						     || mbcset->non_match)))
+     {
+       bin_tree_t *mbc_tree;
+@@ -3326,7 +3352,7 @@
+ 		       re_token_t *token, int token_len, re_dfa_t *dfa,
+ 		       reg_syntax_t syntax, int accept_hyphen)
+ {
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+   int cur_char_size;
+   cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
+   if (cur_char_size > 1)
+@@ -3336,7 +3362,7 @@
+       re_string_skip_bytes (regexp, cur_char_size);
+       return REG_NOERROR;
+     }
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+   re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+   if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+       || token->type == OP_OPEN_EQUIV_CLASS)
+@@ -3416,7 +3442,9 @@
+ build_equiv_class (bitset_t sbcset, const unsigned char *name)
+ #endif /* not RE_ENABLE_I18N */
+ {
+-#ifdef _LIBC
++  /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C locale
++     is supported; it has no collation rules.  */
++#if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+   uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+   if (nrules != 0)
+     {
+@@ -3488,7 +3516,7 @@
+       mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
+     }
+   else
+-#endif /* _LIBC */
++#endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+     {
+       if (BE (strlen ((const char *) name) != 1, 0))
+ 	return REG_ECOLLATE;
+@@ -3522,7 +3550,7 @@
+       && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
+     name = "alpha";
+ 
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+   /* Check the space of the arrays.  */
+   if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+     {
+@@ -3538,7 +3566,7 @@
+       *char_class_alloc = new_char_class_alloc;
+     }
+   mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+ 
+ #define BUILD_CHARCLASS_LOOP(ctype_func)	\
+   do {						\
+@@ -3649,7 +3677,7 @@
+ 
+ #ifdef RE_ENABLE_I18N
+   /* Ensure only single byte characters are set.  */
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     bitset_mask (sbcset, dfa->sb_char);
+ #endif
+ 
+@@ -3661,7 +3689,7 @@
+     goto build_word_op_espace;
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     {
+       bin_tree_t *mbc_tree;
+       /* Build a tree for complex bracket.  */
+diff -Naur glibc-2.20/posix/regexec.c glibc-2.20-patch/posix/regexec.c
+--- glibc-2.20/posix/regexec.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/regexec.c	2015-03-04 00:51:32.387952006 -0600
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
+ static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+ 				     int n) internal_function;
+@@ -186,11 +187,11 @@
+ static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+ 				    const re_string_t *input, int idx)
+      internal_function;
+-# ifdef _LIBC
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+ static unsigned int find_collation_sequence_value (const unsigned char *mbs,
+ 						   size_t name_len)
+      internal_function;
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ #endif /* RE_ENABLE_I18N */
+ static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
+ 				       const re_dfastate_t *state,
+@@ -255,25 +256,9 @@
+   return err != REG_NOERROR;
+ }
+ 
+-#ifdef _LIBC
+-# include <shlib-compat.h>
+-versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
+-
+-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+-__typeof__ (__regexec) __compat_regexec;
+-
+-int
+-attribute_compat_text_section
+-__compat_regexec (const regex_t *__restrict preg,
+-		  const char *__restrict string, size_t nmatch,
+-		  regmatch_t pmatch[], int eflags)
+-{
+-  return regexec (preg, string, nmatch, pmatch,
+-		  eflags & (REG_NOTBOL | REG_NOTEOL));
+-}
+-compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+-# endif
+-#endif
++/* EGLIBC: The code that used to be here was move to a separate file
++   so that it can be shared with xregex.c.  */
++#include "regexec-compat.c"
+ 
+ /* Entry points for GNU code.  */
+ 
+@@ -728,7 +713,7 @@
+   incr = (range < 0) ? -1 : 1;
+   left_lim = (range < 0) ? start + range : start;
+   right_lim = (range < 0) ? start : start + range;
+-  sb = dfa->mb_cur_max == 1;
++  sb = dfa_mb_cur_max (dfa) == 1;
+   match_kind =
+     (fastmap
+      ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+@@ -3448,7 +3433,7 @@
+ 	  if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+ 	    goto out_free;
+ 
+-	  if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
++	  if (dest_states[i] != dest_states_word[i] && dfa_mb_cur_max (dfa) > 1)
+ 	    need_word_trtable = 1;
+ 
+ 	  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+@@ -3590,7 +3575,7 @@
+       else if (type == OP_PERIOD)
+ 	{
+ #ifdef RE_ENABLE_I18N
+-	  if (dfa->mb_cur_max > 1)
++	  if (dfa_mb_cur_max (dfa) > 1)
+ 	    bitset_merge (accepts, dfa->sb_char);
+ 	  else
+ #endif
+@@ -3641,7 +3626,7 @@
+ 		  continue;
+ 		}
+ #ifdef RE_ENABLE_I18N
+-	      if (dfa->mb_cur_max > 1)
++	      if (dfa_mb_cur_max (dfa) > 1)
+ 		for (j = 0; j < BITSET_WORDS; ++j)
+ 		  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
+ 	      else
+@@ -3660,7 +3645,7 @@
+ 		  continue;
+ 		}
+ #ifdef RE_ENABLE_I18N
+-	      if (dfa->mb_cur_max > 1)
++	      if (dfa_mb_cur_max (dfa) > 1)
+ 		for (j = 0; j < BITSET_WORDS; ++j)
+ 		  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
+ 	      else
+@@ -3832,12 +3817,6 @@
+   if (node->type == COMPLEX_BRACKET)
+     {
+       const re_charset_t *cset = node->opr.mbcset;
+-# ifdef _LIBC
+-      const unsigned char *pin
+-	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
+-      int j;
+-      uint32_t nrules;
+-# endif /* _LIBC */
+       int match_len = 0;
+       wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
+ 		    ? re_string_wchar_at (input, str_idx) : 0);
+@@ -3849,6 +3828,7 @@
+ 	    match_len = char_len;
+ 	    goto check_node_accept_bytes_match;
+ 	  }
++#if __OPTION_EGLIBC_LOCALE_CODE
+       /* match with character_class?  */
+       for (i = 0; i < cset->nchar_classes; ++i)
+ 	{
+@@ -3859,8 +3839,16 @@
+ 	      goto check_node_accept_bytes_match;
+ 	    }
+ 	}
++#endif
++
++      /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C
++         locale is supported; it has no collation rules.  */
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
++      const unsigned char *pin
++	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
++      int j;
++      uint32_t nrules;
+ 
+-# ifdef _LIBC
+       nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+       if (nrules != 0)
+ 	{
+@@ -3953,8 +3941,12 @@
+ 	    }
+ 	}
+       else
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ 	{
++          /* In the _LIBC version, if OPTION_EGLIBC_LOCALE_CODE is
++             disabled, there can be no multibyte range endpoints, and
++             cset->nranges is always zero.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	  /* match with range expression?  */
+ #if __GNUC__ >= 2
+ 	  wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
+@@ -3973,6 +3965,7 @@
+ 		  goto check_node_accept_bytes_match;
+ 		}
+ 	    }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 	}
+     check_node_accept_bytes_match:
+       if (!cset->non_match)
+@@ -3988,7 +3981,7 @@
+   return 0;
+ }
+ 
+-# ifdef _LIBC
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+ static unsigned int
+ internal_function
+ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
+@@ -4046,7 +4039,7 @@
+       return UINT_MAX;
+     }
+ }
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ #endif /* RE_ENABLE_I18N */
+ 
+ /* Check whether the node accepts the byte which is IDX-th
+@@ -4137,7 +4130,7 @@
+   if (pstr->icase)
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	{
+ 	  ret = build_wcs_upper_buffer (pstr);
+ 	  if (BE (ret != REG_NOERROR, 0))
+@@ -4150,7 +4143,7 @@
+   else
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	build_wcs_buffer (pstr);
+       else
+ #endif /* RE_ENABLE_I18N  */
+diff -Naur glibc-2.20/posix/regexec-compat.c glibc-2.20-patch/posix/regexec-compat.c
+--- glibc-2.20/posix/regexec-compat.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/posix/regexec-compat.c	2015-03-04 00:51:32.388952006 -0600
+@@ -0,0 +1,39 @@
++/* Extended regular expression matching and search library.
++   Copyright (C) 2008 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
++
++   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.  */
++
++#ifdef _LIBC
++# include <shlib-compat.h>
++versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
++
++# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
++__typeof__ (__regexec) __compat_regexec;
++
++int
++attribute_compat_text_section
++__compat_regexec (const regex_t *__restrict preg,
++		  const char *__restrict string, size_t nmatch,
++		  regmatch_t pmatch[], int eflags)
++{
++  return regexec (preg, string, nmatch, pmatch,
++		  eflags & (REG_NOTBOL | REG_NOTEOL));
++}
++compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
++# endif
++#endif
+diff -Naur glibc-2.20/posix/regex.h glibc-2.20-patch/posix/regex.h
+--- glibc-2.20/posix/regex.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/regex.h	2015-03-04 00:51:32.388952006 -0600
+@@ -21,6 +21,7 @@
+ #define _REGEX_H 1
+ 
+ #include <sys/types.h>
++#include <gnu/option-groups.h>
+ 
+ /* Allow the use in C++ code.  */
+ #ifdef __cplusplus
+@@ -156,6 +157,8 @@
+    treated as 'a\{1'.  */
+ # define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+ 
++/* EGLIBC: Old regex implementation does not support these.  */
++# ifdef __OPTION_POSIX_REGEXP_GLIBC
+ /* If this bit is set, then ignore case when matching.
+    If not set, then case is significant.  */
+ # define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+@@ -172,6 +175,7 @@
+ /* If this bit is set, then no_sub will be set to 1 during
+    re_compile_pattern.  */
+ # define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
++# endif /* __OPTION_POSIX_REGEXP_GLIBC */
+ #endif
+ 
+ /* This global variable defines the particular regexp syntax to use (for
+@@ -231,8 +235,13 @@
+   (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
+    | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+ 
++#ifdef __OPTION_POSIX_REGEXP_GLIBC
+ #define RE_SYNTAX_POSIX_BASIC						\
+   (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
++#else
++#define RE_SYNTAX_POSIX_BASIC						\
++  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
++#endif
+ 
+ /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+    RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+@@ -298,9 +307,11 @@
+ /* Like REG_NOTBOL, except for the end-of-line.  */
+ #define REG_NOTEOL (1 << 1)
+ 
++#ifdef __OPTION_POSIX_REGEXP_GLIBC
+ /* Use PMATCH[0] to delimit the start and end of the search in the
+    buffer.  */
+ #define REG_STARTEND (1 << 2)
++#endif
+ 
+ 
+ /* If any error codes are removed, changed, or added, update the
+diff -Naur glibc-2.20/posix/regex_internal.c glibc-2.20-patch/posix/regex_internal.c
+--- glibc-2.20/posix/regex_internal.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/regex_internal.c	2015-03-04 00:51:32.388952006 -0600
+@@ -43,8 +43,8 @@
+   int init_buf_len;
+ 
+   /* Ensure at least one character fits into the buffers.  */
+-  if (init_len < dfa->mb_cur_max)
+-    init_len = dfa->mb_cur_max;
++  if (init_len < dfa_mb_cur_max (dfa))
++    init_len = dfa_mb_cur_max (dfa);
+   init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
+   re_string_construct_common (str, len, pstr, trans, icase, dfa);
+ 
+@@ -55,7 +55,7 @@
+   pstr->word_char = dfa->word_char;
+   pstr->word_ops_used = dfa->word_ops_used;
+   pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+-  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
++  pstr->valid_len = (pstr->mbs_allocated || dfa_mb_cur_max (dfa) > 1) ? 0 : len;
+   pstr->valid_raw_len = pstr->valid_len;
+   return REG_NOERROR;
+ }
+@@ -82,7 +82,7 @@
+   if (icase)
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  while (1)
+ 	    {
+@@ -91,7 +91,7 @@
+ 		return ret;
+ 	      if (pstr->valid_raw_len >= len)
+ 		break;
+-	      if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
++	      if (pstr->bufs_len > pstr->valid_len + dfa_mb_cur_max (dfa))
+ 		break;
+ 	      ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+ 	      if (BE (ret != REG_NOERROR, 0))
+@@ -105,7 +105,7 @@
+   else
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	build_wcs_buffer (pstr);
+       else
+ #endif /* RE_ENABLE_I18N  */
+@@ -130,7 +130,7 @@
+ re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
+ {
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1)
++  if (string_mb_cur_max (pstr) > 1)
+     {
+       wint_t *new_wcs;
+ 
+@@ -177,7 +177,7 @@
+   pstr->trans = trans;
+   pstr->icase = icase ? 1 : 0;
+   pstr->mbs_allocated = (trans != NULL || icase);
+-  pstr->mb_cur_max = dfa->mb_cur_max;
++  pstr->mb_cur_max = dfa_mb_cur_max (dfa);
+   pstr->is_utf8 = dfa->is_utf8;
+   pstr->map_notascii = dfa->map_notascii;
+   pstr->stop = pstr->len;
+@@ -203,7 +203,7 @@
+ {
+ #ifdef _LIBC
+   unsigned char buf[MB_LEN_MAX];
+-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
++  assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
+ #else
+   unsigned char buf[64];
+ #endif
+@@ -226,7 +226,7 @@
+ 	{
+ 	  int i, ch;
+ 
+-	  for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
++	  for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
+ 	    {
+ 	      ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
+ 	      buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
+@@ -275,7 +275,7 @@
+   size_t mbclen;
+ #ifdef _LIBC
+   char buf[MB_LEN_MAX];
+-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
++  assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
+ #else
+   char buf[64];
+ #endif
+@@ -369,7 +369,7 @@
+ 	  {
+ 	    int i, ch;
+ 
+-	    for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
++	    for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
+ 	      {
+ 		ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
+ 		buf[i] = pstr->trans[ch];
+@@ -567,8 +567,9 @@
+ }
+ 
+ /* This function re-construct the buffers.
+-   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+-   convert to upper case in case of REG_ICASE, apply translation.  */
++   Concretely, convert to wide character in case of
++   string_mb_cur_max (pstr) > 1, convert to upper case in case of
++   REG_ICASE, apply translation.  */
+ 
+ static reg_errcode_t
+ internal_function __attribute_warn_unused_result__
+@@ -579,7 +580,7 @@
+     {
+       /* Reset buffer.  */
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+ #endif /* RE_ENABLE_I18N */
+       pstr->len = pstr->raw_len;
+@@ -670,7 +671,7 @@
+ 	      pstr->tip_context = re_string_context_at (pstr, offset - 1,
+ 							eflags);
+ #ifdef RE_ENABLE_I18N
+-	      if (pstr->mb_cur_max > 1)
++	      if (string_mb_cur_max (pstr) > 1)
+ 		memmove (pstr->wcs, pstr->wcs + offset,
+ 			 (pstr->valid_len - offset) * sizeof (wint_t));
+ #endif /* RE_ENABLE_I18N */
+@@ -699,7 +700,7 @@
+ #endif
+ 	  pstr->valid_len = 0;
+ #ifdef RE_ENABLE_I18N
+-	  if (pstr->mb_cur_max > 1)
++	  if (string_mb_cur_max (pstr) > 1)
+ 	    {
+ 	      int wcs_idx;
+ 	      wint_t wc = WEOF;
+@@ -711,7 +712,7 @@
+ 		  /* Special case UTF-8.  Multi-byte chars start with any
+ 		     byte other than 0x80 - 0xbf.  */
+ 		  raw = pstr->raw_mbs + pstr->raw_mbs_idx;
+-		  end = raw + (offset - pstr->mb_cur_max);
++		  end = raw + (offset - string_mb_cur_max (pstr));
+ 		  if (end < pstr->raw_mbs)
+ 		    end = pstr->raw_mbs;
+ 		  p = raw + offset - 1;
+@@ -803,7 +804,7 @@
+ 
+   /* Then build the buffers.  */
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1)
++  if (string_mb_cur_max (pstr) > 1)
+     {
+       if (pstr->icase)
+ 	{
+@@ -841,7 +842,7 @@
+     return re_string_peek_byte (pstr, idx);
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1
++  if (string_mb_cur_max (pstr) > 1
+       && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
+     return re_string_peek_byte (pstr, idx);
+ #endif
+@@ -930,7 +931,7 @@
+     return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+ 	    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1)
++  if (string_mb_cur_max (input) > 1)
+     {
+       wint_t wc;
+       int wc_idx = idx;
+@@ -1444,7 +1445,7 @@
+   dfa->nodes[dfa->nodes_len].constraint = 0;
+ #ifdef RE_ENABLE_I18N
+   dfa->nodes[dfa->nodes_len].accept_mb =
+-    (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
++    (type == OP_PERIOD && dfa_mb_cur_max (dfa) > 1) || type == COMPLEX_BRACKET;
+ #endif
+   dfa->nexts[dfa->nodes_len] = -1;
+   re_node_set_init_empty (dfa->edests + dfa->nodes_len);
+diff -Naur glibc-2.20/posix/regex_internal.h glibc-2.20-patch/posix/regex_internal.h
+--- glibc-2.20/posix/regex_internal.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/posix/regex_internal.h	2015-03-04 00:51:32.388952006 -0600
+@@ -26,6 +26,10 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
+ # include <langinfo.h>
+ #endif
+@@ -370,6 +374,13 @@
+ };
+ typedef struct re_string_t re_string_t;
+ 
++/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
++   help the compiler make use of that fact.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define string_mb_cur_max(str) ((str)->mb_cur_max + 0)
++#else
++# define string_mb_cur_max(str) (1)
++#endif
+ 
+ struct re_dfa_t;
+ typedef struct re_dfa_t re_dfa_t;
+@@ -655,6 +666,14 @@
+   __libc_lock_define (, lock)
+ };
+ 
++/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
++   help the compiler make use of that fact.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define dfa_mb_cur_max(dfa) ((dfa)->mb_cur_max + 0)
++#else
++# define dfa_mb_cur_max(dfa) (1)
++#endif
++
+ #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+ #define re_node_set_remove(set,id) \
+   (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+@@ -715,7 +734,7 @@
+ re_string_char_size_at (const re_string_t *pstr, int idx)
+ {
+   int byte_idx;
+-  if (pstr->mb_cur_max == 1)
++  if (string_mb_cur_max (pstr) == 1)
+     return 1;
+   for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
+     if (pstr->wcs[idx + byte_idx] != WEOF)
+@@ -727,7 +746,7 @@
+ internal_function __attribute__ ((pure, unused))
+ re_string_wchar_at (const re_string_t *pstr, int idx)
+ {
+-  if (pstr->mb_cur_max == 1)
++  if (string_mb_cur_max (pstr) == 1)
+     return (wint_t) pstr->mbs[idx];
+   return (wint_t) pstr->wcs[idx];
+ }
+diff -Naur glibc-2.20/posix/xregex.c glibc-2.20-patch/posix/xregex.c
+--- glibc-2.20/posix/xregex.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/posix/xregex.c	2015-03-04 00:51:32.416952006 -0600
+@@ -0,0 +1,8212 @@
++/* Extended regular expression matching and search library,
++   version 0.12.
++   (Implements POSIX draft P1003.2/D11.2, except for some of the
++   internationalization features.)
++
++   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
++   2002, 2005 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   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., 51 Franklin Street, Fifth Floor, Boston, MA
++   02110-1301 USA.  */
++
++/* AIX requires this to be the first thing in the file. */
++#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC
++  #pragma alloca
++#endif
++
++#undef	_GNU_SOURCE
++#define _GNU_SOURCE
++
++#ifndef INSIDE_RECURSION
++# ifdef HAVE_CONFIG_H
++#  include <config.h>
++# endif
++#endif
++
++/*#include <ansidecl.h>*/
++
++#ifndef INSIDE_RECURSION
++
++# if defined STDC_HEADERS && !defined emacs
++#  include <stddef.h>
++# else
++/* We need this for `regex.h', and perhaps for the Emacs include files.  */
++#  include <sys/types.h>
++# endif
++
++# define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
++
++/* For platform which support the ISO C amendement 1 functionality we
++   support user defined character classes.  */
++# if WIDE_CHAR_SUPPORT
++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
++#  include <wchar.h>
++#  include <wctype.h>
++# endif
++
++# ifdef _LIBC
++/* We have to keep the namespace clean.  */
++#  define regfree(preg) __regfree (preg)
++#  define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
++#  define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
++#  define regerror(errcode, preg, errbuf, errbuf_size) \
++	__regerror(errcode, preg, errbuf, errbuf_size)
++#  define re_set_registers(bu, re, nu, st, en) \
++	__re_set_registers (bu, re, nu, st, en)
++#  define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
++	__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
++#  define re_match(bufp, string, size, pos, regs) \
++	__re_match (bufp, string, size, pos, regs)
++#  define re_search(bufp, string, size, startpos, range, regs) \
++	__re_search (bufp, string, size, startpos, range, regs)
++#  define re_compile_pattern(pattern, length, bufp) \
++	__re_compile_pattern (pattern, length, bufp)
++#  define re_set_syntax(syntax) __re_set_syntax (syntax)
++#  define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
++	__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
++#  define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
++
++#  define btowc __btowc
++
++/* We are also using some library internals.  */
++#  include <locale/localeinfo.h>
++#  include <locale/elem-hash.h>
++#  include <langinfo.h>
++#  include <locale/coll-lookup.h>
++# endif
++
++/* This is for other GNU distributions with internationalized messages.  */
++# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
++#  include <libintl.h>
++#  ifdef _LIBC
++#   undef gettext
++#   define gettext(msgid) __dcgettext ("libc", msgid, LC_MESSAGES)
++#  endif
++# else
++#  define gettext(msgid) (msgid)
++# endif
++
++# ifndef gettext_noop
++/* This define is so xgettext can find the internationalizable
++   strings.  */
++#  define gettext_noop(String) String
++# endif
++
++/* The `emacs' switch turns on certain matching commands
++   that make sense only in Emacs. */
++# ifdef emacs
++
++#  include "lisp.h"
++#  include "buffer.h"
++#  include "syntax.h"
++
++# else  /* not emacs */
++
++/* If we are not linking with Emacs proper,
++   we can't use the relocating allocator
++   even if config.h says that we can.  */
++#  undef REL_ALLOC
++
++#  if defined STDC_HEADERS || defined _LIBC
++#   include <stdlib.h>
++#  else
++char *malloc ();
++char *realloc ();
++#  endif
++
++/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
++   If nothing else has been done, use the method below.  */
++#  ifdef INHIBIT_STRING_HEADER
++#   if !(defined HAVE_BZERO && defined HAVE_BCOPY)
++#    if !defined bzero && !defined bcopy
++#     undef INHIBIT_STRING_HEADER
++#    endif
++#   endif
++#  endif
++
++/* This is the normal way of making sure we have a bcopy and a bzero.
++   This is used in most programs--a few other programs avoid this
++   by defining INHIBIT_STRING_HEADER.  */
++#  ifndef INHIBIT_STRING_HEADER
++#   if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
++#    include <string.h>
++#    ifndef bzero
++#     ifndef _LIBC
++#      define bzero(s, n)	(memset (s, '\0', n), (s))
++#     else
++#      define bzero(s, n)	__bzero (s, n)
++#     endif
++#    endif
++#   else
++#    include <strings.h>
++#    ifndef memcmp
++#     define memcmp(s1, s2, n)	bcmp (s1, s2, n)
++#    endif
++#    ifndef memcpy
++#     define memcpy(d, s, n)	(bcopy (s, d, n), (d))
++#    endif
++#   endif
++#  endif
++
++/* Define the syntax stuff for \<, \>, etc.  */
++
++/* This must be nonzero for the wordchar and notwordchar pattern
++   commands in re_match_2.  */
++#  ifndef Sword
++#   define Sword 1
++#  endif
++
++#  ifdef SWITCH_ENUM_BUG
++#   define SWITCH_ENUM_CAST(x) ((int)(x))
++#  else
++#   define SWITCH_ENUM_CAST(x) (x)
++#  endif
++
++# endif /* not emacs */
++
++# if defined _LIBC || HAVE_LIMITS_H
++#  include <limits.h>
++# endif
++
++# ifndef MB_LEN_MAX
++#  define MB_LEN_MAX 1
++# endif
++\f
++/* Get the interface, including the syntax bits.  */
++# include "regex.h"
++
++/* isalpha etc. are used for the character classes.  */
++# include <ctype.h>
++
++/* Jim Meyering writes:
++
++   "... Some ctype macros are valid only for character codes that
++   isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
++   using /bin/cc or gcc but without giving an ansi option).  So, all
++   ctype uses should be through macros like ISPRINT...  If
++   STDC_HEADERS is defined, then autoconf has verified that the ctype
++   macros don't need to be guarded with references to isascii. ...
++   Defining isascii to 1 should let any compiler worth its salt
++   eliminate the && through constant folding."
++   Solaris defines some of these symbols so we must undefine them first.  */
++
++# undef ISASCII
++# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
++#  define ISASCII(c) 1
++# else
++#  define ISASCII(c) isascii(c)
++# endif
++
++# ifdef isblank
++#  define ISBLANK(c) (ISASCII (c) && isblank (c))
++# else
++#  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
++# endif
++# ifdef isgraph
++#  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
++# else
++#  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
++# endif
++
++# undef ISPRINT
++# define ISPRINT(c) (ISASCII (c) && isprint (c))
++# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
++# define ISALNUM(c) (ISASCII (c) && isalnum (c))
++# define ISALPHA(c) (ISASCII (c) && isalpha (c))
++# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
++# define ISLOWER(c) (ISASCII (c) && islower (c))
++# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
++# define ISSPACE(c) (ISASCII (c) && isspace (c))
++# define ISUPPER(c) (ISASCII (c) && isupper (c))
++# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
++
++# ifdef _tolower
++#  define TOLOWER(c) _tolower(c)
++# else
++#  define TOLOWER(c) tolower(c)
++# endif
++
++# ifndef NULL
++#  define NULL (void *)0
++# endif
++
++/* We remove any previous definition of `SIGN_EXTEND_CHAR',
++   since ours (we hope) works properly with all combinations of
++   machines, compilers, `char' and `unsigned char' argument types.
++   (Per Bothner suggested the basic approach.)  */
++# undef SIGN_EXTEND_CHAR
++# if __STDC__
++#  define SIGN_EXTEND_CHAR(c) ((signed char) (c))
++# else  /* not __STDC__ */
++/* As in Harbison and Steele.  */
++#  define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
++# endif
++\f
++# ifndef emacs
++/* How many characters in the character set.  */
++#  define CHAR_SET_SIZE 256
++
++#  ifdef SYNTAX_TABLE
++
++extern char *re_syntax_table;
++
++#  else /* not SYNTAX_TABLE */
++
++static char re_syntax_table[CHAR_SET_SIZE];
++
++static void init_syntax_once (void);
++
++static void
++init_syntax_once (void)
++{
++   register int c;
++   static int done = 0;
++
++   if (done)
++     return;
++   bzero (re_syntax_table, sizeof re_syntax_table);
++
++   for (c = 0; c < CHAR_SET_SIZE; ++c)
++     if (ISALNUM (c))
++	re_syntax_table[c] = Sword;
++
++   re_syntax_table['_'] = Sword;
++
++   done = 1;
++}
++
++#  endif /* not SYNTAX_TABLE */
++
++#  define SYNTAX(c) re_syntax_table[(unsigned char) (c)]
++
++# endif /* emacs */
++\f
++/* Integer type for pointers.  */
++# if !defined _LIBC && !defined HAVE_UINTPTR_T
++typedef unsigned long int uintptr_t;
++# endif
++
++/* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
++   use `alloca' instead of `malloc'.  This is because using malloc in
++   re_search* or re_match* could cause memory leaks when C-g is used in
++   Emacs; also, malloc is slower and causes storage fragmentation.  On
++   the other hand, malloc is more portable, and easier to debug.
++
++   Because we sometimes use alloca, some routines have to be macros,
++   not functions -- `alloca'-allocated space disappears at the end of the
++   function it is called in.  */
++
++# ifdef REGEX_MALLOC
++
++#  define REGEX_ALLOCATE malloc
++#  define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
++#  define REGEX_FREE free
++
++# else /* not REGEX_MALLOC  */
++
++/* Emacs already defines alloca, sometimes.  */
++#  ifndef alloca
++
++/* Make alloca work the best possible way.  */
++#   ifdef __GNUC__
++#    define alloca __builtin_alloca
++#   else /* not __GNUC__ */
++#    if HAVE_ALLOCA_H
++#     include <alloca.h>
++#    endif /* HAVE_ALLOCA_H */
++#   endif /* not __GNUC__ */
++
++#  endif /* not alloca */
++
++#  define REGEX_ALLOCATE alloca
++
++/* Assumes a `char *destination' variable.  */
++#  define REGEX_REALLOCATE(source, osize, nsize)			\
++  (destination = (char *) alloca (nsize),				\
++   memcpy (destination, source, osize))
++
++/* No need to do anything to free, after alloca.  */
++#  define REGEX_FREE(arg) ((void)0) /* Do nothing!  But inhibit gcc warning.  */
++
++# endif /* not REGEX_MALLOC */
++
++/* Define how to allocate the failure stack.  */
++
++# if defined REL_ALLOC && defined REGEX_MALLOC
++
++#  define REGEX_ALLOCATE_STACK(size)				\
++  r_alloc (&failure_stack_ptr, (size))
++#  define REGEX_REALLOCATE_STACK(source, osize, nsize)		\
++  r_re_alloc (&failure_stack_ptr, (nsize))
++#  define REGEX_FREE_STACK(ptr)					\
++  r_alloc_free (&failure_stack_ptr)
++
++# else /* not using relocating allocator */
++
++#  ifdef REGEX_MALLOC
++
++#   define REGEX_ALLOCATE_STACK malloc
++#   define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
++#   define REGEX_FREE_STACK free
++
++#  else /* not REGEX_MALLOC */
++
++#   define REGEX_ALLOCATE_STACK alloca
++
++#   define REGEX_REALLOCATE_STACK(source, osize, nsize)			\
++   REGEX_REALLOCATE (source, osize, nsize)
++/* No need to explicitly free anything.  */
++#   define REGEX_FREE_STACK(arg)
++
++#  endif /* not REGEX_MALLOC */
++# endif /* not using relocating allocator */
++
++
++/* True if `size1' is non-NULL and PTR is pointing anywhere inside
++   `string1' or just past its end.  This works if PTR is NULL, which is
++   a good thing.  */
++# define FIRST_STRING_P(ptr) 					\
++  (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
++
++/* (Re)Allocate N items of type T using malloc, or fail.  */
++# define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
++# define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
++# define RETALLOC_IF(addr, n, t) \
++  if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
++# define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
++
++# define BYTEWIDTH 8 /* In bits.  */
++
++# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
++
++# undef MAX
++# undef MIN
++# define MAX(a, b) ((a) > (b) ? (a) : (b))
++# define MIN(a, b) ((a) < (b) ? (a) : (b))
++
++typedef char boolean;
++# define false 0
++# define true 1
++
++static reg_errcode_t byte_regex_compile (const char *pattern, size_t size,
++                                         reg_syntax_t syntax,
++                                         struct re_pattern_buffer *bufp);
++
++static int byte_re_match_2_internal (struct re_pattern_buffer *bufp,
++                                     const char *string1, int size1,
++                                     const char *string2, int size2,
++                                     int pos,
++                                     struct re_registers *regs,
++                                     int stop);
++static int byte_re_search_2 (struct re_pattern_buffer *bufp,
++                             const char *string1, int size1,
++                             const char *string2, int size2,
++                             int startpos, int range,
++                             struct re_registers *regs, int stop);
++static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp);
++
++#ifdef MBS_SUPPORT
++static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size,
++                                        reg_syntax_t syntax,
++                                        struct re_pattern_buffer *bufp);
++
++
++static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
++                                    const char *cstring1, int csize1,
++                                    const char *cstring2, int csize2,
++                                    int pos,
++                                    struct re_registers *regs,
++                                    int stop,
++                                    wchar_t *string1, int size1,
++                                    wchar_t *string2, int size2,
++                                    int *mbs_offset1, int *mbs_offset2);
++static int wcs_re_search_2 (struct re_pattern_buffer *bufp,
++                            const char *string1, int size1,
++                            const char *string2, int size2,
++                            int startpos, int range,
++                            struct re_registers *regs, int stop);
++static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp);
++#endif
++\f
++/* These are the command codes that appear in compiled regular
++   expressions.  Some opcodes are followed by argument bytes.  A
++   command code can specify any interpretation whatsoever for its
++   arguments.  Zero bytes may appear in the compiled regular expression.  */
++
++typedef enum
++{
++  no_op = 0,
++
++  /* Succeed right away--no more backtracking.  */
++  succeed,
++
++        /* Followed by one byte giving n, then by n literal bytes.  */
++  exactn,
++
++# ifdef MBS_SUPPORT
++	/* Same as exactn, but contains binary data.  */
++  exactn_bin,
++# endif
++
++        /* Matches any (more or less) character.  */
++  anychar,
++
++        /* Matches any one char belonging to specified set.  First
++           following byte is number of bitmap bytes.  Then come bytes
++           for a bitmap saying which chars are in.  Bits in each byte
++           are ordered low-bit-first.  A character is in the set if its
++           bit is 1.  A character too large to have a bit in the map is
++           automatically not in the set.  */
++        /* ifdef MBS_SUPPORT, following element is length of character
++	   classes, length of collating symbols, length of equivalence
++	   classes, length of character ranges, and length of characters.
++	   Next, character class element, collating symbols elements,
++	   equivalence class elements, range elements, and character
++	   elements follow.
++	   See regex_compile function.  */
++  charset,
++
++        /* Same parameters as charset, but match any character that is
++           not one of those specified.  */
++  charset_not,
++
++        /* Start remembering the text that is matched, for storing in a
++           register.  Followed by one byte with the register number, in
++           the range 0 to one less than the pattern buffer's re_nsub
++           field.  Then followed by one byte with the number of groups
++           inner to this one.  (This last has to be part of the
++           start_memory only because we need it in the on_failure_jump
++           of re_match_2.)  */
++  start_memory,
++
++        /* Stop remembering the text that is matched and store it in a
++           memory register.  Followed by one byte with the register
++           number, in the range 0 to one less than `re_nsub' in the
++           pattern buffer, and one byte with the number of inner groups,
++           just like `start_memory'.  (We need the number of inner
++           groups here because we don't have any easy way of finding the
++           corresponding start_memory when we're at a stop_memory.)  */
++  stop_memory,
++
++        /* Match a duplicate of something remembered. Followed by one
++           byte containing the register number.  */
++  duplicate,
++
++        /* Fail unless at beginning of line.  */
++  begline,
++
++        /* Fail unless at end of line.  */
++  endline,
++
++        /* Succeeds if at beginning of buffer (if emacs) or at beginning
++           of string to be matched (if not).  */
++  begbuf,
++
++        /* Analogously, for end of buffer/string.  */
++  endbuf,
++
++        /* Followed by two byte relative address to which to jump.  */
++  jump,
++
++	/* Same as jump, but marks the end of an alternative.  */
++  jump_past_alt,
++
++        /* Followed by two-byte relative address of place to resume at
++           in case of failure.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  on_failure_jump,
++
++        /* Like on_failure_jump, but pushes a placeholder instead of the
++           current string position when executed.  */
++  on_failure_keep_string_jump,
++
++        /* Throw away latest failure point and then jump to following
++           two-byte relative address.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  pop_failure_jump,
++
++        /* Change to pop_failure_jump if know won't have to backtrack to
++           match; otherwise change to jump.  This is used to jump
++           back to the beginning of a repeat.  If what follows this jump
++           clearly won't match what the repeat does, such that we can be
++           sure that there is no use backtracking out of repetitions
++           already matched, then we change it to a pop_failure_jump.
++           Followed by two-byte address.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  maybe_pop_jump,
++
++        /* Jump to following two-byte address, and push a dummy failure
++           point. This failure point will be thrown away if an attempt
++           is made to use it for a failure.  A `+' construct makes this
++           before the first repeat.  Also used as an intermediary kind
++           of jump when compiling an alternative.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  dummy_failure_jump,
++
++	/* Push a dummy failure point and continue.  Used at the end of
++	   alternatives.  */
++  push_dummy_failure,
++
++        /* Followed by two-byte relative address and two-byte number n.
++           After matching N times, jump to the address upon failure.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  succeed_n,
++
++        /* Followed by two-byte relative address, and two-byte number n.
++           Jump to the address N times, then fail.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  jump_n,
++
++        /* Set the following two-byte relative address to the
++           subsequent two-byte number.  The address *includes* the two
++           bytes of number.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  set_number_at,
++
++  wordchar,	/* Matches any word-constituent character.  */
++  notwordchar,	/* Matches any char that is not a word-constituent.  */
++
++  wordbeg,	/* Succeeds if at word beginning.  */
++  wordend,	/* Succeeds if at word end.  */
++
++  wordbound,	/* Succeeds if at a word boundary.  */
++  notwordbound	/* Succeeds if not at a word boundary.  */
++
++# ifdef emacs
++  ,before_dot,	/* Succeeds if before point.  */
++  at_dot,	/* Succeeds if at point.  */
++  after_dot,	/* Succeeds if after point.  */
++
++	/* Matches any character whose syntax is specified.  Followed by
++           a byte which contains a syntax code, e.g., Sword.  */
++  syntaxspec,
++
++	/* Matches any character whose syntax is not that specified.  */
++  notsyntaxspec
++# endif /* emacs */
++} re_opcode_t;
++#endif /* not INSIDE_RECURSION */
++\f
++
++#ifdef BYTE
++# define CHAR_T char
++# define UCHAR_T unsigned char
++# define COMPILED_BUFFER_VAR bufp->buffer
++# define OFFSET_ADDRESS_SIZE 2
++# define PREFIX(name) byte_##name
++# define ARG_PREFIX(name) name
++# define PUT_CHAR(c) putchar (c)
++#else
++# ifdef WCHAR
++#  define CHAR_T wchar_t
++#  define UCHAR_T wchar_t
++#  define COMPILED_BUFFER_VAR wc_buffer
++#  define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */
++#  define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1)
++#  define PREFIX(name) wcs_##name
++#  define ARG_PREFIX(name) c##name
++/* Should we use wide stream??  */
++#  define PUT_CHAR(c) printf ("%C", c);
++#  define TRUE 1
++#  define FALSE 0
++# else
++#  ifdef MBS_SUPPORT
++#   define WCHAR
++#   define INSIDE_RECURSION
++#   include "xregex.c"
++#   undef INSIDE_RECURSION
++#  endif
++#  define BYTE
++#  define INSIDE_RECURSION
++#  include "xregex.c"
++#  undef INSIDE_RECURSION
++# endif
++#endif
++
++#ifdef INSIDE_RECURSION
++/* Common operations on the compiled pattern.  */
++
++/* Store NUMBER in two contiguous bytes starting at DESTINATION.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# ifdef WCHAR
++#  define STORE_NUMBER(destination, number)				\
++  do {									\
++    *(destination) = (UCHAR_T)(number);				\
++  } while (0)
++# else /* BYTE */
++#  define STORE_NUMBER(destination, number)				\
++  do {									\
++    (destination)[0] = (number) & 0377;					\
++    (destination)[1] = (number) >> 8;					\
++  } while (0)
++# endif /* WCHAR */
++
++/* Same as STORE_NUMBER, except increment DESTINATION to
++   the byte after where the number is stored.  Therefore, DESTINATION
++   must be an lvalue.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# define STORE_NUMBER_AND_INCR(destination, number)			\
++  do {									\
++    STORE_NUMBER (destination, number);					\
++    (destination) += OFFSET_ADDRESS_SIZE;				\
++  } while (0)
++
++/* Put into DESTINATION a number stored in two contiguous bytes starting
++   at SOURCE.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# ifdef WCHAR
++#  define EXTRACT_NUMBER(destination, source)				\
++  do {									\
++    (destination) = *(source);						\
++  } while (0)
++# else /* BYTE */
++#  define EXTRACT_NUMBER(destination, source)				\
++  do {									\
++    (destination) = *(source) & 0377;					\
++    (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8;		\
++  } while (0)
++# endif
++
++# ifdef DEBUG
++static void PREFIX(extract_number) (int *dest, UCHAR_T *source);
++static void
++PREFIX(extract_number) (int *dest, UCHAR_T *source)
++{
++#  ifdef WCHAR
++  *dest = *source;
++#  else /* BYTE */
++  int temp = SIGN_EXTEND_CHAR (*(source + 1));
++  *dest = *source & 0377;
++  *dest += temp << 8;
++#  endif
++}
++
++#  ifndef EXTRACT_MACROS /* To debug the macros.  */
++#   undef EXTRACT_NUMBER
++#   define EXTRACT_NUMBER(dest, src) PREFIX(extract_number) (&dest, src)
++#  endif /* not EXTRACT_MACROS */
++
++# endif /* DEBUG */
++
++/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
++   SOURCE must be an lvalue.  */
++
++# define EXTRACT_NUMBER_AND_INCR(destination, source)			\
++  do {									\
++    EXTRACT_NUMBER (destination, source);				\
++    (source) += OFFSET_ADDRESS_SIZE; 					\
++  } while (0)
++
++# ifdef DEBUG
++static void PREFIX(extract_number_and_incr) (int *destination,
++                                             UCHAR_T **source);
++static void
++PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source)
++{
++  PREFIX(extract_number) (destination, *source);
++  *source += OFFSET_ADDRESS_SIZE;
++}
++
++#  ifndef EXTRACT_MACROS
++#   undef EXTRACT_NUMBER_AND_INCR
++#   define EXTRACT_NUMBER_AND_INCR(dest, src) \
++  PREFIX(extract_number_and_incr) (&dest, &src)
++#  endif /* not EXTRACT_MACROS */
++
++# endif /* DEBUG */
++
++\f
++
++/* If DEBUG is defined, Regex prints many voluminous messages about what
++   it is doing (if the variable `debug' is nonzero).  If linked with the
++   main program in `iregex.c', you can enter patterns and strings
++   interactively.  And if linked with the main program in `main.c' and
++   the other test files, you can run the already-written tests.  */
++
++# ifdef DEBUG
++
++#  ifndef DEFINED_ONCE
++
++/* We use standard I/O for debugging.  */
++#   include <stdio.h>
++
++/* It is useful to test things that ``must'' be true when debugging.  */
++#   include <assert.h>
++
++static int debug;
++
++#   define DEBUG_STATEMENT(e) e
++#   define DEBUG_PRINT1(x) if (debug) printf (x)
++#   define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
++#   define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
++#   define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
++#  endif /* not DEFINED_ONCE */
++
++#  define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) 			\
++  if (debug) PREFIX(print_partial_compiled_pattern) (s, e)
++#  define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)		\
++  if (debug) PREFIX(print_double_string) (w, s1, sz1, s2, sz2)
++
++
++/* Print the fastmap in human-readable form.  */
++
++#  ifndef DEFINED_ONCE
++void
++print_fastmap (char *fastmap)
++{
++  unsigned was_a_range = 0;
++  unsigned i = 0;
++
++  while (i < (1 << BYTEWIDTH))
++    {
++      if (fastmap[i++])
++	{
++	  was_a_range = 0;
++          putchar (i - 1);
++          while (i < (1 << BYTEWIDTH)  &&  fastmap[i])
++            {
++              was_a_range = 1;
++              i++;
++            }
++	  if (was_a_range)
++            {
++              printf ("-");
++              putchar (i - 1);
++            }
++        }
++    }
++  putchar ('\n');
++}
++#  endif /* not DEFINED_ONCE */
++
++
++/* Print a compiled pattern string in human-readable form, starting at
++   the START pointer into it and ending just before the pointer END.  */
++
++void
++PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
++{
++  int mcnt, mcnt2;
++  UCHAR_T *p1;
++  UCHAR_T *p = start;
++  UCHAR_T *pend = end;
++
++  if (start == NULL)
++    {
++      printf ("(null)\n");
++      return;
++    }
++
++  /* Loop over pattern commands.  */
++  while (p < pend)
++    {
++#  ifdef _LIBC
++      printf ("%td:\t", p - start);
++#  else
++      printf ("%ld:\t", (long int) (p - start));
++#  endif
++
++      switch ((re_opcode_t) *p++)
++	{
++        case no_op:
++          printf ("/no_op");
++          break;
++
++	case exactn:
++	  mcnt = *p++;
++          printf ("/exactn/%d", mcnt);
++          do
++	    {
++              putchar ('/');
++	      PUT_CHAR (*p++);
++            }
++          while (--mcnt);
++          break;
++
++#  ifdef MBS_SUPPORT
++	case exactn_bin:
++	  mcnt = *p++;
++	  printf ("/exactn_bin/%d", mcnt);
++          do
++	    {
++	      printf("/%lx", (long int) *p++);
++            }
++          while (--mcnt);
++          break;
++#  endif /* MBS_SUPPORT */
++
++	case start_memory:
++          mcnt = *p++;
++          printf ("/start_memory/%d/%ld", mcnt, (long int) *p++);
++          break;
++
++	case stop_memory:
++          mcnt = *p++;
++	  printf ("/stop_memory/%d/%ld", mcnt, (long int) *p++);
++          break;
++
++	case duplicate:
++	  printf ("/duplicate/%ld", (long int) *p++);
++	  break;
++
++	case anychar:
++	  printf ("/anychar");
++	  break;
++
++	case charset:
++        case charset_not:
++          {
++#  ifdef WCHAR
++	    int i, length;
++	    wchar_t *workp = p;
++	    printf ("/charset [%s",
++	            (re_opcode_t) *(workp - 1) == charset_not ? "^" : "");
++	    p += 5;
++	    length = *workp++; /* the length of char_classes */
++	    for (i=0 ; i<length ; i++)
++	      printf("[:%lx:]", (long int) *p++);
++	    length = *workp++; /* the length of collating_symbol */
++	    for (i=0 ; i<length ;)
++	      {
++		printf("[.");
++		while(*p != 0)
++		  PUT_CHAR((i++,*p++));
++		i++,p++;
++		printf(".]");
++	      }
++	    length = *workp++; /* the length of equivalence_class */
++	    for (i=0 ; i<length ;)
++	      {
++		printf("[=");
++		while(*p != 0)
++		  PUT_CHAR((i++,*p++));
++		i++,p++;
++		printf("=]");
++	      }
++	    length = *workp++; /* the length of char_range */
++	    for (i=0 ; i<length ; i++)
++	      {
++		wchar_t range_start = *p++;
++		wchar_t range_end = *p++;
++		printf("%C-%C", range_start, range_end);
++	      }
++	    length = *workp++; /* the length of char */
++	    for (i=0 ; i<length ; i++)
++	      printf("%C", *p++);
++	    putchar (']');
++#  else
++            register int c, last = -100;
++	    register int in_range = 0;
++
++	    printf ("/charset [%s",
++	            (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
++
++            assert (p + *p < pend);
++
++            for (c = 0; c < 256; c++)
++	      if (c / 8 < *p
++		  && (p[1 + (c/8)] & (1 << (c % 8))))
++		{
++		  /* Are we starting a range?  */
++		  if (last + 1 == c && ! in_range)
++		    {
++		      putchar ('-');
++		      in_range = 1;
++		    }
++		  /* Have we broken a range?  */
++		  else if (last + 1 != c && in_range)
++              {
++		      putchar (last);
++		      in_range = 0;
++		    }
++
++		  if (! in_range)
++		    putchar (c);
++
++		  last = c;
++              }
++
++	    if (in_range)
++	      putchar (last);
++
++	    putchar (']');
++
++	    p += 1 + *p;
++#  endif /* WCHAR */
++	  }
++	  break;
++
++	case begline:
++	  printf ("/begline");
++          break;
++
++	case endline:
++          printf ("/endline");
++          break;
++
++	case on_failure_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/on_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/on_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case on_failure_keep_string_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/on_failure_keep_string_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/on_failure_keep_string_jump to %ld",
++		  (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case dummy_failure_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/dummy_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/dummy_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case push_dummy_failure:
++          printf ("/push_dummy_failure");
++          break;
++
++        case maybe_pop_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/maybe_pop_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/maybe_pop_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case pop_failure_jump:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/pop_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/pop_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case jump_past_alt:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/jump_past_alt to %td", p + mcnt - start);
++#  else
++  	  printf ("/jump_past_alt to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case jump:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case succeed_n:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++#  ifdef _LIBC
++	  printf ("/succeed_n to %td, %d times", p1 - start, mcnt2);
++#  else
++	  printf ("/succeed_n to %ld, %d times",
++		  (long int) (p1 - start), mcnt2);
++#  endif
++          break;
++
++        case jump_n:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++	  printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
++          break;
++
++        case set_number_at:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++#  ifdef _LIBC
++	  printf ("/set_number_at location %td to %d", p1 - start, mcnt2);
++#  else
++	  printf ("/set_number_at location %ld to %d",
++		  (long int) (p1 - start), mcnt2);
++#  endif
++          break;
++
++        case wordbound:
++	  printf ("/wordbound");
++	  break;
++
++	case notwordbound:
++	  printf ("/notwordbound");
++          break;
++
++	case wordbeg:
++	  printf ("/wordbeg");
++	  break;
++
++	case wordend:
++	  printf ("/wordend");
++	  break;
++
++#  ifdef emacs
++	case before_dot:
++	  printf ("/before_dot");
++          break;
++
++	case at_dot:
++	  printf ("/at_dot");
++          break;
++
++	case after_dot:
++	  printf ("/after_dot");
++          break;
++
++	case syntaxspec:
++          printf ("/syntaxspec");
++	  mcnt = *p++;
++	  printf ("/%d", mcnt);
++          break;
++
++	case notsyntaxspec:
++          printf ("/notsyntaxspec");
++	  mcnt = *p++;
++	  printf ("/%d", mcnt);
++	  break;
++#  endif /* emacs */
++
++	case wordchar:
++	  printf ("/wordchar");
++          break;
++
++	case notwordchar:
++	  printf ("/notwordchar");
++          break;
++
++	case begbuf:
++	  printf ("/begbuf");
++          break;
++
++	case endbuf:
++	  printf ("/endbuf");
++          break;
++
++        default:
++          printf ("?%ld", (long int) *(p-1));
++	}
++
++      putchar ('\n');
++    }
++
++#  ifdef _LIBC
++  printf ("%td:\tend of pattern.\n", p - start);
++#  else
++  printf ("%ld:\tend of pattern.\n", (long int) (p - start));
++#  endif
++}
++
++
++void
++PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
++{
++  UCHAR_T *buffer = (UCHAR_T*) bufp->buffer;
++
++  PREFIX(print_partial_compiled_pattern) (buffer, buffer
++				  + bufp->used / sizeof(UCHAR_T));
++  printf ("%ld bytes used/%ld bytes allocated.\n",
++	  bufp->used, bufp->allocated);
++
++  if (bufp->fastmap_accurate && bufp->fastmap)
++    {
++      printf ("fastmap: ");
++      print_fastmap (bufp->fastmap);
++    }
++
++#  ifdef _LIBC
++  printf ("re_nsub: %Zd\t", bufp->re_nsub);
++#  else
++  printf ("re_nsub: %ld\t", (long int) bufp->re_nsub);
++#  endif
++  printf ("regs_alloc: %d\t", bufp->regs_allocated);
++  printf ("can_be_null: %d\t", bufp->can_be_null);
++  printf ("newline_anchor: %d\n", bufp->newline_anchor);
++  printf ("no_sub: %d\t", bufp->no_sub);
++  printf ("not_bol: %d\t", bufp->not_bol);
++  printf ("not_eol: %d\t", bufp->not_eol);
++  printf ("syntax: %lx\n", bufp->syntax);
++  /* Perhaps we should print the translate table?  */
++}
++
++
++void
++PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1,
++                             int size1, const CHAR_T *string2, int size2)
++{
++  int this_char;
++
++  if (where == NULL)
++    printf ("(null)");
++  else
++    {
++      int cnt;
++
++      if (FIRST_STRING_P (where))
++        {
++          for (this_char = where - string1; this_char < size1; this_char++)
++	    PUT_CHAR (string1[this_char]);
++
++          where = string2;
++        }
++
++      cnt = 0;
++      for (this_char = where - string2; this_char < size2; this_char++)
++	{
++	  PUT_CHAR (string2[this_char]);
++	  if (++cnt > 100)
++	    {
++	      fputs ("...", stdout);
++	      break;
++	    }
++	}
++    }
++}
++
++#  ifndef DEFINED_ONCE
++void
++printchar (int c)
++{
++  putc (c, stderr);
++}
++#  endif
++
++# else /* not DEBUG */
++
++#  ifndef DEFINED_ONCE
++#   undef assert
++#   define assert(e)
++
++#   define DEBUG_STATEMENT(e)
++#   define DEBUG_PRINT1(x)
++#   define DEBUG_PRINT2(x1, x2)
++#   define DEBUG_PRINT3(x1, x2, x3)
++#   define DEBUG_PRINT4(x1, x2, x3, x4)
++#  endif /* not DEFINED_ONCE */
++#  define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
++#  define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
++
++# endif /* not DEBUG */
++
++\f
++
++# ifdef WCHAR
++/* This  convert a multibyte string to a wide character string.
++   And write their correspondances to offset_buffer(see below)
++   and write whether each wchar_t is binary data to is_binary.
++   This assume invalid multibyte sequences as binary data.
++   We assume offset_buffer and is_binary is already allocated
++   enough space.  */
++
++static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src,
++				  size_t len, int *offset_buffer,
++				  char *is_binary);
++static size_t
++convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len,
++                    int *offset_buffer, char *is_binary)
++     /* It hold correspondances between src(char string) and
++	dest(wchar_t string) for optimization.
++	e.g. src  = "xxxyzz"
++             dest = {'X', 'Y', 'Z'}
++	      (each "xxx", "y" and "zz" represent one multibyte character
++	       corresponding to 'X', 'Y' and 'Z'.)
++	  offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")}
++	  	        = {0, 3, 4, 6}
++     */
++{
++  wchar_t *pdest = dest;
++  const unsigned char *psrc = src;
++  size_t wc_count = 0;
++
++  mbstate_t mbs;
++  int i, consumed;
++  size_t mb_remain = len;
++  size_t mb_count = 0;
++
++  /* Initialize the conversion state.  */
++  memset (&mbs, 0, sizeof (mbstate_t));
++
++  offset_buffer[0] = 0;
++  for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed,
++	 psrc += consumed)
++    {
++#ifdef _LIBC
++      consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs);
++#else
++      consumed = mbrtowc (pdest, psrc, mb_remain, &mbs);
++#endif
++
++      if (consumed <= 0)
++	/* failed to convert. maybe src contains binary data.
++	   So we consume 1 byte manualy.  */
++	{
++	  *pdest = *psrc;
++	  consumed = 1;
++	  is_binary[wc_count] = TRUE;
++	}
++      else
++	is_binary[wc_count] = FALSE;
++      /* In sjis encoding, we use yen sign as escape character in
++	 place of reverse solidus. So we convert 0x5c(yen sign in
++	 sjis) to not 0xa5(yen sign in UCS2) but 0x5c(reverse
++	 solidus in UCS2).  */
++      if (consumed == 1 && (int) *psrc == 0x5c && (int) *pdest == 0xa5)
++	*pdest = (wchar_t) *psrc;
++
++      offset_buffer[wc_count + 1] = mb_count += consumed;
++    }
++
++  /* Fill remain of the buffer with sentinel.  */
++  for (i = wc_count + 1 ; i <= len ; i++)
++    offset_buffer[i] = mb_count + 1;
++
++  return wc_count;
++}
++
++# endif /* WCHAR */
++
++#else /* not INSIDE_RECURSION */
++
++/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
++   also be assigned to arbitrarily: each pattern buffer stores its own
++   syntax, so it can be changed between regex compilations.  */
++/* This has no initializer because initialized variables in Emacs
++   become read-only after dumping.  */
++reg_syntax_t re_syntax_options;
++
++
++/* Specify the precise syntax of regexps for compilation.  This provides
++   for compatibility for various utilities which historically have
++   different, incompatible syntaxes.
++
++   The argument SYNTAX is a bit mask comprised of the various bits
++   defined in regex.h.  We return the old syntax.  */
++
++reg_syntax_t
++re_set_syntax (reg_syntax_t syntax)
++{
++  reg_syntax_t ret = re_syntax_options;
++
++  re_syntax_options = syntax;
++# ifdef DEBUG
++  if (syntax & RE_DEBUG)
++    debug = 1;
++  else if (debug) /* was on but now is not */
++    debug = 0;
++# endif /* DEBUG */
++  return ret;
++}
++# ifdef _LIBC
++weak_alias (__re_set_syntax, re_set_syntax)
++# endif
++\f
++/* This table gives an error message for each of the error codes listed
++   in regex.h.  Obviously the order here has to be same as there.
++   POSIX doesn't require that we do anything for REG_NOERROR,
++   but why not be nice?  */
++
++static const char *re_error_msgid[] =
++  {
++    gettext_noop ("Success"),	/* REG_NOERROR */
++    gettext_noop ("No match"),	/* REG_NOMATCH */
++    gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
++    gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
++    gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
++    gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
++    gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
++    gettext_noop ("Unmatched [ or [^"),	/* REG_EBRACK */
++    gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
++    gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
++    gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
++    gettext_noop ("Invalid range end"),	/* REG_ERANGE */
++    gettext_noop ("Memory exhausted"), /* REG_ESPACE */
++    gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
++    gettext_noop ("Premature end of regular expression"), /* REG_EEND */
++    gettext_noop ("Regular expression too big"), /* REG_ESIZE */
++    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
++  };
++\f
++#endif /* INSIDE_RECURSION */
++
++#ifndef DEFINED_ONCE
++/* Avoiding alloca during matching, to placate r_alloc.  */
++
++/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
++   searching and matching functions should not call alloca.  On some
++   systems, alloca is implemented in terms of malloc, and if we're
++   using the relocating allocator routines, then malloc could cause a
++   relocation, which might (if the strings being searched are in the
++   ralloc heap) shift the data out from underneath the regexp
++   routines.
++
++   Here's another reason to avoid allocation: Emacs
++   processes input from X in a signal handler; processing X input may
++   call malloc; if input arrives while a matching routine is calling
++   malloc, then we're scrod.  But Emacs can't just block input while
++   calling matching routines; then we don't notice interrupts when
++   they come in.  So, Emacs blocks input around all regexp calls
++   except the matching calls, which it leaves unprotected, in the
++   faith that they will not malloc.  */
++
++/* Normally, this is fine.  */
++# define MATCH_MAY_ALLOCATE
++
++/* When using GNU C, we are not REALLY using the C alloca, no matter
++   what config.h may say.  So don't take precautions for it.  */
++# ifdef __GNUC__
++#  undef C_ALLOCA
++# endif
++
++/* The match routines may not allocate if (1) they would do it with malloc
++   and (2) it's not safe for them to use malloc.
++   Note that if REL_ALLOC is defined, matching would not use malloc for the
++   failure stack, but we would still use it for the register vectors;
++   so REL_ALLOC should not affect this.  */
++# if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
++#  undef MATCH_MAY_ALLOCATE
++# endif
++#endif /* not DEFINED_ONCE */
++\f
++#ifdef INSIDE_RECURSION
++/* Failure stack declarations and macros; both re_compile_fastmap and
++   re_match_2 use a failure stack.  These have to be macros because of
++   REGEX_ALLOCATE_STACK.  */
++
++
++/* Number of failure points for which to initially allocate space
++   when matching.  If this number is exceeded, we allocate more
++   space, so it is not a hard limit.  */
++# ifndef INIT_FAILURE_ALLOC
++#  define INIT_FAILURE_ALLOC 5
++# endif
++
++/* Roughly the maximum number of failure points on the stack.  Would be
++   exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
++   This is a variable only so users of regex can assign to it; we never
++   change it ourselves.  */
++
++
++# ifndef DEFINED_ONCE
++
++#  ifdef INT_IS_16BIT
++#   define RE_M_F_TYPE long int
++#  else
++#   define RE_M_F_TYPE int
++#  endif /* INT_IS_16BIT */
++
++#  ifdef MATCH_MAY_ALLOCATE
++/* 4400 was enough to cause a crash on Alpha OSF/1,
++   whose default stack limit is 2mb.  */
++#   define RE_M_F_DEFAULT 4000
++#  else
++#   define RE_M_F_DEFAULT 2000
++#  endif /* MATCH_MAY_ALLOCATE */
++
++#  include <shlib-compat.h>
++
++#  if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
++link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
++RE_M_F_TYPE re_max_failures = RE_M_F_DEFAULT;
++#  else
++RE_M_F_TYPE re_max_failures attribute_hidden = RE_M_F_DEFAULT;
++#  endif /* SHLIB_COMPAT */
++
++#  undef RE_M_F_TYPE
++#  undef RE_M_F_DEFAULT
++
++# endif /* DEFINED_ONCE */
++
++# ifdef INT_IS_16BIT
++
++union PREFIX(fail_stack_elt)
++{
++  UCHAR_T *pointer;
++  long int integer;
++};
++
++typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
++
++typedef struct
++{
++  PREFIX(fail_stack_elt_t) *stack;
++  unsigned long int size;
++  unsigned long int avail;		/* Offset of next open position.  */
++} PREFIX(fail_stack_type);
++
++# else /* not INT_IS_16BIT */
++
++union PREFIX(fail_stack_elt)
++{
++  UCHAR_T *pointer;
++  int integer;
++};
++
++typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
++
++typedef struct
++{
++  PREFIX(fail_stack_elt_t) *stack;
++  unsigned size;
++  unsigned avail;			/* Offset of next open position.  */
++} PREFIX(fail_stack_type);
++
++# endif /* INT_IS_16BIT */
++
++# ifndef DEFINED_ONCE
++#  define FAIL_STACK_EMPTY()     (fail_stack.avail == 0)
++#  define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
++#  define FAIL_STACK_FULL()      (fail_stack.avail == fail_stack.size)
++# endif
++
++
++/* Define macros to initialize and free the failure stack.
++   Do `return -2' if the alloc fails.  */
++
++# ifdef MATCH_MAY_ALLOCATE
++#  define INIT_FAIL_STACK()						\
++  do {									\
++    fail_stack.stack = (PREFIX(fail_stack_elt_t) *)		\
++      REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (PREFIX(fail_stack_elt_t))); \
++									\
++    if (fail_stack.stack == NULL)				\
++      return -2;							\
++									\
++    fail_stack.size = INIT_FAILURE_ALLOC;			\
++    fail_stack.avail = 0;					\
++  } while (0)
++
++#  define RESET_FAIL_STACK()  REGEX_FREE_STACK (fail_stack.stack)
++# else
++#  define INIT_FAIL_STACK()						\
++  do {									\
++    fail_stack.avail = 0;					\
++  } while (0)
++
++#  define RESET_FAIL_STACK()
++# endif
++
++
++/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
++
++   Return 1 if succeeds, and 0 if either ran out of memory
++   allocating space for it or it was already too large.
++
++   REGEX_REALLOCATE_STACK requires `destination' be declared.   */
++
++# define DOUBLE_FAIL_STACK(fail_stack)					\
++  ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS)	\
++   ? 0									\
++   : ((fail_stack).stack = (PREFIX(fail_stack_elt_t) *)			\
++        REGEX_REALLOCATE_STACK ((fail_stack).stack, 			\
++          (fail_stack).size * sizeof (PREFIX(fail_stack_elt_t)),	\
++          ((fail_stack).size << 1) * sizeof (PREFIX(fail_stack_elt_t))),\
++									\
++      (fail_stack).stack == NULL					\
++      ? 0								\
++      : ((fail_stack).size <<= 1, 					\
++         1)))
++
++
++/* Push pointer POINTER on FAIL_STACK.
++   Return 1 if was able to do so and 0 if ran out of memory allocating
++   space to do so.  */
++# define PUSH_PATTERN_OP(POINTER, FAIL_STACK)				\
++  ((FAIL_STACK_FULL ()							\
++    && !DOUBLE_FAIL_STACK (FAIL_STACK))					\
++   ? 0									\
++   : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER,	\
++      1))
++
++/* Push a pointer value onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_POINTER(item)					\
++  fail_stack.stack[fail_stack.avail++].pointer = (UCHAR_T *) (item)
++
++/* This pushes an integer-valued item onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_INT(item)					\
++  fail_stack.stack[fail_stack.avail++].integer = (item)
++
++/* Push a fail_stack_elt_t value onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_ELT(item)					\
++  fail_stack.stack[fail_stack.avail++] =  (item)
++
++/* These three POP... operations complement the three PUSH... operations.
++   All assume that `fail_stack' is nonempty.  */
++# define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
++# define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
++# define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
++
++/* Used to omit pushing failure point id's when we're not debugging.  */
++# ifdef DEBUG
++#  define DEBUG_PUSH PUSH_FAILURE_INT
++#  define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
++# else
++#  define DEBUG_PUSH(item)
++#  define DEBUG_POP(item_addr)
++# endif
++
++
++/* Push the information about the state we will need
++   if we ever fail back to it.
++
++   Requires variables fail_stack, regstart, regend, reg_info, and
++   num_regs_pushed be declared.  DOUBLE_FAIL_STACK requires `destination'
++   be declared.
++
++   Does `return FAILURE_CODE' if runs out of memory.  */
++
++# define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code)	\
++  do {									\
++    char *destination;							\
++    /* Must be int, so when we don't save any registers, the arithmetic	\
++       of 0 + -1 isn't done as unsigned.  */				\
++    /* Can't be int, since there is not a shred of a guarantee that int	\
++       is wide enough to hold a value of something to which pointer can	\
++       be assigned */							\
++    active_reg_t this_reg;						\
++    									\
++    DEBUG_STATEMENT (failure_id++);					\
++    DEBUG_STATEMENT (nfailure_points_pushed++);				\
++    DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id);		\
++    DEBUG_PRINT2 ("  Before push, next avail: %d\n", (fail_stack).avail);\
++    DEBUG_PRINT2 ("                     size: %d\n", (fail_stack).size);\
++									\
++    DEBUG_PRINT2 ("  slots needed: %ld\n", NUM_FAILURE_ITEMS);		\
++    DEBUG_PRINT2 ("     available: %d\n", REMAINING_AVAIL_SLOTS);	\
++									\
++    /* Ensure we have enough space allocated for what we will push.  */	\
++    while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS)			\
++      {									\
++        if (!DOUBLE_FAIL_STACK (fail_stack))				\
++          return failure_code;						\
++									\
++        DEBUG_PRINT2 ("\n  Doubled stack; size now: %d\n",		\
++		       (fail_stack).size);				\
++        DEBUG_PRINT2 ("  slots available: %d\n", REMAINING_AVAIL_SLOTS);\
++      }									\
++									\
++    /* Push the info, starting with the registers.  */			\
++    DEBUG_PRINT1 ("\n");						\
++									\
++    if (1)								\
++      for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
++	   this_reg++)							\
++	{								\
++	  DEBUG_PRINT2 ("  Pushing reg: %lu\n", this_reg);		\
++	  DEBUG_STATEMENT (num_regs_pushed++);				\
++									\
++	  DEBUG_PRINT2 ("    start: %p\n", regstart[this_reg]);		\
++	  PUSH_FAILURE_POINTER (regstart[this_reg]);			\
++									\
++	  DEBUG_PRINT2 ("    end: %p\n", regend[this_reg]);		\
++	  PUSH_FAILURE_POINTER (regend[this_reg]);			\
++									\
++	  DEBUG_PRINT2 ("    info: %p\n      ",				\
++			reg_info[this_reg].word.pointer);		\
++	  DEBUG_PRINT2 (" match_null=%d",				\
++			REG_MATCH_NULL_STRING_P (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" matched_something=%d",			\
++			MATCHED_SOMETHING (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" ever_matched=%d",				\
++			EVER_MATCHED_SOMETHING (reg_info[this_reg]));	\
++	  DEBUG_PRINT1 ("\n");						\
++	  PUSH_FAILURE_ELT (reg_info[this_reg].word);			\
++	}								\
++									\
++    DEBUG_PRINT2 ("  Pushing  low active reg: %ld\n", lowest_active_reg);\
++    PUSH_FAILURE_INT (lowest_active_reg);				\
++									\
++    DEBUG_PRINT2 ("  Pushing high active reg: %ld\n", highest_active_reg);\
++    PUSH_FAILURE_INT (highest_active_reg);				\
++									\
++    DEBUG_PRINT2 ("  Pushing pattern %p:\n", pattern_place);		\
++    DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend);		\
++    PUSH_FAILURE_POINTER (pattern_place);				\
++									\
++    DEBUG_PRINT2 ("  Pushing string %p: `", string_place);		\
++    DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2,   \
++				 size2);				\
++    DEBUG_PRINT1 ("'\n");						\
++    PUSH_FAILURE_POINTER (string_place);				\
++									\
++    DEBUG_PRINT2 ("  Pushing failure id: %u\n", failure_id);		\
++    DEBUG_PUSH (failure_id);						\
++  } while (0)
++
++# ifndef DEFINED_ONCE
++/* This is the number of items that are pushed and popped on the stack
++   for each register.  */
++#  define NUM_REG_ITEMS  3
++
++/* Individual items aside from the registers.  */
++#  ifdef DEBUG
++#   define NUM_NONREG_ITEMS 5 /* Includes failure point id.  */
++#  else
++#   define NUM_NONREG_ITEMS 4
++#  endif
++
++/* We push at most this many items on the stack.  */
++/* We used to use (num_regs - 1), which is the number of registers
++   this regexp will save; but that was changed to 5
++   to avoid stack overflow for a regexp with lots of parens.  */
++#  define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
++
++/* We actually push this many items.  */
++#  define NUM_FAILURE_ITEMS				\
++  (((0							\
++     ? 0 : highest_active_reg - lowest_active_reg + 1)	\
++    * NUM_REG_ITEMS)					\
++   + NUM_NONREG_ITEMS)
++
++/* How many items can still be added to the stack without overflowing it.  */
++#  define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
++# endif /* not DEFINED_ONCE */
++
++
++/* Pops what PUSH_FAIL_STACK pushes.
++
++   We restore into the parameters, all of which should be lvalues:
++     STR -- the saved data position.
++     PAT -- the saved pattern position.
++     LOW_REG, HIGH_REG -- the highest and lowest active registers.
++     REGSTART, REGEND -- arrays of string positions.
++     REG_INFO -- array of information about each subexpression.
++
++   Also assumes the variables `fail_stack' and (if debugging), `bufp',
++   `pend', `string1', `size1', `string2', and `size2'.  */
++# define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
++{									\
++  DEBUG_STATEMENT (unsigned failure_id;)				\
++  active_reg_t this_reg;						\
++  const UCHAR_T *string_temp;						\
++									\
++  assert (!FAIL_STACK_EMPTY ());					\
++									\
++  /* Remove failure points and point to how many regs pushed.  */	\
++  DEBUG_PRINT1 ("POP_FAILURE_POINT:\n");				\
++  DEBUG_PRINT2 ("  Before pop, next avail: %d\n", fail_stack.avail);	\
++  DEBUG_PRINT2 ("                    size: %d\n", fail_stack.size);	\
++									\
++  assert (fail_stack.avail >= NUM_NONREG_ITEMS);			\
++									\
++  DEBUG_POP (&failure_id);						\
++  DEBUG_PRINT2 ("  Popping failure id: %u\n", failure_id);		\
++									\
++  /* If the saved string location is NULL, it came from an		\
++     on_failure_keep_string_jump opcode, and we want to throw away the	\
++     saved NULL, thus retaining our current position in the string.  */	\
++  string_temp = POP_FAILURE_POINTER ();					\
++  if (string_temp != NULL)						\
++    str = (const CHAR_T *) string_temp;					\
++									\
++  DEBUG_PRINT2 ("  Popping string %p: `", str);				\
++  DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2);	\
++  DEBUG_PRINT1 ("'\n");							\
++									\
++  pat = (UCHAR_T *) POP_FAILURE_POINTER ();				\
++  DEBUG_PRINT2 ("  Popping pattern %p:\n", pat);			\
++  DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend);			\
++									\
++  /* Restore register info.  */						\
++  high_reg = (active_reg_t) POP_FAILURE_INT ();				\
++  DEBUG_PRINT2 ("  Popping high active reg: %ld\n", high_reg);		\
++									\
++  low_reg = (active_reg_t) POP_FAILURE_INT ();				\
++  DEBUG_PRINT2 ("  Popping  low active reg: %ld\n", low_reg);		\
++									\
++  if (1)								\
++    for (this_reg = high_reg; this_reg >= low_reg; this_reg--)		\
++      {									\
++	DEBUG_PRINT2 ("    Popping reg: %ld\n", this_reg);		\
++									\
++	reg_info[this_reg].word = POP_FAILURE_ELT ();			\
++	DEBUG_PRINT2 ("      info: %p\n",				\
++		      reg_info[this_reg].word.pointer);			\
++									\
++	regend[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER ();	\
++	DEBUG_PRINT2 ("      end: %p\n", regend[this_reg]);		\
++									\
++	regstart[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER ();	\
++	DEBUG_PRINT2 ("      start: %p\n", regstart[this_reg]);		\
++      }									\
++  else									\
++    {									\
++      for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
++	{								\
++	  reg_info[this_reg].word.integer = 0;				\
++	  regend[this_reg] = 0;						\
++	  regstart[this_reg] = 0;					\
++	}								\
++      highest_active_reg = high_reg;					\
++    }									\
++									\
++  set_regs_matched_done = 0;						\
++  DEBUG_STATEMENT (nfailure_points_popped++);				\
++} /* POP_FAILURE_POINT */
++\f
++/* Structure for per-register (a.k.a. per-group) information.
++   Other register information, such as the
++   starting and ending positions (which are addresses), and the list of
++   inner groups (which is a bits list) are maintained in separate
++   variables.
++
++   We are making a (strictly speaking) nonportable assumption here: that
++   the compiler will pack our bit fields into something that fits into
++   the type of `word', i.e., is something that fits into one item on the
++   failure stack.  */
++
++
++/* Declarations and macros for re_match_2.  */
++
++typedef union
++{
++  PREFIX(fail_stack_elt_t) word;
++  struct
++  {
++      /* This field is one if this group can match the empty string,
++         zero if not.  If not yet determined,  `MATCH_NULL_UNSET_VALUE'.  */
++# define MATCH_NULL_UNSET_VALUE 3
++    unsigned match_null_string_p : 2;
++    unsigned is_active : 1;
++    unsigned matched_something : 1;
++    unsigned ever_matched_something : 1;
++  } bits;
++} PREFIX(register_info_type);
++
++# ifndef DEFINED_ONCE
++#  define REG_MATCH_NULL_STRING_P(R)  ((R).bits.match_null_string_p)
++#  define IS_ACTIVE(R)  ((R).bits.is_active)
++#  define MATCHED_SOMETHING(R)  ((R).bits.matched_something)
++#  define EVER_MATCHED_SOMETHING(R)  ((R).bits.ever_matched_something)
++
++
++/* Call this when have matched a real character; it sets `matched' flags
++   for the subexpressions which we are currently inside.  Also records
++   that those subexprs have matched.  */
++#  define SET_REGS_MATCHED()						\
++  do									\
++    {									\
++      if (!set_regs_matched_done)					\
++	{								\
++	  active_reg_t r;						\
++	  set_regs_matched_done = 1;					\
++	  for (r = lowest_active_reg; r <= highest_active_reg; r++)	\
++	    {								\
++	      MATCHED_SOMETHING (reg_info[r])				\
++		= EVER_MATCHED_SOMETHING (reg_info[r])			\
++		= 1;							\
++	    }								\
++	}								\
++    }									\
++  while (0)
++# endif /* not DEFINED_ONCE */
++
++/* Registers are set to a sentinel when they haven't yet matched.  */
++static CHAR_T PREFIX(reg_unset_dummy);
++# define REG_UNSET_VALUE (&PREFIX(reg_unset_dummy))
++# define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
++
++/* Subroutine declarations and macros for regex_compile.  */
++static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg);
++static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc,
++                               int arg1, int arg2);
++static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc,
++                                int arg, UCHAR_T *end);
++static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc,
++                                int arg1, int arg2, UCHAR_T *end);
++static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern,
++                                         const CHAR_T *p,
++                                         reg_syntax_t syntax);
++static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p,
++                                         const CHAR_T *pend,
++                                         reg_syntax_t syntax);
++# ifdef WCHAR
++static reg_errcode_t wcs_compile_range (CHAR_T range_start,
++                                        const CHAR_T **p_ptr,
++                                        const CHAR_T *pend,
++                                        char *translate,
++                                        reg_syntax_t syntax,
++                                        UCHAR_T *b,
++                                        CHAR_T *char_set);
++static void insert_space (int num, CHAR_T *loc, CHAR_T *end);
++# else /* BYTE */
++static reg_errcode_t byte_compile_range (unsigned int range_start,
++                                         const char **p_ptr,
++                                         const char *pend,
++                                         RE_TRANSLATE_TYPE translate,
++                                         reg_syntax_t syntax,
++                                         unsigned char *b);
++# endif /* WCHAR */
++
++/* Fetch the next character in the uncompiled pattern---translating it
++   if necessary.  Also cast from a signed character in the constant
++   string passed to us by the user to an unsigned char that we can use
++   as an array index (in, e.g., `translate').  */
++/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
++   because it is impossible to allocate 4GB array for some encodings
++   which have 4 byte character_set like UCS4.  */
++# ifndef PATFETCH
++#  ifdef WCHAR
++#   define PATFETCH(c)							\
++  do {if (p == pend) return REG_EEND;					\
++    c = (UCHAR_T) *p++;							\
++    if (translate && (c <= 0xff)) c = (UCHAR_T) translate[c];		\
++  } while (0)
++#  else /* BYTE */
++#   define PATFETCH(c)							\
++  do {if (p == pend) return REG_EEND;					\
++    c = (unsigned char) *p++;						\
++    if (translate) c = (unsigned char) translate[c];			\
++  } while (0)
++#  endif /* WCHAR */
++# endif
++
++/* Fetch the next character in the uncompiled pattern, with no
++   translation.  */
++# define PATFETCH_RAW(c)						\
++  do {if (p == pend) return REG_EEND;					\
++    c = (UCHAR_T) *p++; 	       					\
++  } while (0)
++
++/* Go backwards one character in the pattern.  */
++# define PATUNFETCH p--
++
++
++/* If `translate' is non-null, return translate[D], else just D.  We
++   cast the subscript to translate because some data is declared as
++   `char *', to avoid warnings when a string constant is passed.  But
++   when we use a character as a subscript we must make it unsigned.  */
++/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
++   because it is impossible to allocate 4GB array for some encodings
++   which have 4 byte character_set like UCS4.  */
++
++# ifndef TRANSLATE
++#  ifdef WCHAR
++#   define TRANSLATE(d) \
++  ((translate && ((UCHAR_T) (d)) <= 0xff) \
++   ? (char) translate[(unsigned char) (d)] : (d))
++# else /* BYTE */
++#   define TRANSLATE(d) \
++  (translate ? (char) translate[(unsigned char) (d)] : (char) (d))
++#  endif /* WCHAR */
++# endif
++
++
++/* Macros for outputting the compiled pattern into `buffer'.  */
++
++/* If the buffer isn't allocated when it comes in, use this.  */
++# define INIT_BUF_SIZE  (32 * sizeof(UCHAR_T))
++
++/* Make sure we have at least N more bytes of space in buffer.  */
++# ifdef WCHAR
++#  define GET_BUFFER_SPACE(n)						\
++    while (((unsigned long)b - (unsigned long)COMPILED_BUFFER_VAR	\
++            + (n)*sizeof(CHAR_T)) > bufp->allocated)			\
++      EXTEND_BUFFER ()
++# else /* BYTE */
++#  define GET_BUFFER_SPACE(n)						\
++    while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated)	\
++      EXTEND_BUFFER ()
++# endif /* WCHAR */
++
++/* Make sure we have one more byte of buffer space and then add C to it.  */
++# define BUF_PUSH(c)							\
++  do {									\
++    GET_BUFFER_SPACE (1);						\
++    *b++ = (UCHAR_T) (c);						\
++  } while (0)
++
++
++/* Ensure we have two more bytes of buffer space and then append C1 and C2.  */
++# define BUF_PUSH_2(c1, c2)						\
++  do {									\
++    GET_BUFFER_SPACE (2);						\
++    *b++ = (UCHAR_T) (c1);						\
++    *b++ = (UCHAR_T) (c2);						\
++  } while (0)
++
++
++/* As with BUF_PUSH_2, except for three bytes.  */
++# define BUF_PUSH_3(c1, c2, c3)						\
++  do {									\
++    GET_BUFFER_SPACE (3);						\
++    *b++ = (UCHAR_T) (c1);						\
++    *b++ = (UCHAR_T) (c2);						\
++    *b++ = (UCHAR_T) (c3);						\
++  } while (0)
++
++/* Store a jump with opcode OP at LOC to location TO.  We store a
++   relative address offset by the three bytes the jump itself occupies.  */
++# define STORE_JUMP(op, loc, to) \
++ PREFIX(store_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)))
++
++/* Likewise, for a two-argument jump.  */
++# define STORE_JUMP2(op, loc, to, arg) \
++  PREFIX(store_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), arg)
++
++/* Like `STORE_JUMP', but for inserting.  Assume `b' is the buffer end.  */
++# define INSERT_JUMP(op, loc, to) \
++  PREFIX(insert_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), b)
++
++/* Like `STORE_JUMP2', but for inserting.  Assume `b' is the buffer end.  */
++# define INSERT_JUMP2(op, loc, to, arg) \
++  PREFIX(insert_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)),\
++	      arg, b)
++
++/* This is not an arbitrary limit: the arguments which represent offsets
++   into the pattern are two bytes long.  So if 2^16 bytes turns out to
++   be too small, many things would have to change.  */
++/* Any other compiler which, like MSC, has allocation limit below 2^16
++   bytes will have to use approach similar to what was done below for
++   MSC and drop MAX_BUF_SIZE a bit.  Otherwise you may end up
++   reallocating to 0 bytes.  Such thing is not going to work too well.
++   You have been warned!!  */
++# ifndef DEFINED_ONCE
++#  if defined _MSC_VER  && !defined WIN32
++/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
++   The REALLOC define eliminates a flurry of conversion warnings,
++   but is not required. */
++#   define MAX_BUF_SIZE  65500L
++#   define REALLOC(p,s) realloc ((p), (size_t) (s))
++#  else
++#   define MAX_BUF_SIZE (1L << 16)
++#   define REALLOC(p,s) realloc ((p), (s))
++#  endif
++
++/* Extend the buffer by twice its current size via realloc and
++   reset the pointers that pointed into the old block to point to the
++   correct places in the new one.  If extending the buffer results in it
++   being larger than MAX_BUF_SIZE, then flag memory exhausted.  */
++#  if __BOUNDED_POINTERS__
++#   define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
++#   define MOVE_BUFFER_POINTER(P) \
++  (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
++#   define ELSE_EXTEND_BUFFER_HIGH_BOUND	\
++  else						\
++    {						\
++      SET_HIGH_BOUND (b);			\
++      SET_HIGH_BOUND (begalt);			\
++      if (fixup_alt_jump)			\
++	SET_HIGH_BOUND (fixup_alt_jump);	\
++      if (laststart)				\
++	SET_HIGH_BOUND (laststart);		\
++      if (pending_exact)			\
++	SET_HIGH_BOUND (pending_exact);		\
++    }
++#  else
++#   define MOVE_BUFFER_POINTER(P) (P) += incr
++#   define ELSE_EXTEND_BUFFER_HIGH_BOUND
++#  endif
++# endif /* not DEFINED_ONCE */
++
++# ifdef WCHAR
++#  define EXTEND_BUFFER()						\
++  do {									\
++    UCHAR_T *old_buffer = COMPILED_BUFFER_VAR;				\
++    int wchar_count;							\
++    if (bufp->allocated + sizeof(UCHAR_T) > MAX_BUF_SIZE)		\
++      return REG_ESIZE;							\
++    bufp->allocated <<= 1;						\
++    if (bufp->allocated > MAX_BUF_SIZE)					\
++      bufp->allocated = MAX_BUF_SIZE;					\
++    /* How many characters the new buffer can have?  */			\
++    wchar_count = bufp->allocated / sizeof(UCHAR_T);			\
++    if (wchar_count == 0) wchar_count = 1;				\
++    /* Truncate the buffer to CHAR_T align.  */			\
++    bufp->allocated = wchar_count * sizeof(UCHAR_T);			\
++    RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T);		\
++    bufp->buffer = (char*)COMPILED_BUFFER_VAR;				\
++    if (COMPILED_BUFFER_VAR == NULL)					\
++      return REG_ESPACE;						\
++    /* If the buffer moved, move all the pointers into it.  */		\
++    if (old_buffer != COMPILED_BUFFER_VAR)				\
++      {									\
++	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
++	MOVE_BUFFER_POINTER (b);					\
++	MOVE_BUFFER_POINTER (begalt);					\
++	if (fixup_alt_jump)						\
++	  MOVE_BUFFER_POINTER (fixup_alt_jump);				\
++	if (laststart)							\
++	  MOVE_BUFFER_POINTER (laststart);				\
++	if (pending_exact)						\
++	  MOVE_BUFFER_POINTER (pending_exact);				\
++      }									\
++    ELSE_EXTEND_BUFFER_HIGH_BOUND					\
++  } while (0)
++# else /* BYTE */
++#  define EXTEND_BUFFER()						\
++  do {									\
++    UCHAR_T *old_buffer = COMPILED_BUFFER_VAR;				\
++    if (bufp->allocated == MAX_BUF_SIZE)				\
++      return REG_ESIZE;							\
++    bufp->allocated <<= 1;						\
++    if (bufp->allocated > MAX_BUF_SIZE)					\
++      bufp->allocated = MAX_BUF_SIZE;					\
++    bufp->buffer = (UCHAR_T *) REALLOC (COMPILED_BUFFER_VAR,		\
++						bufp->allocated);	\
++    if (COMPILED_BUFFER_VAR == NULL)					\
++      return REG_ESPACE;						\
++    /* If the buffer moved, move all the pointers into it.  */		\
++    if (old_buffer != COMPILED_BUFFER_VAR)				\
++      {									\
++	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
++	MOVE_BUFFER_POINTER (b);					\
++	MOVE_BUFFER_POINTER (begalt);					\
++	if (fixup_alt_jump)						\
++	  MOVE_BUFFER_POINTER (fixup_alt_jump);				\
++	if (laststart)							\
++	  MOVE_BUFFER_POINTER (laststart);				\
++	if (pending_exact)						\
++	  MOVE_BUFFER_POINTER (pending_exact);				\
++      }									\
++    ELSE_EXTEND_BUFFER_HIGH_BOUND					\
++  } while (0)
++# endif /* WCHAR */
++
++# ifndef DEFINED_ONCE
++/* Since we have one byte reserved for the register number argument to
++   {start,stop}_memory, the maximum number of groups we can report
++   things about is what fits in that byte.  */
++#  define MAX_REGNUM 255
++
++/* But patterns can have more than `MAX_REGNUM' registers.  We just
++   ignore the excess.  */
++typedef unsigned regnum_t;
++
++
++/* Macros for the compile stack.  */
++
++/* Since offsets can go either forwards or backwards, this type needs to
++   be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1.  */
++/* int may be not enough when sizeof(int) == 2.  */
++typedef long pattern_offset_t;
++
++typedef struct
++{
++  pattern_offset_t begalt_offset;
++  pattern_offset_t fixup_alt_jump;
++  pattern_offset_t inner_group_offset;
++  pattern_offset_t laststart_offset;
++  regnum_t regnum;
++} compile_stack_elt_t;
++
++
++typedef struct
++{
++  compile_stack_elt_t *stack;
++  unsigned size;
++  unsigned avail;			/* Offset of next open position.  */
++} compile_stack_type;
++
++
++#  define INIT_COMPILE_STACK_SIZE 32
++
++#  define COMPILE_STACK_EMPTY  (compile_stack.avail == 0)
++#  define COMPILE_STACK_FULL  (compile_stack.avail == compile_stack.size)
++
++/* The next available element.  */
++#  define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
++
++# endif /* not DEFINED_ONCE */
++
++/* Set the bit for character C in a list.  */
++# ifndef DEFINED_ONCE
++#  define SET_LIST_BIT(c)                               \
++  (b[((unsigned char) (c)) / BYTEWIDTH]               \
++   |= 1 << (((unsigned char) c) % BYTEWIDTH))
++# endif /* DEFINED_ONCE */
++
++/* Get the next unsigned number in the uncompiled pattern.  */
++# define GET_UNSIGNED_NUMBER(num) \
++  {									\
++    while (p != pend)							\
++      {									\
++	PATFETCH (c);							\
++	if (c < '0' || c > '9')						\
++	  break;							\
++	if (num <= RE_DUP_MAX)						\
++	  {								\
++	    if (num < 0)						\
++	      num = 0;							\
++	    num = num * 10 + c - '0';					\
++	  }								\
++      }									\
++  }
++
++# ifndef DEFINED_ONCE
++#  if WIDE_CHAR_SUPPORT
++/* The GNU C library provides support for user-defined character classes
++   and the functions from ISO C amendement 1.  */
++#   ifdef CHARCLASS_NAME_MAX
++#    define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
++#   else
++/* This shouldn't happen but some implementation might still have this
++   problem.  Use a reasonable default value.  */
++#    define CHAR_CLASS_MAX_LENGTH 256
++#   endif
++
++#   ifdef _LIBC
++#    define IS_CHAR_CLASS(string) __wctype (string)
++#   else
++#    define IS_CHAR_CLASS(string) wctype (string)
++#   endif
++#  else
++#   define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
++
++#   define IS_CHAR_CLASS(string)					\
++   (STREQ (string, "alpha") || STREQ (string, "upper")			\
++    || STREQ (string, "lower") || STREQ (string, "digit")		\
++    || STREQ (string, "alnum") || STREQ (string, "xdigit")		\
++    || STREQ (string, "space") || STREQ (string, "print")		\
++    || STREQ (string, "punct") || STREQ (string, "graph")		\
++    || STREQ (string, "cntrl") || STREQ (string, "blank"))
++#  endif
++# endif /* DEFINED_ONCE */
++\f
++# ifndef MATCH_MAY_ALLOCATE
++
++/* If we cannot allocate large objects within re_match_2_internal,
++   we make the fail stack and register vectors global.
++   The fail stack, we grow to the maximum size when a regexp
++   is compiled.
++   The register vectors, we adjust in size each time we
++   compile a regexp, according to the number of registers it needs.  */
++
++static PREFIX(fail_stack_type) fail_stack;
++
++/* Size with which the following vectors are currently allocated.
++   That is so we can make them bigger as needed,
++   but never make them smaller.  */
++#  ifdef DEFINED_ONCE
++static int regs_allocated_size;
++
++static const char **     regstart, **     regend;
++static const char ** old_regstart, ** old_regend;
++static const char **best_regstart, **best_regend;
++static const char **reg_dummy;
++#  endif /* DEFINED_ONCE */
++
++static PREFIX(register_info_type) *PREFIX(reg_info);
++static PREFIX(register_info_type) *PREFIX(reg_info_dummy);
++
++/* Make the register vectors big enough for NUM_REGS registers,
++   but don't make them smaller.  */
++
++static void
++PREFIX(regex_grow_registers) (int num_regs)
++{
++  if (num_regs > regs_allocated_size)
++    {
++      RETALLOC_IF (regstart,	 num_regs, const char *);
++      RETALLOC_IF (regend,	 num_regs, const char *);
++      RETALLOC_IF (old_regstart, num_regs, const char *);
++      RETALLOC_IF (old_regend,	 num_regs, const char *);
++      RETALLOC_IF (best_regstart, num_regs, const char *);
++      RETALLOC_IF (best_regend,	 num_regs, const char *);
++      RETALLOC_IF (PREFIX(reg_info), num_regs, PREFIX(register_info_type));
++      RETALLOC_IF (reg_dummy,	 num_regs, const char *);
++      RETALLOC_IF (PREFIX(reg_info_dummy), num_regs, PREFIX(register_info_type));
++
++      regs_allocated_size = num_regs;
++    }
++}
++
++# endif /* not MATCH_MAY_ALLOCATE */
++\f
++# ifndef DEFINED_ONCE
++static boolean group_in_compile_stack (compile_stack_type compile_stack,
++                                       regnum_t regnum);
++# endif /* not DEFINED_ONCE */
++
++/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
++   Returns one of error codes defined in `regex.h', or zero for success.
++
++   Assumes the `allocated' (and perhaps `buffer') and `translate'
++   fields are set in BUFP on entry.
++
++   If it succeeds, results are put in BUFP (if it returns an error, the
++   contents of BUFP are undefined):
++     `buffer' is the compiled pattern;
++     `syntax' is set to SYNTAX;
++     `used' is set to the length of the compiled pattern;
++     `fastmap_accurate' is zero;
++     `re_nsub' is the number of subexpressions in PATTERN;
++     `not_bol' and `not_eol' are zero;
++
++   The `fastmap' and `newline_anchor' fields are neither
++   examined nor set.  */
++
++/* Return, freeing storage we allocated.  */
++# ifdef WCHAR
++#  define FREE_STACK_RETURN(value)		\
++  return (free(pattern), free(mbs_offset), free(is_binary), free (compile_stack.stack), value)
++# else
++#  define FREE_STACK_RETURN(value)		\
++  return (free (compile_stack.stack), value)
++# endif /* WCHAR */
++
++static reg_errcode_t
++PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
++                       size_t ARG_PREFIX(size), reg_syntax_t syntax,
++                       struct re_pattern_buffer *bufp)
++{
++  /* We fetch characters from PATTERN here.  Even though PATTERN is
++     `char *' (i.e., signed), we declare these variables as unsigned, so
++     they can be reliably used as array indices.  */
++  register UCHAR_T c, c1;
++
++#ifdef WCHAR
++  /* A temporary space to keep wchar_t pattern and compiled pattern.  */
++  CHAR_T *pattern, *COMPILED_BUFFER_VAR;
++  size_t size;
++  /* offset buffer for optimization. See convert_mbs_to_wc.  */
++  int *mbs_offset = NULL;
++  /* It hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++  /* A flag whether exactn is handling binary data or not.  */
++  char is_exactn_bin = FALSE;
++#endif /* WCHAR */
++
++  /* A random temporary spot in PATTERN.  */
++  const CHAR_T *p1;
++
++  /* Points to the end of the buffer, where we should append.  */
++  register UCHAR_T *b;
++
++  /* Keeps track of unclosed groups.  */
++  compile_stack_type compile_stack;
++
++  /* Points to the current (ending) position in the pattern.  */
++#ifdef WCHAR
++  const CHAR_T *p;
++  const CHAR_T *pend;
++#else /* BYTE */
++  const CHAR_T *p = pattern;
++  const CHAR_T *pend = pattern + size;
++#endif /* WCHAR */
++
++  /* How to translate the characters in the pattern.  */
++  RE_TRANSLATE_TYPE translate = bufp->translate;
++
++  /* Address of the count-byte of the most recently inserted `exactn'
++     command.  This makes it possible to tell if a new exact-match
++     character can be added to that command or if the character requires
++     a new `exactn' command.  */
++  UCHAR_T *pending_exact = 0;
++
++  /* Address of start of the most recently finished expression.
++     This tells, e.g., postfix * where to find the start of its
++     operand.  Reset at the beginning of groups and alternatives.  */
++  UCHAR_T *laststart = 0;
++
++  /* Address of beginning of regexp, or inside of last group.  */
++  UCHAR_T *begalt;
++
++  /* Address of the place where a forward jump should go to the end of
++     the containing expression.  Each alternative of an `or' -- except the
++     last -- ends with a forward jump of this sort.  */
++  UCHAR_T *fixup_alt_jump = 0;
++
++  /* Counts open-groups as they are encountered.  Remembered for the
++     matching close-group on the compile stack, so the same register
++     number is put in the stop_memory as the start_memory.  */
++  regnum_t regnum = 0;
++
++#ifdef WCHAR
++  /* Initialize the wchar_t PATTERN and offset_buffer.  */
++  p = pend = pattern = TALLOC(csize + 1, CHAR_T);
++  mbs_offset = TALLOC(csize + 1, int);
++  is_binary = TALLOC(csize + 1, char);
++  if (pattern == NULL || mbs_offset == NULL || is_binary == NULL)
++    {
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++      return REG_ESPACE;
++    }
++  pattern[csize] = L'\0';	/* sentinel */
++  size = convert_mbs_to_wcs(pattern, cpattern, csize, mbs_offset, is_binary);
++  pend = p + size;
++  if (size < 0)
++    {
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++      return REG_BADPAT;
++    }
++#endif
++
++#ifdef DEBUG
++  DEBUG_PRINT1 ("\nCompiling pattern: ");
++  if (debug)
++    {
++      unsigned debug_count;
++
++      for (debug_count = 0; debug_count < size; debug_count++)
++        PUT_CHAR (pattern[debug_count]);
++      putchar ('\n');
++    }
++#endif /* DEBUG */
++
++  /* Initialize the compile stack.  */
++  compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
++  if (compile_stack.stack == NULL)
++    {
++#ifdef WCHAR
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++#endif
++      return REG_ESPACE;
++    }
++
++  compile_stack.size = INIT_COMPILE_STACK_SIZE;
++  compile_stack.avail = 0;
++
++  /* Initialize the pattern buffer.  */
++  bufp->syntax = syntax;
++  bufp->fastmap_accurate = 0;
++  bufp->not_bol = bufp->not_eol = 0;
++
++  /* Set `used' to zero, so that if we return an error, the pattern
++     printer (for debugging) will think there's no pattern.  We reset it
++     at the end.  */
++  bufp->used = 0;
++
++  /* Always count groups, whether or not bufp->no_sub is set.  */
++  bufp->re_nsub = 0;
++
++#if !defined emacs && !defined SYNTAX_TABLE
++  /* Initialize the syntax table.  */
++   init_syntax_once ();
++#endif
++
++  if (bufp->allocated == 0)
++    {
++      if (bufp->buffer)
++	{ /* If zero allocated, but buffer is non-null, try to realloc
++             enough space.  This loses if buffer's address is bogus, but
++             that is the user's responsibility.  */
++#ifdef WCHAR
++	  /* Free bufp->buffer and allocate an array for wchar_t pattern
++	     buffer.  */
++          free(bufp->buffer);
++          COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE/sizeof(UCHAR_T),
++					UCHAR_T);
++#else
++          RETALLOC (COMPILED_BUFFER_VAR, INIT_BUF_SIZE, UCHAR_T);
++#endif /* WCHAR */
++        }
++      else
++        { /* Caller did not allocate a buffer.  Do it for them.  */
++          COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE / sizeof(UCHAR_T),
++					UCHAR_T);
++        }
++
++      if (!COMPILED_BUFFER_VAR) FREE_STACK_RETURN (REG_ESPACE);
++#ifdef WCHAR
++      bufp->buffer = (char*)COMPILED_BUFFER_VAR;
++#endif /* WCHAR */
++      bufp->allocated = INIT_BUF_SIZE;
++    }
++#ifdef WCHAR
++  else
++    COMPILED_BUFFER_VAR = (UCHAR_T*) bufp->buffer;
++#endif
++
++  begalt = b = COMPILED_BUFFER_VAR;
++
++  /* Loop through the uncompiled pattern until we're at the end.  */
++  while (p != pend)
++    {
++      PATFETCH (c);
++
++      switch (c)
++        {
++        case '^':
++          {
++            if (   /* If at start of pattern, it's an operator.  */
++                   p == pattern + 1
++                   /* If context independent, it's an operator.  */
++                || syntax & RE_CONTEXT_INDEP_ANCHORS
++                   /* Otherwise, depends on what's come before.  */
++                || PREFIX(at_begline_loc_p) (pattern, p, syntax))
++              BUF_PUSH (begline);
++            else
++              goto normal_char;
++          }
++          break;
++
++
++        case '$':
++          {
++            if (   /* If at end of pattern, it's an operator.  */
++                   p == pend
++                   /* If context independent, it's an operator.  */
++                || syntax & RE_CONTEXT_INDEP_ANCHORS
++                   /* Otherwise, depends on what's next.  */
++                || PREFIX(at_endline_loc_p) (p, pend, syntax))
++               BUF_PUSH (endline);
++             else
++               goto normal_char;
++           }
++           break;
++
++
++	case '+':
++        case '?':
++          if ((syntax & RE_BK_PLUS_QM)
++              || (syntax & RE_LIMITED_OPS))
++            goto normal_char;
++        handle_plus:
++        case '*':
++          /* If there is no previous pattern... */
++          if (!laststart)
++            {
++              if (syntax & RE_CONTEXT_INVALID_OPS)
++                FREE_STACK_RETURN (REG_BADRPT);
++              else if (!(syntax & RE_CONTEXT_INDEP_OPS))
++                goto normal_char;
++            }
++
++          {
++            /* Are we optimizing this jump?  */
++            boolean keep_string_p = false;
++
++            /* 1 means zero (many) matches is allowed.  */
++            char zero_times_ok = 0, many_times_ok = 0;
++
++            /* If there is a sequence of repetition chars, collapse it
++               down to just one (the right one).  We can't combine
++               interval operators with these because of, e.g., `a{2}*',
++               which should only match an even number of `a's.  */
++
++            for (;;)
++              {
++                zero_times_ok |= c != '+';
++                many_times_ok |= c != '?';
++
++                if (p == pend)
++                  break;
++
++                PATFETCH (c);
++
++                if (c == '*'
++                    || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
++                  ;
++
++                else if (syntax & RE_BK_PLUS_QM  &&  c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++                    if (!(c1 == '+' || c1 == '?'))
++                      {
++                        PATUNFETCH;
++                        PATUNFETCH;
++                        break;
++                      }
++
++                    c = c1;
++                  }
++                else
++                  {
++                    PATUNFETCH;
++                    break;
++                  }
++
++                /* If we get here, we found another repeat character.  */
++               }
++
++            /* Star, etc. applied to an empty pattern is equivalent
++               to an empty pattern.  */
++            if (!laststart)
++              break;
++
++            /* Now we know whether or not zero matches is allowed
++               and also whether or not two or more matches is allowed.  */
++            if (many_times_ok)
++              { /* More than one repetition is allowed, so put in at the
++                   end a backward relative jump from `b' to before the next
++                   jump we're going to put in below (which jumps from
++                   laststart to after this jump).
++
++                   But if we are at the `*' in the exact sequence `.*\n',
++                   insert an unconditional jump backwards to the .,
++                   instead of the beginning of the loop.  This way we only
++                   push a failure point once, instead of every time
++                   through the loop.  */
++                assert (p - 1 > pattern);
++
++                /* Allocate the space for the jump.  */
++                GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++
++                /* We know we are not at the first character of the pattern,
++                   because laststart was nonzero.  And we've already
++                   incremented `p', by the way, to be the character after
++                   the `*'.  Do we have to do something analogous here
++                   for null bytes, because of RE_DOT_NOT_NULL?  */
++                if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
++		    && zero_times_ok
++                    && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
++                    && !(syntax & RE_DOT_NEWLINE))
++                  { /* We have .*\n.  */
++                    STORE_JUMP (jump, b, laststart);
++                    keep_string_p = true;
++                  }
++                else
++                  /* Anything else.  */
++                  STORE_JUMP (maybe_pop_jump, b, laststart -
++			      (1 + OFFSET_ADDRESS_SIZE));
++
++                /* We've added more stuff to the buffer.  */
++                b += 1 + OFFSET_ADDRESS_SIZE;
++              }
++
++            /* On failure, jump from laststart to b + 3, which will be the
++               end of the buffer after this jump is inserted.  */
++	    /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' instead of
++	       'b + 3'.  */
++            GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++            INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
++                                       : on_failure_jump,
++                         laststart, b + 1 + OFFSET_ADDRESS_SIZE);
++            pending_exact = 0;
++            b += 1 + OFFSET_ADDRESS_SIZE;
++
++            if (!zero_times_ok)
++              {
++                /* At least one repetition is required, so insert a
++                   `dummy_failure_jump' before the initial
++                   `on_failure_jump' instruction of the loop. This
++                   effects a skip over that instruction the first time
++                   we hit that loop.  */
++                GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++                INSERT_JUMP (dummy_failure_jump, laststart, laststart +
++			     2 + 2 * OFFSET_ADDRESS_SIZE);
++                b += 1 + OFFSET_ADDRESS_SIZE;
++              }
++            }
++	  break;
++
++
++	case '.':
++          laststart = b;
++          BUF_PUSH (anychar);
++          break;
++
++
++        case '[':
++          {
++            boolean had_char_class = false;
++#ifdef WCHAR
++	    CHAR_T range_start = 0xffffffff;
++#else
++	    unsigned int range_start = 0xffffffff;
++#endif
++            if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++#ifdef WCHAR
++	    /* We assume a charset(_not) structure as a wchar_t array.
++	       charset[0] = (re_opcode_t) charset(_not)
++               charset[1] = l (= length of char_classes)
++               charset[2] = m (= length of collating_symbols)
++               charset[3] = n (= length of equivalence_classes)
++	       charset[4] = o (= length of char_ranges)
++	       charset[5] = p (= length of chars)
++
++               charset[6] = char_class (wctype_t)
++               charset[6+CHAR_CLASS_SIZE] = char_class (wctype_t)
++                         ...
++               charset[l+5]  = char_class (wctype_t)
++
++               charset[l+6]  = collating_symbol (wchar_t)
++                            ...
++               charset[l+m+5]  = collating_symbol (wchar_t)
++					ifdef _LIBC we use the index if
++					_NL_COLLATE_SYMB_EXTRAMB instead of
++					wchar_t string.
++
++               charset[l+m+6]  = equivalence_classes (wchar_t)
++                              ...
++               charset[l+m+n+5]  = equivalence_classes (wchar_t)
++					ifdef _LIBC we use the index in
++					_NL_COLLATE_WEIGHT instead of
++					wchar_t string.
++
++	       charset[l+m+n+6] = range_start
++	       charset[l+m+n+7] = range_end
++	                       ...
++	       charset[l+m+n+2o+4] = range_start
++	       charset[l+m+n+2o+5] = range_end
++					ifdef _LIBC we use the value looked up
++					in _NL_COLLATE_COLLSEQ instead of
++					wchar_t character.
++
++	       charset[l+m+n+2o+6] = char
++	                          ...
++	       charset[l+m+n+2o+p+5] = char
++
++	     */
++
++	    /* We need at least 6 spaces: the opcode, the length of
++               char_classes, the length of collating_symbols, the length of
++               equivalence_classes, the length of char_ranges, the length of
++               chars.  */
++	    GET_BUFFER_SPACE (6);
++
++	    /* Save b as laststart. And We use laststart as the pointer
++	       to the first element of the charset here.
++	       In other words, laststart[i] indicates charset[i].  */
++            laststart = b;
++
++            /* We test `*p == '^' twice, instead of using an if
++               statement, so we only need one BUF_PUSH.  */
++            BUF_PUSH (*p == '^' ? charset_not : charset);
++            if (*p == '^')
++              p++;
++
++            /* Push the length of char_classes, the length of
++               collating_symbols, the length of equivalence_classes, the
++               length of char_ranges and the length of chars.  */
++            BUF_PUSH_3 (0, 0, 0);
++            BUF_PUSH_2 (0, 0);
++
++            /* Remember the first position in the bracket expression.  */
++            p1 = p;
++
++            /* charset_not matches newline according to a syntax bit.  */
++            if ((re_opcode_t) b[-6] == charset_not
++                && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
++	      {
++		BUF_PUSH('\n');
++		laststart[5]++; /* Update the length of characters  */
++	      }
++
++            /* Read in characters and ranges, setting map bits.  */
++            for (;;)
++              {
++                if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                PATFETCH (c);
++
++                /* \ might escape characters inside [...] and [^...].  */
++                if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++		    BUF_PUSH(c1);
++		    laststart[5]++; /* Update the length of chars  */
++		    range_start = c1;
++                    continue;
++                  }
++
++                /* Could be the end of the bracket expression.  If it's
++                   not (i.e., when the bracket expression is `[]' so
++                   far), the ']' character bit gets set way below.  */
++                if (c == ']' && p != p1 + 1)
++                  break;
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character class.  */
++                if (had_char_class && c == '-' && *p != ']')
++                  FREE_STACK_RETURN (REG_ERANGE);
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character: if this is a hyphen not at the
++                   beginning or the end of a list, then it's the range
++                   operator.  */
++                if (c == '-'
++                    && !(p - 2 >= pattern && p[-2] == '[')
++                    && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
++                    && *p != ']')
++                  {
++                    reg_errcode_t ret;
++		    /* Allocate the space for range_start and range_end.  */
++		    GET_BUFFER_SPACE (2);
++		    /* Update the pointer to indicate end of buffer.  */
++                    b += 2;
++                    ret = wcs_compile_range (range_start, &p, pend, translate,
++                                         syntax, b, laststart);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++                    range_start = 0xffffffff;
++                  }
++                else if (p[0] == '-' && p[1] != ']')
++                  { /* This handles ranges made up of characters only.  */
++                    reg_errcode_t ret;
++
++		    /* Move past the `-'.  */
++                    PATFETCH (c1);
++		    /* Allocate the space for range_start and range_end.  */
++		    GET_BUFFER_SPACE (2);
++		    /* Update the pointer to indicate end of buffer.  */
++                    b += 2;
++                    ret = wcs_compile_range (c, &p, pend, translate, syntax, b,
++                                         laststart);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                /* See if we're at the beginning of a possible character
++                   class.  */
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
++                  { /* Leave room for the null.  */
++                    char str[CHAR_CLASS_MAX_LENGTH + 1];
++
++                    PATFETCH (c);
++                    c1 = 0;
++
++                    /* If pattern is `[[:'.  */
++                    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                    for (;;)
++                      {
++                        PATFETCH (c);
++                        if ((c == ':' && *p == ']') || p == pend)
++                          break;
++			if (c1 < CHAR_CLASS_MAX_LENGTH)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++                    str[c1] = '\0';
++
++                    /* If isn't a word bracketed by `[:' and `:]':
++                       undo the ending character, the letters, and leave
++                       the leading `:' and `[' (but store them as character).  */
++                    if (c == ':' && *p == ']')
++                      {
++			wctype_t wt;
++			uintptr_t alignedp;
++
++			/* Query the character class as wctype_t.  */
++			wt = IS_CHAR_CLASS (str);
++			if (wt == 0)
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++			/* Allocate the space for character class.  */
++                        GET_BUFFER_SPACE(CHAR_CLASS_SIZE);
++			/* Update the pointer to indicate end of buffer.  */
++                        b += CHAR_CLASS_SIZE;
++			/* Move data which follow character classes
++			    not to violate the data.  */
++                        insert_space(CHAR_CLASS_SIZE,
++				     laststart + 6 + laststart[1],
++				     b - 1);
++			alignedp = ((uintptr_t)(laststart + 6 + laststart[1])
++				    + __alignof__(wctype_t) - 1)
++			  	    & ~(uintptr_t)(__alignof__(wctype_t) - 1);
++			/* Store the character class.  */
++                        *((wctype_t*)alignedp) = wt;
++                        /* Update length of char_classes */
++                        laststart[1] += CHAR_CLASS_SIZE;
++
++                        had_char_class = true;
++                      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        BUF_PUSH ('[');
++                        BUF_PUSH (':');
++                        laststart[5] += 2; /* Update the length of characters  */
++			range_start = ':';
++                        had_char_class = false;
++                      }
++                  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && (*p == '='
++							  || *p == '.'))
++		  {
++		    CHAR_T str[128];	/* Should be large enough.  */
++		    CHAR_T delim = *p; /* '=' or '.'  */
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[=' or '[[.'.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == delim && *p == ']') || p == pend)
++			  break;
++			if (c1 < sizeof (str) - 1)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == delim && *p == ']' && str[0] != '\0')
++		      {
++                        unsigned int i, offset;
++			/* If we have no collation data we use the default
++			   collation in which each character is in a class
++			   by itself.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++
++                        /* If not defined _LIBC, we push the name and
++			   `\0' for the sake of matching performance.  */
++			int datasize = c1 + 1;
++
++# ifdef _LIBC
++			int32_t idx = 0;
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    const int32_t *table;
++			    const int32_t *weights;
++			    const int32_t *extra;
++			    const int32_t *indirect;
++			    wint_t *cp;
++
++			    /* This #include defines a local function!  */
++#  include <locale/weightwc.h>
++
++			    if(delim == '=')
++			      {
++				/* We push the index for equivalence class.  */
++				cp = (wint_t*)str;
++
++				table = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_TABLEWC);
++				weights = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_WEIGHTWC);
++				extra = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_EXTRAWC);
++				indirect = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_INDIRECTWC);
++
++				idx = findidx ((const wint_t**)&cp, c1);
++				if (idx == 0 || cp < (wint_t*) str + c1)
++				  /* This is no valid character.  */
++				  FREE_STACK_RETURN (REG_ECOLLATE);
++
++				str[0] = (wchar_t)idx;
++			      }
++			    else /* delim == '.' */
++			      {
++				/* We push collation sequence value
++				   for collating symbol.  */
++				int32_t table_size;
++				const int32_t *symb_table;
++				const unsigned char *extra;
++				int32_t idx;
++				int32_t elem;
++				int32_t second;
++				int32_t hash;
++				char char_str[c1];
++
++				/* We have to convert the name to a single-byte
++				   string.  This is possible since the names
++				   consist of ASCII characters and the internal
++				   representation is UCS4.  */
++				for (i = 0; i < c1; ++i)
++				  char_str[i] = str[i];
++
++				table_size =
++				  _NL_CURRENT_WORD (LC_COLLATE,
++						    _NL_COLLATE_SYMB_HASH_SIZEMB);
++				symb_table = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_SYMB_TABLEMB);
++				extra = (const unsigned char *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_SYMB_EXTRAMB);
++
++				/* Locate the character in the hashing table.  */
++				hash = elem_hash (char_str, c1);
++
++				idx = 0;
++				elem = hash % table_size;
++				second = hash % (table_size - 2);
++				while (symb_table[2 * elem] != 0)
++				  {
++				    /* First compare the hashing value.  */
++				    if (symb_table[2 * elem] == hash
++					&& c1 == extra[symb_table[2 * elem + 1]]
++					&& memcmp (char_str,
++						   &extra[symb_table[2 * elem + 1]
++							 + 1], c1) == 0)
++				      {
++					/* Yep, this is the entry.  */
++					idx = symb_table[2 * elem + 1];
++					idx += 1 + extra[idx];
++					break;
++				      }
++
++				    /* Next entry.  */
++				    elem += second;
++				  }
++
++				if (symb_table[2 * elem] != 0)
++				  {
++				    /* Compute the index of the byte sequence
++				       in the table.  */
++				    idx += 1 + extra[idx];
++				    /* Adjust for the alignment.  */
++				    idx = (idx + 3) & ~3;
++
++				    str[0] = (wchar_t) idx + 4;
++				  }
++				else if (symb_table[2 * elem] == 0 && c1 == 1)
++				  {
++				    /* No valid character.  Match it as a
++				       single byte character.  */
++				    had_char_class = false;
++				    BUF_PUSH(str[0]);
++				    /* Update the length of characters  */
++				    laststart[5]++;
++				    range_start = str[0];
++
++				    /* Throw away the ] at the end of the
++				       collating symbol.  */
++				    PATFETCH (c);
++				    /* exit from the switch block.  */
++				    continue;
++				  }
++				else
++				  FREE_STACK_RETURN (REG_ECOLLATE);
++			      }
++			    datasize = 1;
++			  }
++# endif
++                        /* Throw away the ] at the end of the equivalence
++                           class (or collating symbol).  */
++                        PATFETCH (c);
++
++			/* Allocate the space for the equivalence class
++			   (or collating symbol) (and '\0' if needed).  */
++                        GET_BUFFER_SPACE(datasize);
++			/* Update the pointer to indicate end of buffer.  */
++                        b += datasize;
++
++			if (delim == '=')
++			  { /* equivalence class  */
++			    /* Calculate the offset of char_ranges,
++			       which is next to equivalence_classes.  */
++			    offset = laststart[1] + laststart[2]
++			      + laststart[3] +6;
++			    /* Insert space.  */
++			    insert_space(datasize, laststart + offset, b - 1);
++
++			    /* Write the equivalence_class and \0.  */
++			    for (i = 0 ; i < datasize ; i++)
++			      laststart[offset + i] = str[i];
++
++			    /* Update the length of equivalence_classes.  */
++			    laststart[3] += datasize;
++			    had_char_class = true;
++			  }
++			else /* delim == '.' */
++			  { /* collating symbol  */
++			    /* Calculate the offset of the equivalence_classes,
++			       which is next to collating_symbols.  */
++			    offset = laststart[1] + laststart[2] + 6;
++			    /* Insert space and write the collationg_symbol
++			       and \0.  */
++			    insert_space(datasize, laststart + offset, b-1);
++			    for (i = 0 ; i < datasize ; i++)
++			      laststart[offset + i] = str[i];
++
++			    /* In re_match_2_internal if range_start < -1, we
++			       assume -range_start is the offset of the
++			       collating symbol which is specified as
++			       the character of the range start.  So we assign
++			       -(laststart[1] + laststart[2] + 6) to
++			       range_start.  */
++			    range_start = -(laststart[1] + laststart[2] + 6);
++			    /* Update the length of collating_symbol.  */
++			    laststart[2] += datasize;
++			    had_char_class = false;
++			  }
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        BUF_PUSH ('[');
++                        BUF_PUSH (delim);
++                        laststart[5] += 2; /* Update the length of characters  */
++			range_start = delim;
++                        had_char_class = false;
++                      }
++		  }
++                else
++                  {
++                    had_char_class = false;
++		    BUF_PUSH(c);
++		    laststart[5]++;  /* Update the length of characters  */
++		    range_start = c;
++                  }
++	      }
++
++#else /* BYTE */
++            /* Ensure that we have enough space to push a charset: the
++               opcode, the length count, and the bitset; 34 bytes in all.  */
++	    GET_BUFFER_SPACE (34);
++
++            laststart = b;
++
++            /* We test `*p == '^' twice, instead of using an if
++               statement, so we only need one BUF_PUSH.  */
++            BUF_PUSH (*p == '^' ? charset_not : charset);
++            if (*p == '^')
++              p++;
++
++            /* Remember the first position in the bracket expression.  */
++            p1 = p;
++
++            /* Push the number of bytes in the bitmap.  */
++            BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
++
++            /* Clear the whole map.  */
++            bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
++
++            /* charset_not matches newline according to a syntax bit.  */
++            if ((re_opcode_t) b[-2] == charset_not
++                && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
++              SET_LIST_BIT ('\n');
++
++            /* Read in characters and ranges, setting map bits.  */
++            for (;;)
++              {
++                if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                PATFETCH (c);
++
++                /* \ might escape characters inside [...] and [^...].  */
++                if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++                    SET_LIST_BIT (c1);
++		    range_start = c1;
++                    continue;
++                  }
++
++                /* Could be the end of the bracket expression.  If it's
++                   not (i.e., when the bracket expression is `[]' so
++                   far), the ']' character bit gets set way below.  */
++                if (c == ']' && p != p1 + 1)
++                  break;
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character class.  */
++                if (had_char_class && c == '-' && *p != ']')
++                  FREE_STACK_RETURN (REG_ERANGE);
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character: if this is a hyphen not at the
++                   beginning or the end of a list, then it's the range
++                   operator.  */
++                if (c == '-'
++                    && !(p - 2 >= pattern && p[-2] == '[')
++                    && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
++                    && *p != ']')
++                  {
++                    reg_errcode_t ret
++                      = byte_compile_range (range_start, &p, pend, translate,
++					    syntax, b);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                else if (p[0] == '-' && p[1] != ']')
++                  { /* This handles ranges made up of characters only.  */
++                    reg_errcode_t ret;
++
++		    /* Move past the `-'.  */
++                    PATFETCH (c1);
++
++                    ret = byte_compile_range (c, &p, pend, translate, syntax, b);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                /* See if we're at the beginning of a possible character
++                   class.  */
++
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
++                  { /* Leave room for the null.  */
++                    char str[CHAR_CLASS_MAX_LENGTH + 1];
++
++                    PATFETCH (c);
++                    c1 = 0;
++
++                    /* If pattern is `[[:'.  */
++                    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                    for (;;)
++                      {
++                        PATFETCH (c);
++                        if ((c == ':' && *p == ']') || p == pend)
++                          break;
++			if (((int) c1) < CHAR_CLASS_MAX_LENGTH)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++                    str[c1] = '\0';
++
++                    /* If isn't a word bracketed by `[:' and `:]':
++                       undo the ending character, the letters, and leave
++                       the leading `:' and `[' (but set bits for them).  */
++                    if (c == ':' && *p == ']')
++                      {
++# if WIDE_CHAR_SUPPORT
++                        boolean is_lower = STREQ (str, "lower");
++                        boolean is_upper = STREQ (str, "upper");
++			wctype_t wt;
++                        int ch;
++
++			wt = IS_CHAR_CLASS (str);
++			if (wt == 0)
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                        for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
++			  {
++#  ifdef _LIBC
++			    if (__iswctype (__btowc (ch), wt))
++			      SET_LIST_BIT (ch);
++#  else
++			    if (iswctype (btowc (ch), wt))
++			      SET_LIST_BIT (ch);
++#  endif
++
++			    if (translate && (is_upper || is_lower)
++				&& (ISUPPER (ch) || ISLOWER (ch)))
++			      SET_LIST_BIT (ch);
++			  }
++
++                        had_char_class = true;
++# else
++                        int ch;
++                        boolean is_alnum = STREQ (str, "alnum");
++                        boolean is_alpha = STREQ (str, "alpha");
++                        boolean is_blank = STREQ (str, "blank");
++                        boolean is_cntrl = STREQ (str, "cntrl");
++                        boolean is_digit = STREQ (str, "digit");
++                        boolean is_graph = STREQ (str, "graph");
++                        boolean is_lower = STREQ (str, "lower");
++                        boolean is_print = STREQ (str, "print");
++                        boolean is_punct = STREQ (str, "punct");
++                        boolean is_space = STREQ (str, "space");
++                        boolean is_upper = STREQ (str, "upper");
++                        boolean is_xdigit = STREQ (str, "xdigit");
++
++                        if (!IS_CHAR_CLASS (str))
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                        for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
++                          {
++			    /* This was split into 3 if's to
++			       avoid an arbitrary limit in some compiler.  */
++                            if (   (is_alnum  && ISALNUM (ch))
++                                || (is_alpha  && ISALPHA (ch))
++                                || (is_blank  && ISBLANK (ch))
++                                || (is_cntrl  && ISCNTRL (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   (is_digit  && ISDIGIT (ch))
++                                || (is_graph  && ISGRAPH (ch))
++                                || (is_lower  && ISLOWER (ch))
++                                || (is_print  && ISPRINT (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   (is_punct  && ISPUNCT (ch))
++                                || (is_space  && ISSPACE (ch))
++                                || (is_upper  && ISUPPER (ch))
++                                || (is_xdigit && ISXDIGIT (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   translate && (is_upper || is_lower)
++				&& (ISUPPER (ch) || ISLOWER (ch)))
++			      SET_LIST_BIT (ch);
++                          }
++                        had_char_class = true;
++# endif	/* libc || wctype.h */
++                      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT (':');
++			range_start = ':';
++                        had_char_class = false;
++                      }
++                  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '=')
++		  {
++		    unsigned char str[MB_LEN_MAX + 1];
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[='.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == '=' && *p == ']') || p == pend)
++			  break;
++			if (c1 < MB_LEN_MAX)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == '=' && *p == ']' && str[0] != '\0')
++		      {
++			/* If we have no collation data we use the default
++			   collation in which each character is in a class
++			   by itself.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++# ifdef _LIBC
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Set the bit for the character.  */
++			    SET_LIST_BIT (str[0]);
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    /* Try to match the byte sequence in `str' against
++			       those known to the collate implementation.
++			       First find out whether the bytes in `str' are
++			       actually from exactly one character.  */
++			    const int32_t *table;
++			    const unsigned char *weights;
++			    const unsigned char *extra;
++			    const int32_t *indirect;
++			    int32_t idx;
++			    const unsigned char *cp = str;
++			    int ch;
++
++			    /* This #include defines a local function!  */
++#  include <locale/weight.h>
++
++			    table = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
++			    weights = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
++			    extra = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
++			    indirect = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
++
++			    idx = findidx (&cp, c1);
++			    if (idx == 0 || cp < str + c1)
++			      /* This is no valid character.  */
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Now we have to go throught the whole table
++			       and find all characters which have the same
++			       first level weight.
++
++			       XXX Note that this is not entirely correct.
++			       we would have to match multibyte sequences
++			       but this is not possible with the current
++			       implementation.  */
++			    for (ch = 1; ch < 256; ++ch)
++			      /* XXX This test would have to be changed if we
++				 would allow matching multibyte sequences.  */
++			      if (table[ch] > 0)
++				{
++				  int32_t idx2 = table[ch];
++				  size_t len = weights[idx2];
++
++				  /* Test whether the lenghts match.  */
++				  if (weights[idx] == len)
++				    {
++				      /* They do.  New compare the bytes of
++					 the weight.  */
++				      size_t cnt = 0;
++
++				      while (cnt < len
++					     && (weights[idx + 1 + cnt]
++						 == weights[idx2 + 1 + cnt]))
++					++cnt;
++
++				      if (cnt == len)
++					/* They match.  Mark the character as
++					   acceptable.  */
++					SET_LIST_BIT (ch);
++				    }
++				}
++			  }
++# endif
++			had_char_class = true;
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT ('=');
++			range_start = '=';
++                        had_char_class = false;
++                      }
++		  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '.')
++		  {
++		    unsigned char str[128];	/* Should be large enough.  */
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[.'.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == '.' && *p == ']') || p == pend)
++			  break;
++			if (c1 < sizeof (str))
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == '.' && *p == ']' && str[0] != '\0')
++		      {
++			/* If we have no collation data we use the default
++			   collation in which each character is the name
++			   for its own class which contains only the one
++			   character.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++# ifdef _LIBC
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Set the bit for the character.  */
++			    SET_LIST_BIT (str[0]);
++			    range_start = ((const unsigned char *) str)[0];
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    /* Try to match the byte sequence in `str' against
++			       those known to the collate implementation.
++			       First find out whether the bytes in `str' are
++			       actually from exactly one character.  */
++			    int32_t table_size;
++			    const int32_t *symb_table;
++			    const unsigned char *extra;
++			    int32_t idx;
++			    int32_t elem;
++			    int32_t second;
++			    int32_t hash;
++
++			    table_size =
++			      _NL_CURRENT_WORD (LC_COLLATE,
++						_NL_COLLATE_SYMB_HASH_SIZEMB);
++			    symb_table = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE,
++					   _NL_COLLATE_SYMB_TABLEMB);
++			    extra = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE,
++					   _NL_COLLATE_SYMB_EXTRAMB);
++
++			    /* Locate the character in the hashing table.  */
++			    hash = elem_hash ((const char *) str, c1);
++
++			    idx = 0;
++			    elem = hash % table_size;
++			    second = hash % (table_size - 2);
++			    while (symb_table[2 * elem] != 0)
++			      {
++				/* First compare the hashing value.  */
++				if (symb_table[2 * elem] == hash
++				    && c1 == extra[symb_table[2 * elem + 1]]
++				    && memcmp (str,
++					       &extra[symb_table[2 * elem + 1]
++						     + 1],
++					       c1) == 0)
++				  {
++				    /* Yep, this is the entry.  */
++				    idx = symb_table[2 * elem + 1];
++				    idx += 1 + extra[idx];
++				    break;
++				  }
++
++				/* Next entry.  */
++				elem += second;
++			      }
++
++			    if (symb_table[2 * elem] == 0)
++			      /* This is no valid character.  */
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Now add the multibyte character(s) we found
++			       to the accept list.
++
++			       XXX Note that this is not entirely correct.
++			       we would have to match multibyte sequences
++			       but this is not possible with the current
++			       implementation.  Also, we have to match
++			       collating symbols, which expand to more than
++			       one file, as a whole and not allow the
++			       individual bytes.  */
++			    c1 = extra[idx++];
++			    if (c1 == 1)
++			      range_start = extra[idx];
++			    while (c1-- > 0)
++			      {
++				SET_LIST_BIT (extra[idx]);
++				++idx;
++			      }
++			  }
++# endif
++			had_char_class = false;
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT ('.');
++			range_start = '.';
++                        had_char_class = false;
++                      }
++		  }
++                else
++                  {
++                    had_char_class = false;
++                    SET_LIST_BIT (c);
++		    range_start = c;
++                  }
++              }
++
++            /* Discard any (non)matching list bytes that are all 0 at the
++               end of the map.  Decrease the map-length byte too.  */
++            while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
++              b[-1]--;
++            b += b[-1];
++#endif /* WCHAR */
++          }
++          break;
++
++
++	case '(':
++          if (syntax & RE_NO_BK_PARENS)
++            goto handle_open;
++          else
++            goto normal_char;
++
++
++        case ')':
++          if (syntax & RE_NO_BK_PARENS)
++            goto handle_close;
++          else
++            goto normal_char;
++
++
++        case '\n':
++          if (syntax & RE_NEWLINE_ALT)
++            goto handle_alt;
++          else
++            goto normal_char;
++
++
++	case '|':
++          if (syntax & RE_NO_BK_VBAR)
++            goto handle_alt;
++          else
++            goto normal_char;
++
++
++        case '{':
++           if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
++             goto handle_interval;
++           else
++             goto normal_char;
++
++
++        case '\\':
++          if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++          /* Do not translate the character after the \, so that we can
++             distinguish, e.g., \B from \b, even if we normally would
++             translate, e.g., B to b.  */
++          PATFETCH_RAW (c);
++
++          switch (c)
++            {
++            case '(':
++              if (syntax & RE_NO_BK_PARENS)
++                goto normal_backslash;
++
++            handle_open:
++              bufp->re_nsub++;
++              regnum++;
++
++              if (COMPILE_STACK_FULL)
++                {
++                  RETALLOC (compile_stack.stack, compile_stack.size << 1,
++                            compile_stack_elt_t);
++                  if (compile_stack.stack == NULL) return REG_ESPACE;
++
++                  compile_stack.size <<= 1;
++                }
++
++              /* These are the values to restore when we hit end of this
++                 group.  They are all relative offsets, so that if the
++                 whole pattern moves because of realloc, they will still
++                 be valid.  */
++              COMPILE_STACK_TOP.begalt_offset = begalt - COMPILED_BUFFER_VAR;
++              COMPILE_STACK_TOP.fixup_alt_jump
++                = fixup_alt_jump ? fixup_alt_jump - COMPILED_BUFFER_VAR + 1 : 0;
++              COMPILE_STACK_TOP.laststart_offset = b - COMPILED_BUFFER_VAR;
++              COMPILE_STACK_TOP.regnum = regnum;
++
++              /* We will eventually replace the 0 with the number of
++                 groups inner to this one.  But do not push a
++                 start_memory for groups beyond the last one we can
++                 represent in the compiled pattern.  */
++              if (regnum <= MAX_REGNUM)
++                {
++                  COMPILE_STACK_TOP.inner_group_offset = b
++		    - COMPILED_BUFFER_VAR + 2;
++                  BUF_PUSH_3 (start_memory, regnum, 0);
++                }
++
++              compile_stack.avail++;
++
++              fixup_alt_jump = 0;
++              laststart = 0;
++              begalt = b;
++	      /* If we've reached MAX_REGNUM groups, then this open
++		 won't actually generate any code, so we'll have to
++		 clear pending_exact explicitly.  */
++	      pending_exact = 0;
++              break;
++
++
++            case ')':
++              if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
++
++              if (COMPILE_STACK_EMPTY)
++		{
++		  if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
++		    goto normal_backslash;
++		  else
++		    FREE_STACK_RETURN (REG_ERPAREN);
++		}
++
++            handle_close:
++              if (fixup_alt_jump)
++                { /* Push a dummy failure point at the end of the
++                     alternative for a possible future
++                     `pop_failure_jump' to pop.  See comments at
++                     `push_dummy_failure' in `re_match_2'.  */
++                  BUF_PUSH (push_dummy_failure);
++
++                  /* We allocated space for this jump when we assigned
++                     to `fixup_alt_jump', in the `handle_alt' case below.  */
++                  STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
++                }
++
++              /* See similar code for backslashed left paren above.  */
++              if (COMPILE_STACK_EMPTY)
++		{
++		  if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
++		    goto normal_char;
++		  else
++		    FREE_STACK_RETURN (REG_ERPAREN);
++		}
++
++              /* Since we just checked for an empty stack above, this
++                 ``can't happen''.  */
++              assert (compile_stack.avail != 0);
++              {
++                /* We don't just want to restore into `regnum', because
++                   later groups should continue to be numbered higher,
++                   as in `(ab)c(de)' -- the second group is #2.  */
++                regnum_t this_group_regnum;
++
++                compile_stack.avail--;
++                begalt = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.begalt_offset;
++                fixup_alt_jump
++                  = COMPILE_STACK_TOP.fixup_alt_jump
++                    ? COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.fixup_alt_jump - 1
++                    : 0;
++                laststart = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.laststart_offset;
++                this_group_regnum = COMPILE_STACK_TOP.regnum;
++		/* If we've reached MAX_REGNUM groups, then this open
++		   won't actually generate any code, so we'll have to
++		   clear pending_exact explicitly.  */
++		pending_exact = 0;
++
++                /* We're at the end of the group, so now we know how many
++                   groups were inside this one.  */
++                if (this_group_regnum <= MAX_REGNUM)
++                  {
++		    UCHAR_T *inner_group_loc
++                      = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.inner_group_offset;
++
++                    *inner_group_loc = regnum - this_group_regnum;
++                    BUF_PUSH_3 (stop_memory, this_group_regnum,
++                                regnum - this_group_regnum);
++                  }
++              }
++              break;
++
++
++            case '|':					/* `\|'.  */
++              if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
++                goto normal_backslash;
++            handle_alt:
++              if (syntax & RE_LIMITED_OPS)
++                goto normal_char;
++
++              /* Insert before the previous alternative a jump which
++                 jumps to this alternative if the former fails.  */
++              GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++              INSERT_JUMP (on_failure_jump, begalt,
++			   b + 2 + 2 * OFFSET_ADDRESS_SIZE);
++              pending_exact = 0;
++              b += 1 + OFFSET_ADDRESS_SIZE;
++
++              /* The alternative before this one has a jump after it
++                 which gets executed if it gets matched.  Adjust that
++                 jump so it will jump to this alternative's analogous
++                 jump (put in below, which in turn will jump to the next
++                 (if any) alternative's such jump, etc.).  The last such
++                 jump jumps to the correct final destination.  A picture:
++                          _____ _____
++                          |   | |   |
++                          |   v |   v
++                         a | b   | c
++
++                 If we are at `b', then fixup_alt_jump right now points to a
++                 three-byte space after `a'.  We'll put in the jump, set
++                 fixup_alt_jump to right after `b', and leave behind three
++                 bytes which we'll fill in when we get to after `c'.  */
++
++              if (fixup_alt_jump)
++                STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
++
++              /* Mark and leave space for a jump after this alternative,
++                 to be filled in later either by next alternative or
++                 when know we're at the end of a series of alternatives.  */
++              fixup_alt_jump = b;
++              GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++              b += 1 + OFFSET_ADDRESS_SIZE;
++
++              laststart = 0;
++              begalt = b;
++              break;
++
++
++            case '{':
++              /* If \{ is a literal.  */
++              if (!(syntax & RE_INTERVALS)
++                     /* If we're at `\{' and it's not the open-interval
++                        operator.  */
++		  || (syntax & RE_NO_BK_BRACES))
++                goto normal_backslash;
++
++            handle_interval:
++              {
++                /* If got here, then the syntax allows intervals.  */
++
++                /* At least (most) this many matches must be made.  */
++                int lower_bound = -1, upper_bound = -1;
++
++		/* Place in the uncompiled pattern (i.e., just after
++		   the '{') to go back to if the interval is invalid.  */
++		const CHAR_T *beg_interval = p;
++
++                if (p == pend)
++		  goto invalid_interval;
++
++                GET_UNSIGNED_NUMBER (lower_bound);
++
++                if (c == ',')
++                  {
++                    GET_UNSIGNED_NUMBER (upper_bound);
++		    if (upper_bound < 0)
++		      upper_bound = RE_DUP_MAX;
++                  }
++                else
++                  /* Interval such as `{1}' => match exactly once. */
++                  upper_bound = lower_bound;
++
++                if (! (0 <= lower_bound && lower_bound <= upper_bound))
++		  goto invalid_interval;
++
++                if (!(syntax & RE_NO_BK_BRACES))
++                  {
++		    if (c != '\\' || p == pend)
++		      goto invalid_interval;
++                    PATFETCH (c);
++                  }
++
++                if (c != '}')
++		  goto invalid_interval;
++
++                /* If it's invalid to have no preceding re.  */
++                if (!laststart)
++                  {
++		    if (syntax & RE_CONTEXT_INVALID_OPS
++			&& !(syntax & RE_INVALID_INTERVAL_ORD))
++                      FREE_STACK_RETURN (REG_BADRPT);
++                    else if (syntax & RE_CONTEXT_INDEP_OPS)
++                      laststart = b;
++                    else
++                      goto unfetch_interval;
++                  }
++
++                /* We just parsed a valid interval.  */
++
++                if (RE_DUP_MAX < upper_bound)
++		  FREE_STACK_RETURN (REG_BADBR);
++
++                /* If the upper bound is zero, don't want to succeed at
++                   all; jump from `laststart' to `b + 3', which will be
++		   the end of the buffer after we insert the jump.  */
++		/* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE'
++		   instead of 'b + 3'.  */
++                 if (upper_bound == 0)
++                   {
++                     GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++                     INSERT_JUMP (jump, laststart, b + 1
++				  + OFFSET_ADDRESS_SIZE);
++                     b += 1 + OFFSET_ADDRESS_SIZE;
++                   }
++
++                 /* Otherwise, we have a nontrivial interval.  When
++                    we're all done, the pattern will look like:
++                      set_number_at <jump count> <upper bound>
++                      set_number_at <succeed_n count> <lower bound>
++                      succeed_n <after jump addr> <succeed_n count>
++                      <body of loop>
++                      jump_n <succeed_n addr> <jump count>
++                    (The upper bound and `jump_n' are omitted if
++                    `upper_bound' is 1, though.)  */
++                 else
++                   { /* If the upper bound is > 1, we need to insert
++                        more at the end of the loop.  */
++                     unsigned nbytes = 2 + 4 * OFFSET_ADDRESS_SIZE +
++		       (upper_bound > 1) * (2 + 4 * OFFSET_ADDRESS_SIZE);
++
++                     GET_BUFFER_SPACE (nbytes);
++
++                     /* Initialize lower bound of the `succeed_n', even
++                        though it will be set during matching by its
++                        attendant `set_number_at' (inserted next),
++                        because `re_compile_fastmap' needs to know.
++                        Jump to the `jump_n' we might insert below.  */
++                     INSERT_JUMP2 (succeed_n, laststart,
++                                   b + 1 + 2 * OFFSET_ADDRESS_SIZE
++				   + (upper_bound > 1) * (1 + 2 * OFFSET_ADDRESS_SIZE)
++				   , lower_bound);
++                     b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                     /* Code to initialize the lower bound.  Insert
++                        before the `succeed_n'.  The `5' is the last two
++                        bytes of this `set_number_at', plus 3 bytes of
++                        the following `succeed_n'.  */
++		     /* ifdef WCHAR, The '1+2*OFFSET_ADDRESS_SIZE'
++			is the 'set_number_at', plus '1+OFFSET_ADDRESS_SIZE'
++			of the following `succeed_n'.  */
++                     PREFIX(insert_op2) (set_number_at, laststart, 1
++				 + 2 * OFFSET_ADDRESS_SIZE, lower_bound, b);
++                     b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                     if (upper_bound > 1)
++                       { /* More than one repetition is allowed, so
++                            append a backward jump to the `succeed_n'
++                            that starts this interval.
++
++                            When we've reached this during matching,
++                            we'll have matched the interval once, so
++                            jump back only `upper_bound - 1' times.  */
++                         STORE_JUMP2 (jump_n, b, laststart
++				      + 2 * OFFSET_ADDRESS_SIZE + 1,
++                                      upper_bound - 1);
++                         b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                         /* The location we want to set is the second
++                            parameter of the `jump_n'; that is `b-2' as
++                            an absolute address.  `laststart' will be
++                            the `set_number_at' we're about to insert;
++                            `laststart+3' the number to set, the source
++                            for the relative address.  But we are
++                            inserting into the middle of the pattern --
++                            so everything is getting moved up by 5.
++                            Conclusion: (b - 2) - (laststart + 3) + 5,
++                            i.e., b - laststart.
++
++                            We insert this at the beginning of the loop
++                            so that if we fail during matching, we'll
++                            reinitialize the bounds.  */
++                         PREFIX(insert_op2) (set_number_at, laststart,
++					     b - laststart,
++					     upper_bound - 1, b);
++                         b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++                       }
++                   }
++                pending_exact = 0;
++		break;
++
++	      invalid_interval:
++		if (!(syntax & RE_INVALID_INTERVAL_ORD))
++		  FREE_STACK_RETURN (p == pend ? REG_EBRACE : REG_BADBR);
++	      unfetch_interval:
++		/* Match the characters as literals.  */
++		p = beg_interval;
++		c = '{';
++		if (syntax & RE_NO_BK_BRACES)
++		  goto normal_char;
++		else
++		  goto normal_backslash;
++	      }
++
++#ifdef emacs
++            /* There is no way to specify the before_dot and after_dot
++               operators.  rms says this is ok.  --karl  */
++            case '=':
++              BUF_PUSH (at_dot);
++              break;
++
++            case 's':
++              laststart = b;
++              PATFETCH (c);
++              BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
++              break;
++
++            case 'S':
++              laststart = b;
++              PATFETCH (c);
++              BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
++              break;
++#endif /* emacs */
++
++
++            case 'w':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              laststart = b;
++              BUF_PUSH (wordchar);
++              break;
++
++
++            case 'W':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              laststart = b;
++              BUF_PUSH (notwordchar);
++              break;
++
++
++            case '<':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordbeg);
++              break;
++
++            case '>':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordend);
++              break;
++
++            case 'b':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordbound);
++              break;
++
++            case 'B':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (notwordbound);
++              break;
++
++            case '`':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (begbuf);
++              break;
++
++            case '\'':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (endbuf);
++              break;
++
++            case '1': case '2': case '3': case '4': case '5':
++            case '6': case '7': case '8': case '9':
++              if (syntax & RE_NO_BK_REFS)
++                goto normal_char;
++
++              c1 = c - '0';
++
++              if (c1 > regnum)
++                FREE_STACK_RETURN (REG_ESUBREG);
++
++              /* Can't back reference to a subexpression if inside of it.  */
++              if (group_in_compile_stack (compile_stack, (regnum_t) c1))
++                goto normal_char;
++
++              laststart = b;
++              BUF_PUSH_2 (duplicate, c1);
++              break;
++
++
++            case '+':
++            case '?':
++              if (syntax & RE_BK_PLUS_QM)
++                goto handle_plus;
++              else
++                goto normal_backslash;
++
++            default:
++            normal_backslash:
++              /* You might think it would be useful for \ to mean
++                 not to translate; but if we don't translate it
++                 it will never match anything.  */
++              c = TRANSLATE (c);
++              goto normal_char;
++            }
++          break;
++
++
++	default:
++        /* Expects the character in `c'.  */
++	normal_char:
++	      /* If no exactn currently being built.  */
++          if (!pending_exact
++#ifdef WCHAR
++	      /* If last exactn handle binary(or character) and
++		 new exactn handle character(or binary).  */
++	      || is_exactn_bin != is_binary[p - 1 - pattern]
++#endif /* WCHAR */
++
++              /* If last exactn not at current position.  */
++              || pending_exact + *pending_exact + 1 != b
++
++              /* We have only one byte following the exactn for the count.  */
++	      || *pending_exact == (1 << BYTEWIDTH) - 1
++
++              /* If followed by a repetition operator.  */
++              || *p == '*' || *p == '^'
++	      || ((syntax & RE_BK_PLUS_QM)
++		  ? *p == '\\' && (p[1] == '+' || p[1] == '?')
++		  : (*p == '+' || *p == '?'))
++	      || ((syntax & RE_INTERVALS)
++                  && ((syntax & RE_NO_BK_BRACES)
++		      ? *p == '{'
++                      : (p[0] == '\\' && p[1] == '{'))))
++	    {
++	      /* Start building a new exactn.  */
++
++              laststart = b;
++
++#ifdef WCHAR
++	      /* Is this exactn binary data or character? */
++	      is_exactn_bin = is_binary[p - 1 - pattern];
++	      if (is_exactn_bin)
++		  BUF_PUSH_2 (exactn_bin, 0);
++	      else
++		  BUF_PUSH_2 (exactn, 0);
++#else
++	      BUF_PUSH_2 (exactn, 0);
++#endif /* WCHAR */
++	      pending_exact = b - 1;
++            }
++
++	  BUF_PUSH (c);
++          (*pending_exact)++;
++	  break;
++        } /* switch (c) */
++    } /* while p != pend */
++
++
++  /* Through the pattern now.  */
++
++  if (fixup_alt_jump)
++    STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
++
++  if (!COMPILE_STACK_EMPTY)
++    FREE_STACK_RETURN (REG_EPAREN);
++
++  /* If we don't want backtracking, force success
++     the first time we reach the end of the compiled pattern.  */
++  if (syntax & RE_NO_POSIX_BACKTRACKING)
++    BUF_PUSH (succeed);
++
++#ifdef WCHAR
++  free (pattern);
++  free (mbs_offset);
++  free (is_binary);
++#endif
++  free (compile_stack.stack);
++
++  /* We have succeeded; set the length of the buffer.  */
++#ifdef WCHAR
++  bufp->used = (uintptr_t) b - (uintptr_t) COMPILED_BUFFER_VAR;
++#else
++  bufp->used = b - bufp->buffer;
++#endif
++
++#ifdef DEBUG
++  if (debug)
++    {
++      DEBUG_PRINT1 ("\nCompiled pattern: \n");
++      PREFIX(print_compiled_pattern) (bufp);
++    }
++#endif /* DEBUG */
++
++#ifndef MATCH_MAY_ALLOCATE
++  /* Initialize the failure stack to the largest possible stack.  This
++     isn't necessary unless we're trying to avoid calling alloca in
++     the search and match routines.  */
++  {
++    int num_regs = bufp->re_nsub + 1;
++
++    /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
++       is strictly greater than re_max_failures, the largest possible stack
++       is 2 * re_max_failures failure points.  */
++    if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
++      {
++	fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
++
++# ifdef emacs
++	if (! fail_stack.stack)
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) xmalloc (fail_stack.size
++				    * sizeof (PREFIX(fail_stack_elt_t)));
++	else
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) xrealloc (fail_stack.stack,
++				     (fail_stack.size
++				      * sizeof (PREFIX(fail_stack_elt_t))));
++# else /* not emacs */
++	if (! fail_stack.stack)
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) malloc (fail_stack.size
++				   * sizeof (PREFIX(fail_stack_elt_t)));
++	else
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) realloc (fail_stack.stack,
++					    (fail_stack.size
++				     * sizeof (PREFIX(fail_stack_elt_t))));
++# endif /* not emacs */
++      }
++
++   PREFIX(regex_grow_registers) (num_regs);
++  }
++#endif /* not MATCH_MAY_ALLOCATE */
++
++  return REG_NOERROR;
++} /* regex_compile */
++
++/* Subroutines for `regex_compile'.  */
++
++/* Store OP at LOC followed by two-byte integer parameter ARG.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg)
++{
++  *loc = (UCHAR_T) op;
++  STORE_NUMBER (loc + 1, arg);
++}
++
++
++/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2)
++{
++  *loc = (UCHAR_T) op;
++  STORE_NUMBER (loc + 1, arg1);
++  STORE_NUMBER (loc + 1 + OFFSET_ADDRESS_SIZE, arg2);
++}
++
++
++/* Copy the bytes from LOC to END to open up three bytes of space at LOC
++   for OP followed by two-byte integer parameter ARG.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end)
++{
++  register UCHAR_T *pfrom = end;
++  register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE;
++
++  while (pfrom != loc)
++    *--pto = *--pfrom;
++
++  PREFIX(store_op1) (op, loc, arg);
++}
++
++
++/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1,
++                    int arg2, UCHAR_T *end)
++{
++  register UCHAR_T *pfrom = end;
++  register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++  while (pfrom != loc)
++    *--pto = *--pfrom;
++
++  PREFIX(store_op2) (op, loc, arg1, arg2);
++}
++
++
++/* P points to just after a ^ in PATTERN.  Return true if that ^ comes
++   after an alternative or a begin-subexpression.  We assume there is at
++   least one character before the ^.  */
++
++static boolean
++PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p,
++                          reg_syntax_t syntax)
++{
++  const CHAR_T *prev = p - 2;
++  boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
++
++  return
++       /* After a subexpression?  */
++       (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
++       /* After an alternative?  */
++    || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
++}
++
++
++/* The dual of at_begline_loc_p.  This one is for $.  We assume there is
++   at least one character after the $, i.e., `P < PEND'.  */
++
++static boolean
++PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend,
++                          reg_syntax_t syntax)
++{
++  const CHAR_T *next = p;
++  boolean next_backslash = *next == '\\';
++  const CHAR_T *next_next = p + 1 < pend ? p + 1 : 0;
++
++  return
++       /* Before a subexpression?  */
++       (syntax & RE_NO_BK_PARENS ? *next == ')'
++        : next_backslash && next_next && *next_next == ')')
++       /* Before an alternative?  */
++    || (syntax & RE_NO_BK_VBAR ? *next == '|'
++        : next_backslash && next_next && *next_next == '|');
++}
++
++#else /* not INSIDE_RECURSION */
++
++/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
++   false if it's not.  */
++
++static boolean
++group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
++{
++  int this_element;
++
++  for (this_element = compile_stack.avail - 1;
++       this_element >= 0;
++       this_element--)
++    if (compile_stack.stack[this_element].regnum == regnum)
++      return true;
++
++  return false;
++}
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef WCHAR
++/* This insert space, which size is "num", into the pattern at "loc".
++   "end" must point the end of the allocated buffer.  */
++static void
++insert_space (int num, CHAR_T *loc, CHAR_T *end)
++{
++  register CHAR_T *pto = end;
++  register CHAR_T *pfrom = end - num;
++
++  while (pfrom >= loc)
++    *pto-- = *pfrom--;
++}
++#endif /* WCHAR */
++
++#ifdef WCHAR
++static reg_errcode_t
++wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr,
++                   const CHAR_T *pend, RE_TRANSLATE_TYPE translate,
++                   reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set)
++{
++  const CHAR_T *p = *p_ptr;
++  CHAR_T range_start, range_end;
++  reg_errcode_t ret;
++# ifdef _LIBC
++  uint32_t nrules;
++  uint32_t start_val, end_val;
++# endif
++  if (p == pend)
++    return REG_ERANGE;
++
++# ifdef _LIBC
++  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++  if (nrules != 0)
++    {
++      const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE,
++						       _NL_COLLATE_COLLSEQWC);
++      const unsigned char *extra = (const unsigned char *)
++	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
++
++      if (range_start_char < -1)
++	{
++	  /* range_start is a collating symbol.  */
++	  int32_t *wextra;
++	  /* Retreive the index and get collation sequence value.  */
++	  wextra = (int32_t*)(extra + char_set[-range_start_char]);
++	  start_val = wextra[1 + *wextra];
++	}
++      else
++	start_val = collseq_table_lookup(collseq, TRANSLATE(range_start_char));
++
++      end_val = collseq_table_lookup (collseq, TRANSLATE (p[0]));
++
++      /* Report an error if the range is empty and the syntax prohibits
++	 this.  */
++      ret = ((syntax & RE_NO_EMPTY_RANGES)
++	     && (start_val > end_val))? REG_ERANGE : REG_NOERROR;
++
++      /* Insert space to the end of the char_ranges.  */
++      insert_space(2, b - char_set[5] - 2, b - 1);
++      *(b - char_set[5] - 2) = (wchar_t)start_val;
++      *(b - char_set[5] - 1) = (wchar_t)end_val;
++      char_set[4]++; /* ranges_index */
++    }
++  else
++# endif
++    {
++      range_start = (range_start_char >= 0)? TRANSLATE (range_start_char):
++	range_start_char;
++      range_end = TRANSLATE (p[0]);
++      /* Report an error if the range is empty and the syntax prohibits
++	 this.  */
++      ret = ((syntax & RE_NO_EMPTY_RANGES)
++	     && (range_start > range_end))? REG_ERANGE : REG_NOERROR;
++
++      /* Insert space to the end of the char_ranges.  */
++      insert_space(2, b - char_set[5] - 2, b - 1);
++      *(b - char_set[5] - 2) = range_start;
++      *(b - char_set[5] - 1) = range_end;
++      char_set[4]++; /* ranges_index */
++    }
++  /* Have to increment the pointer into the pattern string, so the
++     caller isn't still at the ending character.  */
++  (*p_ptr)++;
++
++  return ret;
++}
++#else /* BYTE */
++/* Read the ending character of a range (in a bracket expression) from the
++   uncompiled pattern *P_PTR (which ends at PEND).  We assume the
++   starting character is in `P[-2]'.  (`P[-1]' is the character `-'.)
++   Then we set the translation of all bits between the starting and
++   ending characters (inclusive) in the compiled pattern B.
++
++   Return an error code.
++
++   We use these short variable names so we can use the same macros as
++   `regex_compile' itself.  */
++
++static reg_errcode_t
++byte_compile_range (unsigned int range_start_char, const char **p_ptr,
++                    const char *pend, RE_TRANSLATE_TYPE translate,
++                    reg_syntax_t syntax, unsigned char *b)
++{
++  unsigned this_char;
++  const char *p = *p_ptr;
++  reg_errcode_t ret;
++# if _LIBC
++  const unsigned char *collseq;
++  unsigned int start_colseq;
++  unsigned int end_colseq;
++# else
++  unsigned end_char;
++# endif
++
++  if (p == pend)
++    return REG_ERANGE;
++
++  /* Have to increment the pointer into the pattern string, so the
++     caller isn't still at the ending character.  */
++  (*p_ptr)++;
++
++  /* Report an error if the range is empty and the syntax prohibits this.  */
++  ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
++
++# if _LIBC
++  collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
++						 _NL_COLLATE_COLLSEQMB);
++
++  start_colseq = collseq[(unsigned char) TRANSLATE (range_start_char)];
++  end_colseq = collseq[(unsigned char) TRANSLATE (p[0])];
++  for (this_char = 0; this_char <= (unsigned char) -1; ++this_char)
++    {
++      unsigned int this_colseq = collseq[(unsigned char) TRANSLATE (this_char)];
++
++      if (start_colseq <= this_colseq && this_colseq <= end_colseq)
++	{
++	  SET_LIST_BIT (TRANSLATE (this_char));
++	  ret = REG_NOERROR;
++	}
++    }
++# else
++  /* Here we see why `this_char' has to be larger than an `unsigned
++     char' -- we would otherwise go into an infinite loop, since all
++     characters <= 0xff.  */
++  range_start_char = TRANSLATE (range_start_char);
++  /* TRANSLATE(p[0]) is casted to char (not unsigned char) in TRANSLATE,
++     and some compilers cast it to int implicitly, so following for_loop
++     may fall to (almost) infinite loop.
++     e.g. If translate[p[0]] = 0xff, end_char may equals to 0xffffffff.
++     To avoid this, we cast p[0] to unsigned int and truncate it.  */
++  end_char = ((unsigned)TRANSLATE(p[0]) & ((1 << BYTEWIDTH) - 1));
++
++  for (this_char = range_start_char; this_char <= end_char; ++this_char)
++    {
++      SET_LIST_BIT (TRANSLATE (this_char));
++      ret = REG_NOERROR;
++    }
++# endif
++
++  return ret;
++}
++#endif /* WCHAR */
++\f
++/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
++   BUFP.  A fastmap records which of the (1 << BYTEWIDTH) possible
++   characters can start a string that matches the pattern.  This fastmap
++   is used by re_search to skip quickly over impossible starting points.
++
++   The caller must supply the address of a (1 << BYTEWIDTH)-byte data
++   area as BUFP->fastmap.
++
++   We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
++   the pattern buffer.
++
++   Returns 0 if we succeed, -2 if an internal error.   */
++
++#ifdef WCHAR
++/* local function for re_compile_fastmap.
++   truncate wchar_t character to char.  */
++static unsigned char truncate_wchar (CHAR_T c);
++
++static unsigned char
++truncate_wchar (CHAR_T c)
++{
++  unsigned char buf[MB_CUR_MAX];
++  mbstate_t state;
++  int retval;
++  memset (&state, '\0', sizeof (state));
++# ifdef _LIBC
++  retval = __wcrtomb (buf, c, &state);
++# else
++  retval = wcrtomb (buf, c, &state);
++# endif
++  return retval > 0 ? buf[0] : (unsigned char) c;
++}
++#endif /* WCHAR */
++
++static int
++PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp)
++{
++  int j, k;
++#ifdef MATCH_MAY_ALLOCATE
++  PREFIX(fail_stack_type) fail_stack;
++#endif
++#ifndef REGEX_MALLOC
++  char *destination;
++#endif
++
++  register char *fastmap = bufp->fastmap;
++
++#ifdef WCHAR
++  /* We need to cast pattern to (wchar_t*), because we casted this compiled
++     pattern to (char*) in regex_compile.  */
++  UCHAR_T *pattern = (UCHAR_T*)bufp->buffer;
++  register UCHAR_T *pend = (UCHAR_T*) (bufp->buffer + bufp->used);
++#else /* BYTE */
++  UCHAR_T *pattern = bufp->buffer;
++  register UCHAR_T *pend = pattern + bufp->used;
++#endif /* WCHAR */
++  UCHAR_T *p = pattern;
++
++#ifdef REL_ALLOC
++  /* This holds the pointer to the failure stack, when
++     it is allocated relocatably.  */
++  fail_stack_elt_t *failure_stack_ptr;
++#endif
++
++  /* Assume that each path through the pattern can be null until
++     proven otherwise.  We set this false at the bottom of switch
++     statement, to which we get only if a particular path doesn't
++     match the empty string.  */
++  boolean path_can_be_null = true;
++
++  /* We aren't doing a `succeed_n' to begin with.  */
++  boolean succeed_n_p = false;
++
++  assert (fastmap != NULL && p != NULL);
++
++  INIT_FAIL_STACK ();
++  bzero (fastmap, 1 << BYTEWIDTH);  /* Assume nothing's valid.  */
++  bufp->fastmap_accurate = 1;	    /* It will be when we're done.  */
++  bufp->can_be_null = 0;
++
++  while (1)
++    {
++      if (p == pend || *p == (UCHAR_T) succeed)
++	{
++	  /* We have reached the (effective) end of pattern.  */
++	  if (!FAIL_STACK_EMPTY ())
++	    {
++	      bufp->can_be_null |= path_can_be_null;
++
++	      /* Reset for next path.  */
++	      path_can_be_null = true;
++
++	      p = fail_stack.stack[--fail_stack.avail].pointer;
++
++	      continue;
++	    }
++	  else
++	    break;
++	}
++
++      /* We should never be about to go beyond the end of the pattern.  */
++      assert (p < pend);
++
++      switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
++	{
++
++        /* I guess the idea here is to simply not bother with a fastmap
++           if a backreference is used, since it's too hard to figure out
++           the fastmap for the corresponding group.  Setting
++           `can_be_null' stops `re_search_2' from using the fastmap, so
++           that is all we do.  */
++	case duplicate:
++	  bufp->can_be_null = 1;
++          goto done;
++
++
++      /* Following are the cases which match a character.  These end
++         with `break'.  */
++
++#ifdef WCHAR
++	case exactn:
++          fastmap[truncate_wchar(p[1])] = 1;
++	  break;
++#else /* BYTE */
++	case exactn:
++          fastmap[p[1]] = 1;
++	  break;
++#endif /* WCHAR */
++#ifdef MBS_SUPPORT
++	case exactn_bin:
++	  fastmap[p[1]] = 1;
++	  break;
++#endif
++
++#ifdef WCHAR
++        /* It is hard to distinguish fastmap from (multi byte) characters
++           which depends on current locale.  */
++        case charset:
++	case charset_not:
++	case wordchar:
++	case notwordchar:
++          bufp->can_be_null = 1;
++          goto done;
++#else /* BYTE */
++        case charset:
++          for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
++	    if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
++              fastmap[j] = 1;
++	  break;
++
++
++	case charset_not:
++	  /* Chars beyond end of map must be allowed.  */
++	  for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
++            fastmap[j] = 1;
++
++	  for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
++	    if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
++              fastmap[j] = 1;
++          break;
++
++
++	case wordchar:
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) == Sword)
++	      fastmap[j] = 1;
++	  break;
++
++
++	case notwordchar:
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) != Sword)
++	      fastmap[j] = 1;
++	  break;
++#endif /* WCHAR */
++
++        case anychar:
++	  {
++	    int fastmap_newline = fastmap['\n'];
++
++	    /* `.' matches anything ...  */
++	    for (j = 0; j < (1 << BYTEWIDTH); j++)
++	      fastmap[j] = 1;
++
++	    /* ... except perhaps newline.  */
++	    if (!(bufp->syntax & RE_DOT_NEWLINE))
++	      fastmap['\n'] = fastmap_newline;
++
++	    /* Return if we have already set `can_be_null'; if we have,
++	       then the fastmap is irrelevant.  Something's wrong here.  */
++	    else if (bufp->can_be_null)
++	      goto done;
++
++	    /* Otherwise, have to check alternative paths.  */
++	    break;
++	  }
++
++#ifdef emacs
++        case syntaxspec:
++	  k = *p++;
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) == (enum syntaxcode) k)
++	      fastmap[j] = 1;
++	  break;
++
++
++	case notsyntaxspec:
++	  k = *p++;
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) != (enum syntaxcode) k)
++	      fastmap[j] = 1;
++	  break;
++
++
++      /* All cases after this match the empty string.  These end with
++         `continue'.  */
++
++
++	case before_dot:
++	case at_dot:
++	case after_dot:
++          continue;
++#endif /* emacs */
++
++
++        case no_op:
++        case begline:
++        case endline:
++	case begbuf:
++	case endbuf:
++	case wordbound:
++	case notwordbound:
++	case wordbeg:
++	case wordend:
++        case push_dummy_failure:
++          continue;
++
++
++	case jump_n:
++        case pop_failure_jump:
++	case maybe_pop_jump:
++	case jump:
++        case jump_past_alt:
++	case dummy_failure_jump:
++          EXTRACT_NUMBER_AND_INCR (j, p);
++	  p += j;
++	  if (j > 0)
++	    continue;
++
++          /* Jump backward implies we just went through the body of a
++             loop and matched nothing.  Opcode jumped to should be
++             `on_failure_jump' or `succeed_n'.  Just treat it like an
++             ordinary jump.  For a * loop, it has pushed its failure
++             point already; if so, discard that as redundant.  */
++          if ((re_opcode_t) *p != on_failure_jump
++	      && (re_opcode_t) *p != succeed_n)
++	    continue;
++
++          p++;
++          EXTRACT_NUMBER_AND_INCR (j, p);
++          p += j;
++
++          /* If what's on the stack is where we are now, pop it.  */
++          if (!FAIL_STACK_EMPTY ()
++	      && fail_stack.stack[fail_stack.avail - 1].pointer == p)
++            fail_stack.avail--;
++
++          continue;
++
++
++        case on_failure_jump:
++        case on_failure_keep_string_jump:
++	handle_on_failure_jump:
++          EXTRACT_NUMBER_AND_INCR (j, p);
++
++          /* For some patterns, e.g., `(a?)?', `p+j' here points to the
++             end of the pattern.  We don't want to push such a point,
++             since when we restore it above, entering the switch will
++             increment `p' past the end of the pattern.  We don't need
++             to push such a point since we obviously won't find any more
++             fastmap entries beyond `pend'.  Such a pattern can match
++             the null string, though.  */
++          if (p + j < pend)
++            {
++              if (!PUSH_PATTERN_OP (p + j, fail_stack))
++		{
++		  RESET_FAIL_STACK ();
++		  return -2;
++		}
++            }
++          else
++            bufp->can_be_null = 1;
++
++          if (succeed_n_p)
++            {
++              EXTRACT_NUMBER_AND_INCR (k, p);	/* Skip the n.  */
++              succeed_n_p = false;
++	    }
++
++          continue;
++
++
++	case succeed_n:
++          /* Get to the number of times to succeed.  */
++          p += OFFSET_ADDRESS_SIZE;
++
++          /* Increment p past the n for when k != 0.  */
++          EXTRACT_NUMBER_AND_INCR (k, p);
++          if (k == 0)
++	    {
++              p -= 2 * OFFSET_ADDRESS_SIZE;
++  	      succeed_n_p = true;  /* Spaghetti code alert.  */
++              goto handle_on_failure_jump;
++            }
++          continue;
++
++
++	case set_number_at:
++          p += 2 * OFFSET_ADDRESS_SIZE;
++          continue;
++
++
++	case start_memory:
++        case stop_memory:
++	  p += 2;
++	  continue;
++
++
++	default:
++          abort (); /* We have listed all the cases.  */
++        } /* switch *p++ */
++
++      /* Getting here means we have found the possible starting
++         characters for one path of the pattern -- and that the empty
++         string does not match.  We need not follow this path further.
++         Instead, look at the next alternative (remembered on the
++         stack), or quit if no more.  The test at the top of the loop
++         does these things.  */
++      path_can_be_null = false;
++      p = pend;
++    } /* while p */
++
++  /* Set `can_be_null' for the last path (also the first path, if the
++     pattern is empty).  */
++  bufp->can_be_null |= path_can_be_null;
++
++ done:
++  RESET_FAIL_STACK ();
++  return 0;
++}
++
++#else /* not INSIDE_RECURSION */
++
++int
++re_compile_fastmap (struct re_pattern_buffer *bufp)
++{
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    return wcs_re_compile_fastmap(bufp);
++  else
++# endif
++    return byte_re_compile_fastmap(bufp);
++} /* re_compile_fastmap */
++#ifdef _LIBC
++weak_alias (__re_compile_fastmap, re_compile_fastmap)
++#endif
++\f
++
++/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
++   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
++   this memory for recording register information.  STARTS and ENDS
++   must be allocated using the malloc library routine, and must each
++   be at least NUM_REGS * sizeof (regoff_t) bytes long.
++
++   If NUM_REGS == 0, then subsequent matches should allocate their own
++   register data.
++
++   Unless this function is called, the first search or match using
++   PATTERN_BUFFER will allocate its own register data, without
++   freeing the old data.  */
++
++void
++re_set_registers (struct re_pattern_buffer *bufp,
++                  struct re_registers *regs, unsigned num_regs,
++                  regoff_t *starts, regoff_t *ends)
++{
++  if (num_regs)
++    {
++      bufp->regs_allocated = REGS_REALLOCATE;
++      regs->num_regs = num_regs;
++      regs->start = starts;
++      regs->end = ends;
++    }
++  else
++    {
++      bufp->regs_allocated = REGS_UNALLOCATED;
++      regs->num_regs = 0;
++      regs->start = regs->end = (regoff_t *) 0;
++    }
++}
++#ifdef _LIBC
++weak_alias (__re_set_registers, re_set_registers)
++#endif
++\f
++/* Searching routines.  */
++
++/* Like re_search_2, below, but only one string is specified, and
++   doesn't let you say where to stop matching.  */
++
++int
++re_search (struct re_pattern_buffer *bufp, const char *string, int size,
++           int startpos, int range, struct re_registers *regs)
++{
++  return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
++		      regs, size);
++}
++#ifdef _LIBC
++weak_alias (__re_search, re_search)
++#endif
++
++
++/* Using the compiled pattern in BUFP->buffer, first tries to match the
++   virtual concatenation of STRING1 and STRING2, starting first at index
++   STARTPOS, then at STARTPOS + 1, and so on.
++
++   STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
++
++   RANGE is how far to scan while trying to match.  RANGE = 0 means try
++   only at STARTPOS; in general, the last start tried is STARTPOS +
++   RANGE.
++
++   In REGS, return the indices of the virtual concatenation of STRING1
++   and STRING2 that matched the entire BUFP->buffer and its contained
++   subexpressions.
++
++   Do not consider matching one past the index STOP in the virtual
++   concatenation of STRING1 and STRING2.
++
++   We return either the position in the strings at which the match was
++   found, -1 if no match, or -2 if error (such as failure
++   stack overflow).  */
++
++int
++re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
++             const char *string2, int size2, int startpos, int range,
++             struct re_registers *regs, int stop)
++{
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos,
++			    range, regs, stop);
++  else
++# endif
++    return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
++			     range, regs, stop);
++} /* re_search_2 */
++#ifdef _LIBC
++weak_alias (__re_search_2, re_search_2)
++#endif
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef MATCH_MAY_ALLOCATE
++# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
++#else
++# define FREE_VAR(var) if (var) free (var); var = NULL
++#endif
++
++#ifdef WCHAR
++# define MAX_ALLOCA_SIZE	2000
++
++# define FREE_WCS_BUFFERS() \
++  do {									      \
++    if (size1 > MAX_ALLOCA_SIZE)					      \
++      {									      \
++	free (wcs_string1);						      \
++	free (mbs_offset1);						      \
++      }									      \
++    else								      \
++      {									      \
++	FREE_VAR (wcs_string1);						      \
++	FREE_VAR (mbs_offset1);						      \
++      }									      \
++    if (size2 > MAX_ALLOCA_SIZE) 					      \
++      {									      \
++	free (wcs_string2);						      \
++	free (mbs_offset2);						      \
++      }									      \
++    else								      \
++      {									      \
++	FREE_VAR (wcs_string2);						      \
++	FREE_VAR (mbs_offset2);						      \
++      }									      \
++  } while (0)
++
++#endif
++
++
++static int
++PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1,
++                     int size1, const char *string2, int size2,
++                     int startpos, int range,
++                     struct re_registers *regs, int stop)
++{
++  int val;
++  register char *fastmap = bufp->fastmap;
++  register RE_TRANSLATE_TYPE translate = bufp->translate;
++  int total_size = size1 + size2;
++  int endpos = startpos + range;
++#ifdef WCHAR
++  /* We need wchar_t* buffers correspond to cstring1, cstring2.  */
++  wchar_t *wcs_string1 = NULL, *wcs_string2 = NULL;
++  /* We need the size of wchar_t buffers correspond to csize1, csize2.  */
++  int wcs_size1 = 0, wcs_size2 = 0;
++  /* offset buffer for optimizatoin. See convert_mbs_to_wc.  */
++  int *mbs_offset1 = NULL, *mbs_offset2 = NULL;
++  /* They hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++#endif /* WCHAR */
++
++  /* Check for out-of-range STARTPOS.  */
++  if (startpos < 0 || startpos > total_size)
++    return -1;
++
++  /* Fix up RANGE if it might eventually take us outside
++     the virtual concatenation of STRING1 and STRING2.
++     Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE.  */
++  if (endpos < 0)
++    range = 0 - startpos;
++  else if (endpos > total_size)
++    range = total_size - startpos;
++
++  /* If the search isn't to be a backwards one, don't waste time in a
++     search for a pattern that must be anchored.  */
++  if (bufp->used > 0 && range > 0
++      && ((re_opcode_t) bufp->buffer[0] == begbuf
++	  /* `begline' is like `begbuf' if it cannot match at newlines.  */
++	  || ((re_opcode_t) bufp->buffer[0] == begline
++	      && !bufp->newline_anchor)))
++    {
++      if (startpos > 0)
++	return -1;
++      else
++	range = 1;
++    }
++
++#ifdef emacs
++  /* In a forward search for something that starts with \=.
++     don't keep searching past point.  */
++  if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
++    {
++      range = PT - startpos;
++      if (range <= 0)
++	return -1;
++    }
++#endif /* emacs */
++
++  /* Update the fastmap now if not correct already.  */
++  if (fastmap && !bufp->fastmap_accurate)
++    if (re_compile_fastmap (bufp) == -2)
++      return -2;
++
++#ifdef WCHAR
++  /* Allocate wchar_t array for wcs_string1 and wcs_string2 and
++     fill them with converted string.  */
++  if (size1 != 0)
++    {
++      if (size1 > MAX_ALLOCA_SIZE)
++	{
++	  wcs_string1 = TALLOC (size1 + 1, CHAR_T);
++	  mbs_offset1 = TALLOC (size1 + 1, int);
++	  is_binary = TALLOC (size1 + 1, char);
++	}
++      else
++	{
++	  wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
++	  mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
++	  is_binary = REGEX_TALLOC (size1 + 1, char);
++	}
++      if (!wcs_string1 || !mbs_offset1 || !is_binary)
++	{
++	  if (size1 > MAX_ALLOCA_SIZE)
++	    {
++	      free (wcs_string1);
++	      free (mbs_offset1);
++	      free (is_binary);
++	    }
++	  else
++	    {
++	      FREE_VAR (wcs_string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (is_binary);
++	    }
++	  return -2;
++	}
++      wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1,
++				     mbs_offset1, is_binary);
++      wcs_string1[wcs_size1] = L'\0'; /* for a sentinel  */
++      if (size1 > MAX_ALLOCA_SIZE)
++	free (is_binary);
++      else
++	FREE_VAR (is_binary);
++    }
++  if (size2 != 0)
++    {
++      if (size2 > MAX_ALLOCA_SIZE)
++	{
++	  wcs_string2 = TALLOC (size2 + 1, CHAR_T);
++	  mbs_offset2 = TALLOC (size2 + 1, int);
++	  is_binary = TALLOC (size2 + 1, char);
++	}
++      else
++	{
++	  wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
++	  mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
++	  is_binary = REGEX_TALLOC (size2 + 1, char);
++	}
++      if (!wcs_string2 || !mbs_offset2 || !is_binary)
++	{
++	  FREE_WCS_BUFFERS ();
++	  if (size2 > MAX_ALLOCA_SIZE)
++	    free (is_binary);
++	  else
++	    FREE_VAR (is_binary);
++	  return -2;
++	}
++      wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2,
++				     mbs_offset2, is_binary);
++      wcs_string2[wcs_size2] = L'\0'; /* for a sentinel  */
++      if (size2 > MAX_ALLOCA_SIZE)
++	free (is_binary);
++      else
++	FREE_VAR (is_binary);
++    }
++#endif /* WCHAR */
++
++
++  /* Loop through the string, looking for a place to start matching.  */
++  for (;;)
++    {
++      /* If a fastmap is supplied, skip quickly over characters that
++         cannot be the start of a match.  If the pattern can match the
++         null string, however, we don't need to skip characters; we want
++         the first null string.  */
++      if (fastmap && startpos < total_size && !bufp->can_be_null)
++	{
++	  if (range > 0)	/* Searching forwards.  */
++	    {
++	      register const char *d;
++	      register int lim = 0;
++	      int irange = range;
++
++              if (startpos < size1 && startpos + range >= size1)
++                lim = range - (size1 - startpos);
++
++	      d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
++
++              /* Written out as an if-else to avoid testing `translate'
++                 inside the loop.  */
++	      if (translate)
++                while (range > lim
++                       && !fastmap[(unsigned char)
++				   translate[(unsigned char) *d++]])
++                  range--;
++	      else
++                while (range > lim && !fastmap[(unsigned char) *d++])
++                  range--;
++
++	      startpos += irange - range;
++	    }
++	  else				/* Searching backwards.  */
++	    {
++	      register CHAR_T c = (size1 == 0 || startpos >= size1
++				      ? string2[startpos - size1]
++				      : string1[startpos]);
++
++	      if (!fastmap[(unsigned char) TRANSLATE (c)])
++		goto advance;
++	    }
++	}
++
++      /* If can't match the null string, and that's all we have left, fail.  */
++      if (range >= 0 && startpos == total_size && fastmap
++          && !bufp->can_be_null)
++       {
++#ifdef WCHAR
++         FREE_WCS_BUFFERS ();
++#endif
++         return -1;
++       }
++
++#ifdef WCHAR
++      val = wcs_re_match_2_internal (bufp, string1, size1, string2,
++				     size2, startpos, regs, stop,
++				     wcs_string1, wcs_size1,
++				     wcs_string2, wcs_size2,
++				     mbs_offset1, mbs_offset2);
++#else /* BYTE */
++      val = byte_re_match_2_internal (bufp, string1, size1, string2,
++				      size2, startpos, regs, stop);
++#endif /* BYTE */
++
++#ifndef REGEX_MALLOC
++# ifdef C_ALLOCA
++      alloca (0);
++# endif
++#endif
++
++      if (val >= 0)
++	{
++#ifdef WCHAR
++	  FREE_WCS_BUFFERS ();
++#endif
++	  return startpos;
++	}
++
++      if (val == -2)
++	{
++#ifdef WCHAR
++	  FREE_WCS_BUFFERS ();
++#endif
++	  return -2;
++	}
++
++    advance:
++      if (!range)
++        break;
++      else if (range > 0)
++        {
++          range--;
++          startpos++;
++        }
++      else
++        {
++          range++;
++          startpos--;
++        }
++    }
++#ifdef WCHAR
++  FREE_WCS_BUFFERS ();
++#endif
++  return -1;
++}
++
++#ifdef WCHAR
++/* This converts PTR, a pointer into one of the search wchar_t strings
++   `string1' and `string2' into an multibyte string offset from the
++   beginning of that string. We use mbs_offset to optimize.
++   See convert_mbs_to_wcs.  */
++# define POINTER_TO_OFFSET(ptr)						\
++  (FIRST_STRING_P (ptr)							\
++   ? ((regoff_t)(mbs_offset1 != NULL? mbs_offset1[(ptr)-string1] : 0))	\
++   : ((regoff_t)((mbs_offset2 != NULL? mbs_offset2[(ptr)-string2] : 0)	\
++		 + csize1)))
++#else /* BYTE */
++/* This converts PTR, a pointer into one of the search strings `string1'
++   and `string2' into an offset from the beginning of that string.  */
++# define POINTER_TO_OFFSET(ptr)			\
++  (FIRST_STRING_P (ptr)				\
++   ? ((regoff_t) ((ptr) - string1))		\
++   : ((regoff_t) ((ptr) - string2 + size1)))
++#endif /* WCHAR */
++
++/* Macros for dealing with the split strings in re_match_2.  */
++
++#define MATCHING_IN_FIRST_STRING  (dend == end_match_1)
++
++/* Call before fetching a character with *d.  This switches over to
++   string2 if necessary.  */
++#define PREFETCH()							\
++  while (d == dend)						    	\
++    {									\
++      /* End of string2 => fail.  */					\
++      if (dend == end_match_2) 						\
++        goto fail;							\
++      /* End of string1 => advance to string2.  */ 			\
++      d = string2;						        \
++      dend = end_match_2;						\
++    }
++
++/* Test if at very beginning or at very end of the virtual concatenation
++   of `string1' and `string2'.  If only one string, it's `string2'.  */
++#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
++#define AT_STRINGS_END(d) ((d) == end2)
++
++
++/* Test if D points to a character which is word-constituent.  We have
++   two special cases to check for: if past the end of string1, look at
++   the first character in string2; and if before the beginning of
++   string2, look at the last character in string1.  */
++#ifdef WCHAR
++/* Use internationalized API instead of SYNTAX.  */
++# define WORDCHAR_P(d)							\
++  (iswalnum ((wint_t)((d) == end1 ? *string2				\
++           : (d) == string2 - 1 ? *(end1 - 1) : *(d))) != 0		\
++   || ((d) == end1 ? *string2						\
++       : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == L'_')
++#else /* BYTE */
++# define WORDCHAR_P(d)							\
++  (SYNTAX ((d) == end1 ? *string2					\
++           : (d) == string2 - 1 ? *(end1 - 1) : *(d))			\
++   == Sword)
++#endif /* WCHAR */
++
++/* Disabled due to a compiler bug -- see comment at case wordbound */
++#if 0
++/* Test if the character before D and the one at D differ with respect
++   to being word-constituent.  */
++#define AT_WORD_BOUNDARY(d)						\
++  (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)				\
++   || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
++#endif
++
++/* Free everything we malloc.  */
++#ifdef MATCH_MAY_ALLOCATE
++# ifdef WCHAR
++#  define FREE_VARIABLES()						\
++  do {									\
++    REGEX_FREE_STACK (fail_stack.stack);				\
++    FREE_VAR (regstart);						\
++    FREE_VAR (regend);							\
++    FREE_VAR (old_regstart);						\
++    FREE_VAR (old_regend);						\
++    FREE_VAR (best_regstart);						\
++    FREE_VAR (best_regend);						\
++    FREE_VAR (reg_info);						\
++    FREE_VAR (reg_dummy);						\
++    FREE_VAR (reg_info_dummy);						\
++    if (!cant_free_wcs_buf)						\
++      {									\
++        FREE_VAR (string1);						\
++        FREE_VAR (string2);						\
++        FREE_VAR (mbs_offset1);						\
++        FREE_VAR (mbs_offset2);						\
++      }									\
++  } while (0)
++# else /* BYTE */
++#  define FREE_VARIABLES()						\
++  do {									\
++    REGEX_FREE_STACK (fail_stack.stack);				\
++    FREE_VAR (regstart);						\
++    FREE_VAR (regend);							\
++    FREE_VAR (old_regstart);						\
++    FREE_VAR (old_regend);						\
++    FREE_VAR (best_regstart);						\
++    FREE_VAR (best_regend);						\
++    FREE_VAR (reg_info);						\
++    FREE_VAR (reg_dummy);						\
++    FREE_VAR (reg_info_dummy);						\
++  } while (0)
++# endif /* WCHAR */
++#else
++# ifdef WCHAR
++#  define FREE_VARIABLES()						\
++  do {									\
++    if (!cant_free_wcs_buf)						\
++      {									\
++        FREE_VAR (string1);						\
++        FREE_VAR (string2);						\
++        FREE_VAR (mbs_offset1);						\
++        FREE_VAR (mbs_offset2);						\
++      }									\
++  } while (0)
++# else /* BYTE */
++#  define FREE_VARIABLES() ((void)0) /* Do nothing!  But inhibit gcc warning. */
++# endif /* WCHAR */
++#endif /* not MATCH_MAY_ALLOCATE */
++
++/* These values must meet several constraints.  They must not be valid
++   register values; since we have a limit of 255 registers (because
++   we use only one byte in the pattern for the register number), we can
++   use numbers larger than 255.  They must differ by 1, because of
++   NUM_FAILURE_ITEMS above.  And the value for the lowest register must
++   be larger than the value for the highest register, so we do not try
++   to actually save any registers when none are active.  */
++#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
++#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
++\f
++#else /* not INSIDE_RECURSION */
++/* Matching routines.  */
++
++#ifndef emacs   /* Emacs never uses this.  */
++/* re_match is like re_match_2 except it takes only a single string.  */
++
++int
++re_match (struct re_pattern_buffer *bufp, const char *string,
++          int size, int pos, struct re_registers *regs)
++{
++  int result;
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    result = wcs_re_match_2_internal (bufp, NULL, 0, string, size,
++				      pos, regs, size,
++				      NULL, 0, NULL, 0, NULL, NULL);
++  else
++# endif
++    result = byte_re_match_2_internal (bufp, NULL, 0, string, size,
++				  pos, regs, size);
++# ifndef REGEX_MALLOC
++#  ifdef C_ALLOCA
++  alloca (0);
++#  endif
++# endif
++  return result;
++}
++# ifdef _LIBC
++weak_alias (__re_match, re_match)
++# endif
++#endif /* not emacs */
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p,
++                                                  UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p,
++                                                UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p,
++                                                      UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2,
++                                   register int len,
++				   RE_TRANSLATE_TYPE translate);
++#else /* not INSIDE_RECURSION */
++
++/* re_match_2 matches the compiled pattern in BUFP against the
++   the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
++   and SIZE2, respectively).  We start matching at POS, and stop
++   matching at STOP.
++
++   If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
++   store offsets for the substring each group matched in REGS.  See the
++   documentation for exactly how many groups we fill.
++
++   We return -1 if no match, -2 if an internal error (such as the
++   failure stack overflowing).  Otherwise, we return the length of the
++   matched substring.  */
++
++int
++re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
++            const char *string2, int size2, int pos,
++            struct re_registers *regs, int stop)
++{
++  int result;
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    result = wcs_re_match_2_internal (bufp, string1, size1, string2, size2,
++				      pos, regs, stop,
++				      NULL, 0, NULL, 0, NULL, NULL);
++  else
++# endif
++    result = byte_re_match_2_internal (bufp, string1, size1, string2, size2,
++				  pos, regs, stop);
++
++#ifndef REGEX_MALLOC
++# ifdef C_ALLOCA
++  alloca (0);
++# endif
++#endif
++  return result;
++}
++#ifdef _LIBC
++weak_alias (__re_match_2, re_match_2)
++#endif
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef WCHAR
++static int count_mbs_length (int *, int);
++
++/* This check the substring (from 0, to length) of the multibyte string,
++   to which offset_buffer correspond. And count how many wchar_t_characters
++   the substring occupy. We use offset_buffer to optimization.
++   See convert_mbs_to_wcs.  */
++
++static int
++count_mbs_length(int *offset_buffer, int length)
++{
++  int upper, lower;
++
++  /* Check whether the size is valid.  */
++  if (length < 0)
++    return -1;
++
++  if (offset_buffer == NULL)
++    return 0;
++
++  /* If there are no multibyte character, offset_buffer[i] == i.
++   Optmize for this case.  */
++  if (offset_buffer[length] == length)
++    return length;
++
++  /* Set up upper with length. (because for all i, offset_buffer[i] >= i)  */
++  upper = length;
++  lower = 0;
++
++  while (true)
++    {
++      int middle = (lower + upper) / 2;
++      if (middle == lower || middle == upper)
++	break;
++      if (offset_buffer[middle] > length)
++	upper = middle;
++      else if (offset_buffer[middle] < length)
++	lower = middle;
++      else
++	return middle;
++    }
++
++  return -1;
++}
++#endif /* WCHAR */
++
++/* This is a separate function so that we can force an alloca cleanup
++   afterwards.  */
++#ifdef WCHAR
++static int
++wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
++                         const char *cstring1, int csize1,
++                         const char *cstring2, int csize2,
++                         int pos,
++			 struct re_registers *regs,
++                         int stop,
++     /* string1 == string2 == NULL means string1/2, size1/2 and
++	mbs_offset1/2 need seting up in this function.  */
++     /* We need wchar_t* buffers correspond to cstring1, cstring2.  */
++                         wchar_t *string1, int size1,
++                         wchar_t *string2, int size2,
++     /* offset buffer for optimizatoin. See convert_mbs_to_wc.  */
++			 int *mbs_offset1, int *mbs_offset2)
++#else /* BYTE */
++static int
++byte_re_match_2_internal (struct re_pattern_buffer *bufp,
++                          const char *string1, int size1,
++                          const char *string2, int size2,
++                          int pos,
++			  struct re_registers *regs, int stop)
++#endif /* BYTE */
++{
++  /* General temporaries.  */
++  int mcnt;
++  UCHAR_T *p1;
++#ifdef WCHAR
++  /* They hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++  /* If true, we can't free string1/2, mbs_offset1/2.  */
++  int cant_free_wcs_buf = 1;
++#endif /* WCHAR */
++
++  /* Just past the end of the corresponding string.  */
++  const CHAR_T *end1, *end2;
++
++  /* Pointers into string1 and string2, just past the last characters in
++     each to consider matching.  */
++  const CHAR_T *end_match_1, *end_match_2;
++
++  /* Where we are in the data, and the end of the current string.  */
++  const CHAR_T *d, *dend;
++
++  /* Where we are in the pattern, and the end of the pattern.  */
++#ifdef WCHAR
++  UCHAR_T *pattern, *p;
++  register UCHAR_T *pend;
++#else /* BYTE */
++  UCHAR_T *p = bufp->buffer;
++  register UCHAR_T *pend = p + bufp->used;
++#endif /* WCHAR */
++
++  /* Mark the opcode just after a start_memory, so we can test for an
++     empty subpattern when we get to the stop_memory.  */
++  UCHAR_T *just_past_start_mem = 0;
++
++  /* We use this to map every character in the string.  */
++  RE_TRANSLATE_TYPE translate = bufp->translate;
++
++  /* Failure point stack.  Each place that can handle a failure further
++     down the line pushes a failure point on this stack.  It consists of
++     restart, regend, and reg_info for all registers corresponding to
++     the subexpressions we're currently inside, plus the number of such
++     registers, and, finally, two char *'s.  The first char * is where
++     to resume scanning the pattern; the second one is where to resume
++     scanning the strings.  If the latter is zero, the failure point is
++     a ``dummy''; if a failure happens and the failure point is a dummy,
++     it gets discarded and the next next one is tried.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
++  PREFIX(fail_stack_type) fail_stack;
++#endif
++#ifdef DEBUG
++  static unsigned failure_id;
++  unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
++#endif
++
++#ifdef REL_ALLOC
++  /* This holds the pointer to the failure stack, when
++     it is allocated relocatably.  */
++  fail_stack_elt_t *failure_stack_ptr;
++#endif
++
++  /* We fill all the registers internally, independent of what we
++     return, for use in backreferences.  The number here includes
++     an element for register zero.  */
++  size_t num_regs = bufp->re_nsub + 1;
++
++  /* The currently active registers.  */
++  active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++  active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++
++  /* Information on the contents of registers. These are pointers into
++     the input strings; they record just what was matched (on this
++     attempt) by a subexpression part of the pattern, that is, the
++     regnum-th regstart pointer points to where in the pattern we began
++     matching and the regnum-th regend points to right after where we
++     stopped matching the regnum-th subexpression.  (The zeroth register
++     keeps track of what the whole pattern matches.)  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **regstart, **regend;
++#endif
++
++  /* If a group that's operated upon by a repetition operator fails to
++     match anything, then the register for its start will need to be
++     restored because it will have been set to wherever in the string we
++     are when we last see its open-group operator.  Similarly for a
++     register's end.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **old_regstart, **old_regend;
++#endif
++
++  /* The is_active field of reg_info helps us keep track of which (possibly
++     nested) subexpressions we are currently in. The matched_something
++     field of reg_info[reg_num] helps us tell whether or not we have
++     matched any of the pattern so far this time through the reg_num-th
++     subexpression.  These two fields get reset each time through any
++     loop their register is in.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
++  PREFIX(register_info_type) *reg_info;
++#endif
++
++  /* The following record the register info as found in the above
++     variables when we find a match better than any we've seen before.
++     This happens as we backtrack through the failure points, which in
++     turn happens only if we have not yet matched the entire string. */
++  unsigned best_regs_set = false;
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **best_regstart, **best_regend;
++#endif
++
++  /* Logically, this is `best_regend[0]'.  But we don't want to have to
++     allocate space for that if we're not allocating space for anything
++     else (see below).  Also, we never need info about register 0 for
++     any of the other register vectors, and it seems rather a kludge to
++     treat `best_regend' differently than the rest.  So we keep track of
++     the end of the best match so far in a separate variable.  We
++     initialize this to NULL so that when we backtrack the first time
++     and need to test it, it's not garbage.  */
++  const CHAR_T *match_end = NULL;
++
++  /* This helps SET_REGS_MATCHED avoid doing redundant work.  */
++  int set_regs_matched_done = 0;
++
++  /* Used when we pop values we don't care about.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **reg_dummy;
++  PREFIX(register_info_type) *reg_info_dummy;
++#endif
++
++#ifdef DEBUG
++  /* Counts the total number of registers pushed.  */
++  unsigned num_regs_pushed = 0;
++#endif
++
++  DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
++
++  INIT_FAIL_STACK ();
++
++#ifdef MATCH_MAY_ALLOCATE
++  /* Do not bother to initialize all the register variables if there are
++     no groups in the pattern, as it takes a fair amount of time.  If
++     there are groups, we include space for register 0 (the whole
++     pattern), even though we never use it, since it simplifies the
++     array indexing.  We should fix this.  */
++  if (bufp->re_nsub)
++    {
++      regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      old_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      old_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      best_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      best_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      reg_info = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
++      reg_dummy = REGEX_TALLOC (num_regs, const CHAR_T *);
++      reg_info_dummy = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
++
++      if (!(regstart && regend && old_regstart && old_regend && reg_info
++            && best_regstart && best_regend && reg_dummy && reg_info_dummy))
++        {
++          FREE_VARIABLES ();
++          return -2;
++        }
++    }
++  else
++    {
++      /* We must initialize all our variables to NULL, so that
++         `FREE_VARIABLES' doesn't try to free them.  */
++      regstart = regend = old_regstart = old_regend = best_regstart
++        = best_regend = reg_dummy = NULL;
++      reg_info = reg_info_dummy = (PREFIX(register_info_type) *) NULL;
++    }
++#endif /* MATCH_MAY_ALLOCATE */
++
++  /* The starting position is bogus.  */
++#ifdef WCHAR
++  if (pos < 0 || pos > csize1 + csize2)
++#else /* BYTE */
++  if (pos < 0 || pos > size1 + size2)
++#endif
++    {
++      FREE_VARIABLES ();
++      return -1;
++    }
++
++#ifdef WCHAR
++  /* Allocate wchar_t array for string1 and string2 and
++     fill them with converted string.  */
++  if (string1 == NULL && string2 == NULL)
++    {
++      /* We need seting up buffers here.  */
++
++      /* We must free wcs buffers in this function.  */
++      cant_free_wcs_buf = 0;
++
++      if (csize1 != 0)
++	{
++	  string1 = REGEX_TALLOC (csize1 + 1, CHAR_T);
++	  mbs_offset1 = REGEX_TALLOC (csize1 + 1, int);
++	  is_binary = REGEX_TALLOC (csize1 + 1, char);
++	  if (!string1 || !mbs_offset1 || !is_binary)
++	    {
++	      FREE_VAR (string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (is_binary);
++	      return -2;
++	    }
++	}
++      if (csize2 != 0)
++	{
++	  string2 = REGEX_TALLOC (csize2 + 1, CHAR_T);
++	  mbs_offset2 = REGEX_TALLOC (csize2 + 1, int);
++	  is_binary = REGEX_TALLOC (csize2 + 1, char);
++	  if (!string2 || !mbs_offset2 || !is_binary)
++	    {
++	      FREE_VAR (string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (string2);
++	      FREE_VAR (mbs_offset2);
++	      FREE_VAR (is_binary);
++	      return -2;
++	    }
++	  size2 = convert_mbs_to_wcs(string2, cstring2, csize2,
++				     mbs_offset2, is_binary);
++	  string2[size2] = L'\0'; /* for a sentinel  */
++	  FREE_VAR (is_binary);
++	}
++    }
++
++  /* We need to cast pattern to (wchar_t*), because we casted this compiled
++     pattern to (char*) in regex_compile.  */
++  p = pattern = (CHAR_T*)bufp->buffer;
++  pend = (CHAR_T*)(bufp->buffer + bufp->used);
++
++#endif /* WCHAR */
++
++  /* Initialize subexpression text positions to -1 to mark ones that no
++     start_memory/stop_memory has been seen for. Also initialize the
++     register information struct.  */
++  for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++    {
++      regstart[mcnt] = regend[mcnt]
++        = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
++
++      REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
++      IS_ACTIVE (reg_info[mcnt]) = 0;
++      MATCHED_SOMETHING (reg_info[mcnt]) = 0;
++      EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
++    }
++
++  /* We move `string1' into `string2' if the latter's empty -- but not if
++     `string1' is null.  */
++  if (size2 == 0 && string1 != NULL)
++    {
++      string2 = string1;
++      size2 = size1;
++      string1 = 0;
++      size1 = 0;
++#ifdef WCHAR
++      mbs_offset2 = mbs_offset1;
++      csize2 = csize1;
++      mbs_offset1 = NULL;
++      csize1 = 0;
++#endif
++    }
++  end1 = string1 + size1;
++  end2 = string2 + size2;
++
++  /* Compute where to stop matching, within the two strings.  */
++#ifdef WCHAR
++  if (stop <= csize1)
++    {
++      mcnt = count_mbs_length(mbs_offset1, stop);
++      end_match_1 = string1 + mcnt;
++      end_match_2 = string2;
++    }
++  else
++    {
++      if (stop > csize1 + csize2)
++	stop = csize1 + csize2;
++      end_match_1 = end1;
++      mcnt = count_mbs_length(mbs_offset2, stop-csize1);
++      end_match_2 = string2 + mcnt;
++    }
++  if (mcnt < 0)
++    { /* count_mbs_length return error.  */
++      FREE_VARIABLES ();
++      return -1;
++    }
++#else
++  if (stop <= size1)
++    {
++      end_match_1 = string1 + stop;
++      end_match_2 = string2;
++    }
++  else
++    {
++      end_match_1 = end1;
++      end_match_2 = string2 + stop - size1;
++    }
++#endif /* WCHAR */
++
++  /* `p' scans through the pattern as `d' scans through the data.
++     `dend' is the end of the input string that `d' points within.  `d'
++     is advanced into the following input string whenever necessary, but
++     this happens before fetching; therefore, at the beginning of the
++     loop, `d' can be pointing at the end of a string, but it cannot
++     equal `string2'.  */
++#ifdef WCHAR
++  if (size1 > 0 && pos <= csize1)
++    {
++      mcnt = count_mbs_length(mbs_offset1, pos);
++      d = string1 + mcnt;
++      dend = end_match_1;
++    }
++  else
++    {
++      mcnt = count_mbs_length(mbs_offset2, pos-csize1);
++      d = string2 + mcnt;
++      dend = end_match_2;
++    }
++
++  if (mcnt < 0)
++    { /* count_mbs_length return error.  */
++      FREE_VARIABLES ();
++      return -1;
++    }
++#else
++  if (size1 > 0 && pos <= size1)
++    {
++      d = string1 + pos;
++      dend = end_match_1;
++    }
++  else
++    {
++      d = string2 + pos - size1;
++      dend = end_match_2;
++    }
++#endif /* WCHAR */
++
++  DEBUG_PRINT1 ("The compiled pattern is:\n");
++  DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
++  DEBUG_PRINT1 ("The string to match is: `");
++  DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
++  DEBUG_PRINT1 ("'\n");
++
++  /* This loops over pattern commands.  It exits by returning from the
++     function if the match is complete, or it drops through if the match
++     fails at this starting point in the input data.  */
++  for (;;)
++    {
++#ifdef _LIBC
++      DEBUG_PRINT2 ("\n%p: ", p);
++#else
++      DEBUG_PRINT2 ("\n0x%x: ", p);
++#endif
++
++      if (p == pend)
++	{ /* End of pattern means we might have succeeded.  */
++          DEBUG_PRINT1 ("end of pattern ... ");
++
++	  /* If we haven't matched the entire string, and we want the
++             longest match, try backtracking.  */
++          if (d != end_match_2)
++	    {
++	      /* 1 if this match ends in the same string (string1 or string2)
++		 as the best previous match.  */
++	      boolean same_str_p = (FIRST_STRING_P (match_end)
++				    == MATCHING_IN_FIRST_STRING);
++	      /* 1 if this match is the best seen so far.  */
++	      boolean best_match_p;
++
++	      /* AIX compiler got confused when this was combined
++		 with the previous declaration.  */
++	      if (same_str_p)
++		best_match_p = d > match_end;
++	      else
++		best_match_p = !MATCHING_IN_FIRST_STRING;
++
++              DEBUG_PRINT1 ("backtracking.\n");
++
++              if (!FAIL_STACK_EMPTY ())
++                { /* More failure points to try.  */
++
++                  /* If exceeds best match so far, save it.  */
++                  if (!best_regs_set || best_match_p)
++                    {
++                      best_regs_set = true;
++                      match_end = d;
++
++                      DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
++
++                      for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++                        {
++                          best_regstart[mcnt] = regstart[mcnt];
++                          best_regend[mcnt] = regend[mcnt];
++                        }
++                    }
++                  goto fail;
++                }
++
++              /* If no failure points, don't restore garbage.  And if
++                 last match is real best match, don't restore second
++                 best one. */
++              else if (best_regs_set && !best_match_p)
++                {
++  	        restore_best_regs:
++                  /* Restore best match.  It may happen that `dend ==
++                     end_match_1' while the restored d is in string2.
++                     For example, the pattern `x.*y.*z' against the
++                     strings `x-' and `y-z-', if the two strings are
++                     not consecutive in memory.  */
++                  DEBUG_PRINT1 ("Restoring best registers.\n");
++
++                  d = match_end;
++                  dend = ((d >= string1 && d <= end1)
++		           ? end_match_1 : end_match_2);
++
++		  for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++		    {
++		      regstart[mcnt] = best_regstart[mcnt];
++		      regend[mcnt] = best_regend[mcnt];
++		    }
++                }
++            } /* d != end_match_2 */
++
++	succeed_label:
++          DEBUG_PRINT1 ("Accepting match.\n");
++          /* If caller wants register contents data back, do it.  */
++          if (regs && !bufp->no_sub)
++	    {
++	      /* Have the register data arrays been allocated?  */
++              if (bufp->regs_allocated == REGS_UNALLOCATED)
++                { /* No.  So allocate them with malloc.  We need one
++                     extra element beyond `num_regs' for the `-1' marker
++                     GNU code uses.  */
++                  regs->num_regs = MAX (RE_NREGS, num_regs + 1);
++                  regs->start = TALLOC (regs->num_regs, regoff_t);
++                  regs->end = TALLOC (regs->num_regs, regoff_t);
++                  if (regs->start == NULL || regs->end == NULL)
++		    {
++		      FREE_VARIABLES ();
++		      return -2;
++		    }
++                  bufp->regs_allocated = REGS_REALLOCATE;
++                }
++              else if (bufp->regs_allocated == REGS_REALLOCATE)
++                { /* Yes.  If we need more elements than were already
++                     allocated, reallocate them.  If we need fewer, just
++                     leave it alone.  */
++                  if (regs->num_regs < num_regs + 1)
++                    {
++                      regs->num_regs = num_regs + 1;
++                      RETALLOC (regs->start, regs->num_regs, regoff_t);
++                      RETALLOC (regs->end, regs->num_regs, regoff_t);
++                      if (regs->start == NULL || regs->end == NULL)
++			{
++			  FREE_VARIABLES ();
++			  return -2;
++			}
++                    }
++                }
++              else
++		{
++		  /* These braces fend off a "empty body in an else-statement"
++		     warning under GCC when assert expands to nothing.  */
++		  assert (bufp->regs_allocated == REGS_FIXED);
++		}
++
++              /* Convert the pointer data in `regstart' and `regend' to
++                 indices.  Register zero has to be set differently,
++                 since we haven't kept track of any info for it.  */
++              if (regs->num_regs > 0)
++                {
++                  regs->start[0] = pos;
++#ifdef WCHAR
++		  if (MATCHING_IN_FIRST_STRING)
++		    regs->end[0] = mbs_offset1 != NULL ?
++					mbs_offset1[d-string1] : 0;
++		  else
++		    regs->end[0] = csize1 + (mbs_offset2 != NULL ?
++					     mbs_offset2[d-string2] : 0);
++#else
++                  regs->end[0] = (MATCHING_IN_FIRST_STRING
++				  ? ((regoff_t) (d - string1))
++			          : ((regoff_t) (d - string2 + size1)));
++#endif /* WCHAR */
++                }
++
++              /* Go through the first `min (num_regs, regs->num_regs)'
++                 registers, since that is all we initialized.  */
++	      for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
++		   mcnt++)
++		{
++                  if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
++                    regs->start[mcnt] = regs->end[mcnt] = -1;
++                  else
++                    {
++		      regs->start[mcnt]
++			= (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
++                      regs->end[mcnt]
++			= (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
++                    }
++		}
++
++              /* If the regs structure we return has more elements than
++                 were in the pattern, set the extra elements to -1.  If
++                 we (re)allocated the registers, this is the case,
++                 because we always allocate enough to have at least one
++                 -1 at the end.  */
++              for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
++                regs->start[mcnt] = regs->end[mcnt] = -1;
++	    } /* regs && !bufp->no_sub */
++
++          DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
++                        nfailure_points_pushed, nfailure_points_popped,
++                        nfailure_points_pushed - nfailure_points_popped);
++          DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
++
++#ifdef WCHAR
++	  if (MATCHING_IN_FIRST_STRING)
++	    mcnt = mbs_offset1 != NULL ? mbs_offset1[d-string1] : 0;
++	  else
++	    mcnt = (mbs_offset2 != NULL ? mbs_offset2[d-string2] : 0) +
++			csize1;
++          mcnt -= pos;
++#else
++          mcnt = d - pos - (MATCHING_IN_FIRST_STRING
++			    ? string1
++			    : string2 - size1);
++#endif /* WCHAR */
++
++          DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
++
++          FREE_VARIABLES ();
++          return mcnt;
++        }
++
++      /* Otherwise match next pattern command.  */
++      switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
++	{
++        /* Ignore these.  Used to ignore the n of succeed_n's which
++           currently have n == 0.  */
++        case no_op:
++          DEBUG_PRINT1 ("EXECUTING no_op.\n");
++          break;
++
++	case succeed:
++          DEBUG_PRINT1 ("EXECUTING succeed.\n");
++	  goto succeed_label;
++
++        /* Match the next n pattern characters exactly.  The following
++           byte in the pattern defines n, and the n bytes after that
++           are the characters to match.  */
++	case exactn:
++#ifdef MBS_SUPPORT
++	case exactn_bin:
++#endif
++	  mcnt = *p++;
++          DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
++
++          /* This is written out as an if-else so we don't waste time
++             testing `translate' inside the loop.  */
++          if (translate)
++	    {
++	      do
++		{
++		  PREFETCH ();
++#ifdef WCHAR
++		  if (*d <= 0xff)
++		    {
++		      if ((UCHAR_T) translate[(unsigned char) *d++]
++			  != (UCHAR_T) *p++)
++			goto fail;
++		    }
++		  else
++		    {
++		      if (*d++ != (CHAR_T) *p++)
++			goto fail;
++		    }
++#else
++		  if ((UCHAR_T) translate[(unsigned char) *d++]
++		      != (UCHAR_T) *p++)
++                    goto fail;
++#endif /* WCHAR */
++		}
++	      while (--mcnt);
++	    }
++	  else
++	    {
++	      do
++		{
++		  PREFETCH ();
++		  if (*d++ != (CHAR_T) *p++) goto fail;
++		}
++	      while (--mcnt);
++	    }
++	  SET_REGS_MATCHED ();
++          break;
++
++
++        /* Match any character except possibly a newline or a null.  */
++	case anychar:
++          DEBUG_PRINT1 ("EXECUTING anychar.\n");
++
++          PREFETCH ();
++
++          if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
++              || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
++	    goto fail;
++
++          SET_REGS_MATCHED ();
++          DEBUG_PRINT2 ("  Matched `%ld'.\n", (long int) *d);
++          d++;
++	  break;
++
++
++	case charset:
++	case charset_not:
++	  {
++	    register UCHAR_T c;
++#ifdef WCHAR
++	    unsigned int i, char_class_length, coll_symbol_length,
++              equiv_class_length, ranges_length, chars_length, length;
++	    CHAR_T *workp, *workp2, *charset_top;
++#define WORK_BUFFER_SIZE 128
++            CHAR_T str_buf[WORK_BUFFER_SIZE];
++# ifdef _LIBC
++	    uint32_t nrules;
++# endif /* _LIBC */
++#endif /* WCHAR */
++	    boolean negate = (re_opcode_t) *(p - 1) == charset_not;
++
++            DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : "");
++	    PREFETCH ();
++	    c = TRANSLATE (*d); /* The character to match.  */
++#ifdef WCHAR
++# ifdef _LIBC
++	    nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif /* _LIBC */
++	    charset_top = p - 1;
++	    char_class_length = *p++;
++	    coll_symbol_length = *p++;
++	    equiv_class_length = *p++;
++	    ranges_length = *p++;
++	    chars_length = *p++;
++	    /* p points charset[6], so the address of the next instruction
++	       (charset[l+m+n+2o+k+p']) equals p[l+m+n+2*o+p'],
++	       where l=length of char_classes, m=length of collating_symbol,
++	       n=equivalence_class, o=length of char_range,
++	       p'=length of character.  */
++	    workp = p;
++	    /* Update p to indicate the next instruction.  */
++	    p += char_class_length + coll_symbol_length+ equiv_class_length +
++              2*ranges_length + chars_length;
++
++            /* match with char_class?  */
++	    for (i = 0; i < char_class_length ; i += CHAR_CLASS_SIZE)
++	      {
++		wctype_t wctype;
++		uintptr_t alignedp = ((uintptr_t)workp
++				      + __alignof__(wctype_t) - 1)
++		  		      & ~(uintptr_t)(__alignof__(wctype_t) - 1);
++		wctype = *((wctype_t*)alignedp);
++		workp += CHAR_CLASS_SIZE;
++# ifdef _LIBC
++		if (__iswctype((wint_t)c, wctype))
++		  goto char_set_matched;
++# else
++		if (iswctype((wint_t)c, wctype))
++		  goto char_set_matched;
++# endif
++	      }
++
++            /* match with collating_symbol?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++		const unsigned char *extra = (const unsigned char *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
++
++		for (workp2 = workp + coll_symbol_length ; workp < workp2 ;
++		     workp++)
++		  {
++		    int32_t *wextra;
++		    wextra = (int32_t*)(extra + *workp++);
++		    for (i = 0; i < *wextra; ++i)
++		      if (TRANSLATE(d[i]) != wextra[1 + i])
++			break;
++
++		    if (i == *wextra)
++		      {
++			/* Update d, however d will be incremented at
++			   char_set_matched:, we decrement d here.  */
++			d += i - 1;
++			goto char_set_matched;
++		      }
++		  }
++	      }
++	    else /* (nrules == 0) */
++# endif
++	      /* If we can't look up collation data, we use wcscoll
++		 instead.  */
++	      {
++		for (workp2 = workp + coll_symbol_length ; workp < workp2 ;)
++		  {
++		    const CHAR_T *backup_d = d, *backup_dend = dend;
++# ifdef _LIBC
++		    length = __wcslen (workp);
++# else
++		    length = wcslen (workp);
++# endif
++
++		    /* If wcscoll(the collating symbol, whole string) > 0,
++		       any substring of the string never match with the
++		       collating symbol.  */
++# ifdef _LIBC
++		    if (__wcscoll (workp, d) > 0)
++# else
++		    if (wcscoll (workp, d) > 0)
++# endif
++		      {
++			workp += length + 1;
++			continue;
++		      }
++
++		    /* First, we compare the collating symbol with
++		       the first character of the string.
++		       If it don't match, we add the next character to
++		       the compare buffer in turn.  */
++		    for (i = 0 ; i < WORK_BUFFER_SIZE-1 ; i++, d++)
++		      {
++			int match;
++			if (d == dend)
++			  {
++			    if (dend == end_match_2)
++			      break;
++			    d = string2;
++			    dend = end_match_2;
++			  }
++
++			/* add next character to the compare buffer.  */
++			str_buf[i] = TRANSLATE(*d);
++			str_buf[i+1] = '\0';
++
++# ifdef _LIBC
++			match = __wcscoll (workp, str_buf);
++# else
++			match = wcscoll (workp, str_buf);
++# endif
++			if (match == 0)
++			  goto char_set_matched;
++
++			if (match < 0)
++			  /* (str_buf > workp) indicate (str_buf + X > workp),
++			     because for all X (str_buf + X > str_buf).
++			     So we don't need continue this loop.  */
++			  break;
++
++			/* Otherwise(str_buf < workp),
++			   (str_buf+next_character) may equals (workp).
++			   So we continue this loop.  */
++		      }
++		    /* not matched */
++		    d = backup_d;
++		    dend = backup_dend;
++		    workp += length + 1;
++		  }
++              }
++            /* match with equivalence_class?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++                const CHAR_T *backup_d = d, *backup_dend = dend;
++		/* Try to match the equivalence class against
++		   those known to the collate implementation.  */
++		const int32_t *table;
++		const int32_t *weights;
++		const int32_t *extra;
++		const int32_t *indirect;
++		int32_t idx, idx2;
++		wint_t *cp;
++		size_t len;
++
++		/* This #include defines a local function!  */
++#  include <locale/weightwc.h>
++
++		table = (const int32_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
++		weights = (const wint_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
++		extra = (const wint_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
++		indirect = (const int32_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
++
++		/* Write 1 collating element to str_buf, and
++		   get its index.  */
++		idx2 = 0;
++
++		for (i = 0 ; idx2 == 0 && i < WORK_BUFFER_SIZE - 1; i++)
++		  {
++		    cp = (wint_t*)str_buf;
++		    if (d == dend)
++		      {
++			if (dend == end_match_2)
++			  break;
++			d = string2;
++			dend = end_match_2;
++		      }
++		    str_buf[i] = TRANSLATE(*(d+i));
++		    str_buf[i+1] = '\0'; /* sentinel */
++		    idx2 = findidx ((const wint_t**)&cp, i);
++		  }
++
++		/* Update d, however d will be incremented at
++		   char_set_matched:, we decrement d here.  */
++		d = backup_d + ((wchar_t*)cp - (wchar_t*)str_buf - 1);
++		if (d >= dend)
++		  {
++		    if (dend == end_match_2)
++			d = dend;
++		    else
++		      {
++			d = string2;
++			dend = end_match_2;
++		      }
++		  }
++
++		len = weights[idx2];
++
++		for (workp2 = workp + equiv_class_length ; workp < workp2 ;
++		     workp++)
++		  {
++		    idx = (int32_t)*workp;
++		    /* We already checked idx != 0 in regex_compile. */
++
++		    if (idx2 != 0 && len == weights[idx])
++		      {
++			int cnt = 0;
++			while (cnt < len && (weights[idx + 1 + cnt]
++					     == weights[idx2 + 1 + cnt]))
++			  ++cnt;
++
++			if (cnt == len)
++			  goto char_set_matched;
++		      }
++		  }
++		/* not matched */
++                d = backup_d;
++                dend = backup_dend;
++	      }
++	    else /* (nrules == 0) */
++# endif
++	      /* If we can't look up collation data, we use wcscoll
++		 instead.  */
++	      {
++		for (workp2 = workp + equiv_class_length ; workp < workp2 ;)
++		  {
++		    const CHAR_T *backup_d = d, *backup_dend = dend;
++# ifdef _LIBC
++		    length = __wcslen (workp);
++# else
++		    length = wcslen (workp);
++# endif
++
++		    /* If wcscoll(the collating symbol, whole string) > 0,
++		       any substring of the string never match with the
++		       collating symbol.  */
++# ifdef _LIBC
++		    if (__wcscoll (workp, d) > 0)
++# else
++		    if (wcscoll (workp, d) > 0)
++# endif
++		      {
++			workp += length + 1;
++			break;
++		      }
++
++		    /* First, we compare the equivalence class with
++		       the first character of the string.
++		       If it don't match, we add the next character to
++		       the compare buffer in turn.  */
++		    for (i = 0 ; i < WORK_BUFFER_SIZE - 1 ; i++, d++)
++		      {
++			int match;
++			if (d == dend)
++			  {
++			    if (dend == end_match_2)
++			      break;
++			    d = string2;
++			    dend = end_match_2;
++			  }
++
++			/* add next character to the compare buffer.  */
++			str_buf[i] = TRANSLATE(*d);
++			str_buf[i+1] = '\0';
++
++# ifdef _LIBC
++			match = __wcscoll (workp, str_buf);
++# else
++			match = wcscoll (workp, str_buf);
++# endif
++
++			if (match == 0)
++			  goto char_set_matched;
++
++			if (match < 0)
++			/* (str_buf > workp) indicate (str_buf + X > workp),
++			   because for all X (str_buf + X > str_buf).
++			   So we don't need continue this loop.  */
++			  break;
++
++			/* Otherwise(str_buf < workp),
++			   (str_buf+next_character) may equals (workp).
++			   So we continue this loop.  */
++		      }
++		    /* not matched */
++		    d = backup_d;
++		    dend = backup_dend;
++		    workp += length + 1;
++		  }
++	      }
++
++            /* match with char_range?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++		uint32_t collseqval;
++		const char *collseq = (const char *)
++		  _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
++
++		collseqval = collseq_table_lookup (collseq, c);
++
++		for (; workp < p - chars_length ;)
++		  {
++		    uint32_t start_val, end_val;
++
++		    /* We already compute the collation sequence value
++		       of the characters (or collating symbols).  */
++		    start_val = (uint32_t) *workp++; /* range_start */
++		    end_val = (uint32_t) *workp++; /* range_end */
++
++		    if (start_val <= collseqval && collseqval <= end_val)
++		      goto char_set_matched;
++		  }
++	      }
++	    else
++# endif
++	      {
++		/* We set range_start_char at str_buf[0], range_end_char
++		   at str_buf[4], and compared char at str_buf[2].  */
++		str_buf[1] = 0;
++		str_buf[2] = c;
++		str_buf[3] = 0;
++		str_buf[5] = 0;
++		for (; workp < p - chars_length ;)
++		  {
++		    wchar_t *range_start_char, *range_end_char;
++
++		    /* match if (range_start_char <= c <= range_end_char).  */
++
++		    /* If range_start(or end) < 0, we assume -range_start(end)
++		       is the offset of the collating symbol which is specified
++		       as the character of the range start(end).  */
++
++		    /* range_start */
++		    if (*workp < 0)
++		      range_start_char = charset_top - (*workp++);
++		    else
++		      {
++			str_buf[0] = *workp++;
++			range_start_char = str_buf;
++		      }
++
++		    /* range_end */
++		    if (*workp < 0)
++		      range_end_char = charset_top - (*workp++);
++		    else
++		      {
++			str_buf[4] = *workp++;
++			range_end_char = str_buf + 4;
++		      }
++
++# ifdef _LIBC
++		    if (__wcscoll (range_start_char, str_buf+2) <= 0
++			&& __wcscoll (str_buf+2, range_end_char) <= 0)
++# else
++		    if (wcscoll (range_start_char, str_buf+2) <= 0
++			&& wcscoll (str_buf+2, range_end_char) <= 0)
++# endif
++		      goto char_set_matched;
++		  }
++	      }
++
++            /* match with char?  */
++	    for (; workp < p ; workp++)
++	      if (c == *workp)
++		goto char_set_matched;
++
++	    negate = !negate;
++
++	  char_set_matched:
++	    if (negate) goto fail;
++#else
++            /* Cast to `unsigned' instead of `unsigned char' in case the
++               bit list is a full 32 bytes long.  */
++	    if (c < (unsigned) (*p * BYTEWIDTH)
++		&& p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
++	      negate = !negate;
++
++	    p += 1 + *p;
++
++	    if (!negate) goto fail;
++#undef WORK_BUFFER_SIZE
++#endif /* WCHAR */
++	    SET_REGS_MATCHED ();
++            d++;
++	    break;
++	  }
++
++
++        /* The beginning of a group is represented by start_memory.
++           The arguments are the register number in the next byte, and the
++           number of groups inner to this one in the next.  The text
++           matched within the group is recorded (in the internal
++           registers data structure) under the register number.  */
++        case start_memory:
++	  DEBUG_PRINT3 ("EXECUTING start_memory %ld (%ld):\n",
++			(long int) *p, (long int) p[1]);
++
++          /* Find out if this group can match the empty string.  */
++	  p1 = p;		/* To send to group_match_null_string_p.  */
++
++          if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
++            REG_MATCH_NULL_STRING_P (reg_info[*p])
++              = PREFIX(group_match_null_string_p) (&p1, pend, reg_info);
++
++          /* Save the position in the string where we were the last time
++             we were at this open-group operator in case the group is
++             operated upon by a repetition operator, e.g., with `(a*)*b'
++             against `ab'; then we want to ignore where we are now in
++             the string in case this attempt to match fails.  */
++          old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
++                             ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
++                             : regstart[*p];
++	  DEBUG_PRINT2 ("  old_regstart: %d\n",
++			 POINTER_TO_OFFSET (old_regstart[*p]));
++
++          regstart[*p] = d;
++	  DEBUG_PRINT2 ("  regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
++
++          IS_ACTIVE (reg_info[*p]) = 1;
++          MATCHED_SOMETHING (reg_info[*p]) = 0;
++
++	  /* Clear this whenever we change the register activity status.  */
++	  set_regs_matched_done = 0;
++
++          /* This is the new highest active register.  */
++          highest_active_reg = *p;
++
++          /* If nothing was active before, this is the new lowest active
++             register.  */
++          if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
++            lowest_active_reg = *p;
++
++          /* Move past the register number and inner group count.  */
++          p += 2;
++	  just_past_start_mem = p;
++
++          break;
++
++
++        /* The stop_memory opcode represents the end of a group.  Its
++           arguments are the same as start_memory's: the register
++           number, and the number of inner groups.  */
++	case stop_memory:
++	  DEBUG_PRINT3 ("EXECUTING stop_memory %ld (%ld):\n",
++			(long int) *p, (long int) p[1]);
++
++          /* We need to save the string position the last time we were at
++             this close-group operator in case the group is operated
++             upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
++             against `aba'; then we want to ignore where we are now in
++             the string in case this attempt to match fails.  */
++          old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
++                           ? REG_UNSET (regend[*p]) ? d : regend[*p]
++			   : regend[*p];
++	  DEBUG_PRINT2 ("      old_regend: %d\n",
++			 POINTER_TO_OFFSET (old_regend[*p]));
++
++          regend[*p] = d;
++	  DEBUG_PRINT2 ("      regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
++
++          /* This register isn't active anymore.  */
++          IS_ACTIVE (reg_info[*p]) = 0;
++
++	  /* Clear this whenever we change the register activity status.  */
++	  set_regs_matched_done = 0;
++
++          /* If this was the only register active, nothing is active
++             anymore.  */
++          if (lowest_active_reg == highest_active_reg)
++            {
++              lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++              highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++            }
++          else
++            { /* We must scan for the new highest active register, since
++                 it isn't necessarily one less than now: consider
++                 (a(b)c(d(e)f)g).  When group 3 ends, after the f), the
++                 new highest active register is 1.  */
++              UCHAR_T r = *p - 1;
++              while (r > 0 && !IS_ACTIVE (reg_info[r]))
++                r--;
++
++              /* If we end up at register zero, that means that we saved
++                 the registers as the result of an `on_failure_jump', not
++                 a `start_memory', and we jumped to past the innermost
++                 `stop_memory'.  For example, in ((.)*) we save
++                 registers 1 and 2 as a result of the *, but when we pop
++                 back to the second ), we are at the stop_memory 1.
++                 Thus, nothing is active.  */
++	      if (r == 0)
++                {
++                  lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++                  highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++                }
++              else
++                highest_active_reg = r;
++            }
++
++          /* If just failed to match something this time around with a
++             group that's operated on by a repetition operator, try to
++             force exit from the ``loop'', and restore the register
++             information for this group that we had before trying this
++             last match.  */
++          if ((!MATCHED_SOMETHING (reg_info[*p])
++               || just_past_start_mem == p - 1)
++	      && (p + 2) < pend)
++            {
++              boolean is_a_jump_n = false;
++
++              p1 = p + 2;
++              mcnt = 0;
++              switch ((re_opcode_t) *p1++)
++                {
++                  case jump_n:
++		    is_a_jump_n = true;
++                  case pop_failure_jump:
++		  case maybe_pop_jump:
++		  case jump:
++		  case dummy_failure_jump:
++                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++		    if (is_a_jump_n)
++		      p1 += OFFSET_ADDRESS_SIZE;
++                    break;
++
++                  default:
++                    /* do nothing */ ;
++                }
++	      p1 += mcnt;
++
++              /* If the next operation is a jump backwards in the pattern
++	         to an on_failure_jump right before the start_memory
++                 corresponding to this stop_memory, exit from the loop
++                 by forcing a failure after pushing on the stack the
++                 on_failure_jump's jump in the pattern, and d.  */
++              if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
++                  && (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == start_memory
++		  && p1[2+OFFSET_ADDRESS_SIZE] == *p)
++		{
++                  /* If this group ever matched anything, then restore
++                     what its registers were before trying this last
++                     failed match, e.g., with `(a*)*b' against `ab' for
++                     regstart[1], and, e.g., with `((a*)*(b*)*)*'
++                     against `aba' for regend[3].
++
++                     Also restore the registers for inner groups for,
++                     e.g., `((a*)(b*))*' against `aba' (register 3 would
++                     otherwise get trashed).  */
++
++                  if (EVER_MATCHED_SOMETHING (reg_info[*p]))
++		    {
++		      unsigned r;
++
++                      EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
++
++		      /* Restore this and inner groups' (if any) registers.  */
++                      for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
++			   r++)
++                        {
++                          regstart[r] = old_regstart[r];
++
++                          /* xx why this test?  */
++                          if (old_regend[r] >= regstart[r])
++                            regend[r] = old_regend[r];
++                        }
++                    }
++		  p1++;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
++
++                  goto fail;
++                }
++            }
++
++          /* Move past the register number and the inner group count.  */
++          p += 2;
++          break;
++
++
++	/* \<digit> has been turned into a `duplicate' command which is
++           followed by the numeric value of <digit> as the register number.  */
++        case duplicate:
++	  {
++	    register const CHAR_T *d2, *dend2;
++	    int regno = *p++;   /* Get which register to match against.  */
++	    DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
++
++	    /* Can't back reference a group which we've never matched.  */
++            if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
++              goto fail;
++
++            /* Where in input to try to start matching.  */
++            d2 = regstart[regno];
++
++            /* Where to stop matching; if both the place to start and
++               the place to stop matching are in the same string, then
++               set to the place to stop, otherwise, for now have to use
++               the end of the first string.  */
++
++            dend2 = ((FIRST_STRING_P (regstart[regno])
++		      == FIRST_STRING_P (regend[regno]))
++		     ? regend[regno] : end_match_1);
++	    for (;;)
++	      {
++		/* If necessary, advance to next segment in register
++                   contents.  */
++		while (d2 == dend2)
++		  {
++		    if (dend2 == end_match_2) break;
++		    if (dend2 == regend[regno]) break;
++
++                    /* End of string1 => advance to string2. */
++                    d2 = string2;
++                    dend2 = regend[regno];
++		  }
++		/* At end of register contents => success */
++		if (d2 == dend2) break;
++
++		/* If necessary, advance to next segment in data.  */
++		PREFETCH ();
++
++		/* How many characters left in this segment to match.  */
++		mcnt = dend - d;
++
++		/* Want how many consecutive characters we can match in
++                   one shot, so, if necessary, adjust the count.  */
++                if (mcnt > dend2 - d2)
++		  mcnt = dend2 - d2;
++
++		/* Compare that many; failure if mismatch, else move
++                   past them.  */
++		if (translate
++                    ? PREFIX(bcmp_translate) (d, d2, mcnt, translate)
++                    : memcmp (d, d2, mcnt*sizeof(UCHAR_T)))
++		  goto fail;
++		d += mcnt, d2 += mcnt;
++
++		/* Do this because we've match some characters.  */
++		SET_REGS_MATCHED ();
++	      }
++	  }
++	  break;
++
++
++        /* begline matches the empty string at the beginning of the string
++           (unless `not_bol' is set in `bufp'), and, if
++           `newline_anchor' is set, after newlines.  */
++	case begline:
++          DEBUG_PRINT1 ("EXECUTING begline.\n");
++
++          if (AT_STRINGS_BEG (d))
++            {
++              if (!bufp->not_bol) break;
++            }
++          else if (d[-1] == '\n' && bufp->newline_anchor)
++            {
++              break;
++            }
++          /* In all other cases, we fail.  */
++          goto fail;
++
++
++        /* endline is the dual of begline.  */
++	case endline:
++          DEBUG_PRINT1 ("EXECUTING endline.\n");
++
++          if (AT_STRINGS_END (d))
++            {
++              if (!bufp->not_eol) break;
++            }
++
++          /* We have to ``prefetch'' the next character.  */
++          else if ((d == end1 ? *string2 : *d) == '\n'
++                   && bufp->newline_anchor)
++            {
++              break;
++            }
++          goto fail;
++
++
++	/* Match at the very beginning of the data.  */
++        case begbuf:
++          DEBUG_PRINT1 ("EXECUTING begbuf.\n");
++          if (AT_STRINGS_BEG (d))
++            break;
++          goto fail;
++
++
++	/* Match at the very end of the data.  */
++        case endbuf:
++          DEBUG_PRINT1 ("EXECUTING endbuf.\n");
++	  if (AT_STRINGS_END (d))
++	    break;
++          goto fail;
++
++
++        /* on_failure_keep_string_jump is used to optimize `.*\n'.  It
++           pushes NULL as the value for the string on the stack.  Then
++           `pop_failure_point' will keep the current value for the
++           string, instead of restoring it.  To see why, consider
++           matching `foo\nbar' against `.*\n'.  The .* matches the foo;
++           then the . fails against the \n.  But the next thing we want
++           to do is match the \n against the \n; if we restored the
++           string value, we would be back at the foo.
++
++           Because this is used only in specific cases, we don't need to
++           check all the things that `on_failure_jump' does, to make
++           sure the right things get saved on the stack.  Hence we don't
++           share its code.  The only reason to push anything on the
++           stack at all is that otherwise we would have to change
++           `anychar's code to do something besides goto fail in this
++           case; that seems worse than this.  */
++        case on_failure_keep_string_jump:
++          DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
++
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++          DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
++#else
++          DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
++#endif
++
++          PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
++          break;
++
++
++	/* Uses of on_failure_jump:
++
++           Each alternative starts with an on_failure_jump that points
++           to the beginning of the next alternative.  Each alternative
++           except the last ends with a jump that in effect jumps past
++           the rest of the alternatives.  (They really jump to the
++           ending jump of the following alternative, because tensioning
++           these jumps is a hassle.)
++
++           Repeats start with an on_failure_jump that points past both
++           the repetition text and either the following jump or
++           pop_failure_jump back to this on_failure_jump.  */
++	case on_failure_jump:
++        on_failure:
++          DEBUG_PRINT1 ("EXECUTING on_failure_jump");
++
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++          DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
++#else
++          DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
++#endif
++
++          /* If this on_failure_jump comes right before a group (i.e.,
++             the original * applied to a group), save the information
++             for that group and all inner ones, so that if we fail back
++             to this point, the group's information will be correct.
++             For example, in \(a*\)*\1, we need the preceding group,
++             and in \(zz\(a*\)b*\)\2, we need the inner group.  */
++
++          /* We can't use `p' to check ahead because we push
++             a failure point to `p + mcnt' after we do this.  */
++          p1 = p;
++
++          /* We need to skip no_op's before we look for the
++             start_memory in case this on_failure_jump is happening as
++             the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
++             against aba.  */
++          while (p1 < pend && (re_opcode_t) *p1 == no_op)
++            p1++;
++
++          if (p1 < pend && (re_opcode_t) *p1 == start_memory)
++            {
++              /* We have a new highest active register now.  This will
++                 get reset at the start_memory we are about to get to,
++                 but we will have saved all the registers relevant to
++                 this repetition op, as described above.  */
++              highest_active_reg = *(p1 + 1) + *(p1 + 2);
++              if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
++                lowest_active_reg = *(p1 + 1);
++            }
++
++          DEBUG_PRINT1 (":\n");
++          PUSH_FAILURE_POINT (p + mcnt, d, -2);
++          break;
++
++
++        /* A smart repeat ends with `maybe_pop_jump'.
++	   We change it to either `pop_failure_jump' or `jump'.  */
++        case maybe_pop_jump:
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++          DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
++          {
++	    register UCHAR_T *p2 = p;
++
++            /* Compare the beginning of the repeat with what in the
++               pattern follows its end. If we can establish that there
++               is nothing that they would both match, i.e., that we
++               would have to backtrack because of (as in, e.g., `a*a')
++               then we can change to pop_failure_jump, because we'll
++               never have to backtrack.
++
++               This is not true in the case of alternatives: in
++               `(a|ab)*' we do need to backtrack to the `ab' alternative
++               (e.g., if the string was `ab').  But instead of trying to
++               detect that here, the alternative has put on a dummy
++               failure point which is what we will end up popping.  */
++
++	    /* Skip over open/close-group commands.
++	       If what follows this loop is a ...+ construct,
++	       look at what begins its body, since we will have to
++	       match at least one of that.  */
++	    while (1)
++	      {
++		if (p2 + 2 < pend
++		    && ((re_opcode_t) *p2 == stop_memory
++			|| (re_opcode_t) *p2 == start_memory))
++		  p2 += 3;
++		else if (p2 + 2 + 2 * OFFSET_ADDRESS_SIZE < pend
++			 && (re_opcode_t) *p2 == dummy_failure_jump)
++		  p2 += 2 + 2 * OFFSET_ADDRESS_SIZE;
++		else
++		  break;
++	      }
++
++	    p1 = p + mcnt;
++	    /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
++	       to the `maybe_finalize_jump' of this case.  Examine what
++	       follows.  */
++
++            /* If we're at the end of the pattern, we can change.  */
++            if (p2 == pend)
++	      {
++		/* Consider what happens when matching ":\(.*\)"
++		   against ":/".  I don't really understand this code
++		   yet.  */
++  	        p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
++		  pop_failure_jump;
++                DEBUG_PRINT1
++                  ("  End of pattern: change to `pop_failure_jump'.\n");
++              }
++
++            else if ((re_opcode_t) *p2 == exactn
++#ifdef MBS_SUPPORT
++		     || (re_opcode_t) *p2 == exactn_bin
++#endif
++		     || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
++	      {
++		register UCHAR_T c
++                  = *p2 == (UCHAR_T) endline ? '\n' : p2[2];
++
++                if (((re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn
++#ifdef MBS_SUPPORT
++		     || (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn_bin
++#endif
++		    ) && p1[3+OFFSET_ADDRESS_SIZE] != c)
++                  {
++  		    p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
++		      pop_failure_jump;
++#ifdef WCHAR
++		      DEBUG_PRINT3 ("  %C != %C => pop_failure_jump.\n",
++				    (wint_t) c,
++				    (wint_t) p1[3+OFFSET_ADDRESS_SIZE]);
++#else
++		      DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",
++				    (char) c,
++				    (char) p1[3+OFFSET_ADDRESS_SIZE]);
++#endif
++                  }
++
++#ifndef WCHAR
++		else if ((re_opcode_t) p1[3] == charset
++			 || (re_opcode_t) p1[3] == charset_not)
++		  {
++		    int negate = (re_opcode_t) p1[3] == charset_not;
++
++		    if (c < (unsigned) (p1[4] * BYTEWIDTH)
++			&& p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
++		      negate = !negate;
++
++                    /* `negate' is equal to 1 if c would match, which means
++                        that we can't change to pop_failure_jump.  */
++		    if (!negate)
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++#endif /* not WCHAR */
++	      }
++#ifndef WCHAR
++            else if ((re_opcode_t) *p2 == charset)
++	      {
++		/* We win if the first character of the loop is not part
++                   of the charset.  */
++                if ((re_opcode_t) p1[3] == exactn
++ 		    && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
++ 			  && (p2[2 + p1[5] / BYTEWIDTH]
++ 			      & (1 << (p1[5] % BYTEWIDTH)))))
++		  {
++		    p[-3] = (unsigned char) pop_failure_jump;
++		    DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                  }
++
++		else if ((re_opcode_t) p1[3] == charset_not)
++		  {
++		    int idx;
++		    /* We win if the charset_not inside the loop
++		       lists every character listed in the charset after.  */
++		    for (idx = 0; idx < (int) p2[1]; idx++)
++		      if (! (p2[2 + idx] == 0
++			     || (idx < (int) p1[4]
++				 && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
++			break;
++
++		    if (idx == p2[1])
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++		else if ((re_opcode_t) p1[3] == charset)
++		  {
++		    int idx;
++		    /* We win if the charset inside the loop
++		       has no overlap with the one after the loop.  */
++		    for (idx = 0;
++			 idx < (int) p2[1] && idx < (int) p1[4];
++			 idx++)
++		      if ((p2[2 + idx] & p1[5 + idx]) != 0)
++			break;
++
++		    if (idx == p2[1] || idx == p1[4])
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++	      }
++#endif /* not WCHAR */
++	  }
++	  p -= OFFSET_ADDRESS_SIZE;	/* Point at relative address again.  */
++	  if ((re_opcode_t) p[-1] != pop_failure_jump)
++	    {
++	      p[-1] = (UCHAR_T) jump;
++              DEBUG_PRINT1 ("  Match => jump.\n");
++	      goto unconditional_jump;
++	    }
++        /* Note fall through.  */
++
++
++	/* The end of a simple repeat has a pop_failure_jump back to
++           its matching on_failure_jump, where the latter will push a
++           failure point.  The pop_failure_jump takes off failure
++           points put on by this pop_failure_jump's matching
++           on_failure_jump; we got through the pattern to here from the
++           matching on_failure_jump, so didn't fail.  */
++        case pop_failure_jump:
++          {
++            /* We need to pass separate storage for the lowest and
++               highest registers, even though we don't care about the
++               actual values.  Otherwise, we will restore only one
++               register from the stack, since lowest will == highest in
++               `pop_failure_point'.  */
++            active_reg_t dummy_low_reg, dummy_high_reg;
++            UCHAR_T *pdummy = NULL;
++            const CHAR_T *sdummy = NULL;
++
++            DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
++            POP_FAILURE_POINT (sdummy, pdummy,
++                               dummy_low_reg, dummy_high_reg,
++                               reg_dummy, reg_dummy, reg_info_dummy);
++          }
++	  /* Note fall through.  */
++
++	unconditional_jump:
++#ifdef _LIBC
++	  DEBUG_PRINT2 ("\n%p: ", p);
++#else
++	  DEBUG_PRINT2 ("\n0x%x: ", p);
++#endif
++          /* Note fall through.  */
++
++        /* Unconditionally jump (without popping any failure points).  */
++        case jump:
++	  EXTRACT_NUMBER_AND_INCR (mcnt, p);	/* Get the amount to jump.  */
++          DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
++	  p += mcnt;				/* Do the jump.  */
++#ifdef _LIBC
++          DEBUG_PRINT2 ("(to %p).\n", p);
++#else
++          DEBUG_PRINT2 ("(to 0x%x).\n", p);
++#endif
++	  break;
++
++
++        /* We need this opcode so we can detect where alternatives end
++           in `group_match_null_string_p' et al.  */
++        case jump_past_alt:
++          DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
++          goto unconditional_jump;
++
++
++        /* Normally, the on_failure_jump pushes a failure point, which
++           then gets popped at pop_failure_jump.  We will end up at
++           pop_failure_jump, also, and with a pattern of, say, `a+', we
++           are skipping over the on_failure_jump, so we have to push
++           something meaningless for pop_failure_jump to pop.  */
++        case dummy_failure_jump:
++          DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
++          /* It doesn't matter what we push for the string here.  What
++             the code at `fail' tests is the value for the pattern.  */
++          PUSH_FAILURE_POINT (NULL, NULL, -2);
++          goto unconditional_jump;
++
++
++        /* At the end of an alternative, we need to push a dummy failure
++           point in case we are followed by a `pop_failure_jump', because
++           we don't want the failure point for the alternative to be
++           popped.  For example, matching `(a|ab)*' against `aab'
++           requires that we match the `ab' alternative.  */
++        case push_dummy_failure:
++          DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
++          /* See comments just above at `dummy_failure_jump' about the
++             two zeroes.  */
++          PUSH_FAILURE_POINT (NULL, NULL, -2);
++          break;
++
++        /* Have to succeed matching what follows at least n times.
++           After that, handle like `on_failure_jump'.  */
++        case succeed_n:
++          EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
++          DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
++
++          assert (mcnt >= 0);
++          /* Originally, this is how many times we HAVE to succeed.  */
++          if (mcnt > 0)
++            {
++               mcnt--;
++	       p += OFFSET_ADDRESS_SIZE;
++               STORE_NUMBER_AND_INCR (p, mcnt);
++#ifdef _LIBC
++               DEBUG_PRINT3 ("  Setting %p to %d.\n", p - OFFSET_ADDRESS_SIZE
++			     , mcnt);
++#else
++               DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p - OFFSET_ADDRESS_SIZE
++			     , mcnt);
++#endif
++            }
++	  else if (mcnt == 0)
++            {
++#ifdef _LIBC
++              DEBUG_PRINT2 ("  Setting two bytes from %p to no_op.\n",
++			    p + OFFSET_ADDRESS_SIZE);
++#else
++              DEBUG_PRINT2 ("  Setting two bytes from 0x%x to no_op.\n",
++			    p + OFFSET_ADDRESS_SIZE);
++#endif /* _LIBC */
++
++#ifdef WCHAR
++	      p[1] = (UCHAR_T) no_op;
++#else
++	      p[2] = (UCHAR_T) no_op;
++              p[3] = (UCHAR_T) no_op;
++#endif /* WCHAR */
++              goto on_failure;
++            }
++          break;
++
++        case jump_n:
++          EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
++          DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
++
++          /* Originally, this is how many times we CAN jump.  */
++          if (mcnt)
++            {
++               mcnt--;
++               STORE_NUMBER (p + OFFSET_ADDRESS_SIZE, mcnt);
++
++#ifdef _LIBC
++               DEBUG_PRINT3 ("  Setting %p to %d.\n", p + OFFSET_ADDRESS_SIZE,
++			     mcnt);
++#else
++               DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p + OFFSET_ADDRESS_SIZE,
++			     mcnt);
++#endif /* _LIBC */
++	       goto unconditional_jump;
++            }
++          /* If don't have to jump any more, skip over the rest of command.  */
++	  else
++	    p += 2 * OFFSET_ADDRESS_SIZE;
++          break;
++
++	case set_number_at:
++	  {
++            DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
++
++            EXTRACT_NUMBER_AND_INCR (mcnt, p);
++            p1 = p + mcnt;
++            EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++            DEBUG_PRINT3 ("  Setting %p to %d.\n", p1, mcnt);
++#else
++            DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p1, mcnt);
++#endif
++	    STORE_NUMBER (p1, mcnt);
++            break;
++          }
++
++#if 0
++	/* The DEC Alpha C compiler 3.x generates incorrect code for the
++	   test  WORDCHAR_P (d - 1) != WORDCHAR_P (d)  in the expansion of
++	   AT_WORD_BOUNDARY, so this code is disabled.  Expanding the
++	   macro and introducing temporary variables works around the bug.  */
++
++	case wordbound:
++	  DEBUG_PRINT1 ("EXECUTING wordbound.\n");
++	  if (AT_WORD_BOUNDARY (d))
++	    break;
++	  goto fail;
++
++	case notwordbound:
++	  DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
++	  if (AT_WORD_BOUNDARY (d))
++	    goto fail;
++	  break;
++#else
++	case wordbound:
++	{
++	  boolean prevchar, thischar;
++
++	  DEBUG_PRINT1 ("EXECUTING wordbound.\n");
++	  if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
++	    break;
++
++	  prevchar = WORDCHAR_P (d - 1);
++	  thischar = WORDCHAR_P (d);
++	  if (prevchar != thischar)
++	    break;
++	  goto fail;
++	}
++
++      case notwordbound:
++	{
++	  boolean prevchar, thischar;
++
++	  DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
++	  if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
++	    goto fail;
++
++	  prevchar = WORDCHAR_P (d - 1);
++	  thischar = WORDCHAR_P (d);
++	  if (prevchar != thischar)
++	    goto fail;
++	  break;
++	}
++#endif
++
++	case wordbeg:
++          DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
++	  if (!AT_STRINGS_END (d) && WORDCHAR_P (d)
++	      && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
++	    break;
++          goto fail;
++
++	case wordend:
++          DEBUG_PRINT1 ("EXECUTING wordend.\n");
++	  if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
++              && (AT_STRINGS_END (d) || !WORDCHAR_P (d)))
++	    break;
++          goto fail;
++
++#ifdef emacs
++  	case before_dot:
++          DEBUG_PRINT1 ("EXECUTING before_dot.\n");
++ 	  if (PTR_CHAR_POS ((unsigned char *) d) >= point)
++  	    goto fail;
++  	  break;
++
++  	case at_dot:
++          DEBUG_PRINT1 ("EXECUTING at_dot.\n");
++ 	  if (PTR_CHAR_POS ((unsigned char *) d) != point)
++  	    goto fail;
++  	  break;
++
++  	case after_dot:
++          DEBUG_PRINT1 ("EXECUTING after_dot.\n");
++          if (PTR_CHAR_POS ((unsigned char *) d) <= point)
++  	    goto fail;
++  	  break;
++
++	case syntaxspec:
++          DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
++	  mcnt = *p++;
++	  goto matchsyntax;
++
++        case wordchar:
++          DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
++	  mcnt = (int) Sword;
++        matchsyntax:
++	  PREFETCH ();
++	  /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
++	  d++;
++	  if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
++	    goto fail;
++          SET_REGS_MATCHED ();
++	  break;
++
++	case notsyntaxspec:
++          DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
++	  mcnt = *p++;
++	  goto matchnotsyntax;
++
++        case notwordchar:
++          DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
++	  mcnt = (int) Sword;
++        matchnotsyntax:
++	  PREFETCH ();
++	  /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
++	  d++;
++	  if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
++	    goto fail;
++	  SET_REGS_MATCHED ();
++          break;
++
++#else /* not emacs */
++	case wordchar:
++          DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
++	  PREFETCH ();
++          if (!WORDCHAR_P (d))
++            goto fail;
++	  SET_REGS_MATCHED ();
++          d++;
++	  break;
++
++	case notwordchar:
++          DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
++	  PREFETCH ();
++	  if (WORDCHAR_P (d))
++            goto fail;
++          SET_REGS_MATCHED ();
++          d++;
++	  break;
++#endif /* not emacs */
++
++        default:
++          abort ();
++	}
++      continue;  /* Successfully executed one pattern command; keep going.  */
++
++
++    /* We goto here if a matching operation fails. */
++    fail:
++      if (!FAIL_STACK_EMPTY ())
++	{ /* A restart point is known.  Restore to that state.  */
++          DEBUG_PRINT1 ("\nFAIL:\n");
++          POP_FAILURE_POINT (d, p,
++                             lowest_active_reg, highest_active_reg,
++                             regstart, regend, reg_info);
++
++          /* If this failure point is a dummy, try the next one.  */
++          if (!p)
++	    goto fail;
++
++          /* If we failed to the end of the pattern, don't examine *p.  */
++	  assert (p <= pend);
++          if (p < pend)
++            {
++              boolean is_a_jump_n = false;
++
++              /* If failed to a backwards jump that's part of a repetition
++                 loop, need to pop this failure point and use the next one.  */
++              switch ((re_opcode_t) *p)
++                {
++                case jump_n:
++                  is_a_jump_n = true;
++                case maybe_pop_jump:
++                case pop_failure_jump:
++                case jump:
++                  p1 = p + 1;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  p1 += mcnt;
++
++                  if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
++                      || (!is_a_jump_n
++                          && (re_opcode_t) *p1 == on_failure_jump))
++                    goto fail;
++                  break;
++                default:
++                  /* do nothing */ ;
++                }
++            }
++
++          if (d >= string1 && d <= end1)
++	    dend = end_match_1;
++        }
++      else
++        break;   /* Matching at this starting point really fails.  */
++    } /* for (;;) */
++
++  if (best_regs_set)
++    goto restore_best_regs;
++
++  FREE_VARIABLES ();
++
++  return -1;         			/* Failure to match.  */
++} /* re_match_2 */
++\f
++/* Subroutine definitions for re_match_2.  */
++
++
++/* We are passed P pointing to a register number after a start_memory.
++
++   Return true if the pattern up to the corresponding stop_memory can
++   match the empty string, and false otherwise.
++
++   If we find the matching stop_memory, sets P to point to one past its number.
++   Otherwise, sets P to an undefined byte less than or equal to END.
++
++   We don't handle duplicates properly (yet).  */
++
++static boolean
++PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
++                                   PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  /* Point to after the args to the start_memory.  */
++  UCHAR_T *p1 = *p + 2;
++
++  while (p1 < end)
++    {
++      /* Skip over opcodes that can match nothing, and return true or
++	 false, as appropriate, when we get to one that can't, or to the
++         matching stop_memory.  */
++
++      switch ((re_opcode_t) *p1)
++        {
++        /* Could be either a loop or a series of alternatives.  */
++        case on_failure_jump:
++          p1++;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++
++          /* If the next operation is not a jump backwards in the
++	     pattern.  */
++
++	  if (mcnt >= 0)
++	    {
++              /* Go through the on_failure_jumps of the alternatives,
++                 seeing if any of the alternatives cannot match nothing.
++                 The last alternative starts with only a jump,
++                 whereas the rest start with on_failure_jump and end
++                 with a jump, e.g., here is the pattern for `a|b|c':
++
++                 /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
++                 /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
++                 /exactn/1/c
++
++                 So, we have to first go through the first (n-1)
++                 alternatives and then deal with the last one separately.  */
++
++
++              /* Deal with the first (n-1) alternatives, which start
++                 with an on_failure_jump (see above) that jumps to right
++                 past a jump_past_alt.  */
++
++              while ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] ==
++		     jump_past_alt)
++                {
++                  /* `mcnt' holds how many bytes long the alternative
++                     is, including the ending `jump_past_alt' and
++                     its number.  */
++
++                  if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt -
++						(1 + OFFSET_ADDRESS_SIZE),
++						reg_info))
++                    return false;
++
++                  /* Move to right after this alternative, including the
++		     jump_past_alt.  */
++                  p1 += mcnt;
++
++                  /* Break if it's the beginning of an n-th alternative
++                     that doesn't begin with an on_failure_jump.  */
++                  if ((re_opcode_t) *p1 != on_failure_jump)
++                    break;
++
++		  /* Still have to check that it's not an n-th
++		     alternative that starts with an on_failure_jump.  */
++		  p1++;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  if ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] !=
++		      jump_past_alt)
++                    {
++		      /* Get to the beginning of the n-th alternative.  */
++                      p1 -= 1 + OFFSET_ADDRESS_SIZE;
++                      break;
++                    }
++                }
++
++              /* Deal with the last alternative: go back and get number
++                 of the `jump_past_alt' just before it.  `mcnt' contains
++                 the length of the alternative.  */
++              EXTRACT_NUMBER (mcnt, p1 - OFFSET_ADDRESS_SIZE);
++
++              if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt, reg_info))
++                return false;
++
++              p1 += mcnt;	/* Get past the n-th alternative.  */
++            } /* if mcnt > 0 */
++          break;
++
++
++        case stop_memory:
++	  assert (p1[1] == **p);
++          *p = p1 + 2;
++          return true;
++
++
++        default:
++          if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
++            return false;
++        }
++    } /* while p1 < end */
++
++  return false;
++} /* group_match_null_string_p */
++
++
++/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
++   It expects P to be the first byte of a single alternative and END one
++   byte past the last. The alternative can contain groups.  */
++
++static boolean
++PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end,
++                                 PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  UCHAR_T *p1 = p;
++
++  while (p1 < end)
++    {
++      /* Skip over opcodes that can match nothing, and break when we get
++         to one that can't.  */
++
++      switch ((re_opcode_t) *p1)
++        {
++	/* It's a loop.  */
++        case on_failure_jump:
++          p1++;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++          p1 += mcnt;
++          break;
++
++	default:
++          if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
++            return false;
++        }
++    }  /* while p1 < end */
++
++  return true;
++} /* alt_match_null_string_p */
++
++
++/* Deals with the ops common to group_match_null_string_p and
++   alt_match_null_string_p.
++
++   Sets P to one after the op and its arguments, if any.  */
++
++static boolean
++PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
++                                       PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  boolean ret;
++  int reg_no;
++  UCHAR_T *p1 = *p;
++
++  switch ((re_opcode_t) *p1++)
++    {
++    case no_op:
++    case begline:
++    case endline:
++    case begbuf:
++    case endbuf:
++    case wordbeg:
++    case wordend:
++    case wordbound:
++    case notwordbound:
++#ifdef emacs
++    case before_dot:
++    case at_dot:
++    case after_dot:
++#endif
++      break;
++
++    case start_memory:
++      reg_no = *p1;
++      assert (reg_no > 0 && reg_no <= MAX_REGNUM);
++      ret = PREFIX(group_match_null_string_p) (&p1, end, reg_info);
++
++      /* Have to set this here in case we're checking a group which
++         contains a group and a back reference to it.  */
++
++      if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
++        REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
++
++      if (!ret)
++        return false;
++      break;
++
++    /* If this is an optimized succeed_n for zero times, make the jump.  */
++    case jump:
++      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++      if (mcnt >= 0)
++        p1 += mcnt;
++      else
++        return false;
++      break;
++
++    case succeed_n:
++      /* Get to the number of times to succeed.  */
++      p1 += OFFSET_ADDRESS_SIZE;
++      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++
++      if (mcnt == 0)
++        {
++          p1 -= 2 * OFFSET_ADDRESS_SIZE;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++          p1 += mcnt;
++        }
++      else
++        return false;
++      break;
++
++    case duplicate:
++      if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
++        return false;
++      break;
++
++    case set_number_at:
++      p1 += 2 * OFFSET_ADDRESS_SIZE;
++
++    default:
++      /* All other opcodes mean we cannot match the empty string.  */
++      return false;
++  }
++
++  *p = p1;
++  return true;
++} /* common_op_match_null_string_p */
++
++
++/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
++   bytes; nonzero otherwise.  */
++
++static int
++PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len,
++                        RE_TRANSLATE_TYPE translate)
++{
++  register const UCHAR_T *p1 = (const UCHAR_T *) s1;
++  register const UCHAR_T *p2 = (const UCHAR_T *) s2;
++  while (len)
++    {
++#ifdef WCHAR
++      if (((*p1<=0xff)?translate[*p1++]:*p1++)
++	  != ((*p2<=0xff)?translate[*p2++]:*p2++))
++	return 1;
++#else /* BYTE */
++      if (translate[*p1++] != translate[*p2++]) return 1;
++#endif /* WCHAR */
++      len--;
++    }
++  return 0;
++}
++\f
++
++#else /* not INSIDE_RECURSION */
++
++/* Entry points for GNU code.  */
++
++/* re_compile_pattern is the GNU regular expression compiler: it
++   compiles PATTERN (of length SIZE) and puts the result in BUFP.
++   Returns 0 if the pattern was valid, otherwise an error string.
++
++   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
++   are set in BUFP on entry.
++
++   We call regex_compile to do the actual compilation.  */
++
++const char *
++re_compile_pattern (const char *pattern, size_t length,
++                    struct re_pattern_buffer *bufp)
++{
++  reg_errcode_t ret;
++
++  /* GNU code is written to assume at least RE_NREGS registers will be set
++     (and at least one extra will be -1).  */
++  bufp->regs_allocated = REGS_UNALLOCATED;
++
++  /* And GNU code determines whether or not to get register information
++     by passing null for the REGS argument to re_match, etc., not by
++     setting no_sub.  */
++  bufp->no_sub = 0;
++
++  /* Match anchors at newline.  */
++  bufp->newline_anchor = 1;
++
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (pattern, length, re_syntax_options, bufp);
++  else
++# endif
++    ret = byte_regex_compile (pattern, length, re_syntax_options, bufp);
++
++  if (!ret)
++    return NULL;
++  return gettext (re_error_msgid[(int) ret]);
++}
++#ifdef _LIBC
++weak_alias (__re_compile_pattern, re_compile_pattern)
++#endif
++\f
++/* Entry points compatible with 4.2 BSD regex library.  We don't define
++   them unless specifically requested.  */
++
++#if defined _REGEX_RE_COMP || defined _LIBC
++
++/* BSD has one and only one pattern buffer.  */
++static struct re_pattern_buffer re_comp_buf;
++
++char *
++#ifdef _LIBC
++/* Make these definitions weak in libc, so POSIX programs can redefine
++   these names if they don't use our functions, and still use
++   regcomp/regexec below without link errors.  */
++weak_function
++#endif
++re_comp (const char *s)
++{
++  reg_errcode_t ret;
++
++  if (!s)
++    {
++      if (!re_comp_buf.buffer)
++	return (char *) gettext ("No previous regular expression");
++      return 0;
++    }
++
++  if (!re_comp_buf.buffer)
++    {
++      re_comp_buf.buffer = (unsigned char *) malloc (200);
++      if (re_comp_buf.buffer == NULL)
++        return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
++      re_comp_buf.allocated = 200;
++
++      re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
++      if (re_comp_buf.fastmap == NULL)
++	return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
++    }
++
++  /* Since `re_exec' always passes NULL for the `regs' argument, we
++     don't need to initialize the pattern buffer fields which affect it.  */
++
++  /* Match anchors at newlines.  */
++  re_comp_buf.newline_anchor = 1;
++
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
++  else
++# endif
++    ret = byte_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
++
++  if (!ret)
++    return NULL;
++
++  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
++  return (char *) gettext (re_error_msgid[(int) ret]);
++}
++
++
++int
++#ifdef _LIBC
++weak_function
++#endif
++re_exec (const char *s)
++{
++  const int len = strlen (s);
++  return
++    0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
++}
++
++#endif /* _REGEX_RE_COMP */
++\f
++/* POSIX.2 functions.  Don't define these for Emacs.  */
++
++#ifndef emacs
++
++/* regcomp takes a regular expression as a string and compiles it.
++
++   PREG is a regex_t *.  We do not expect any fields to be initialized,
++   since POSIX says we shouldn't.  Thus, we set
++
++     `buffer' to the compiled pattern;
++     `used' to the length of the compiled pattern;
++     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
++       REG_EXTENDED bit in CFLAGS is set; otherwise, to
++       RE_SYNTAX_POSIX_BASIC;
++     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
++     `fastmap' to an allocated space for the fastmap;
++     `fastmap_accurate' to zero;
++     `re_nsub' to the number of subexpressions in PATTERN.
++
++   PATTERN is the address of the pattern string.
++
++   CFLAGS is a series of bits which affect compilation.
++
++     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
++     use POSIX basic syntax.
++
++     If REG_NEWLINE is set, then . and [^...] don't match newline.
++     Also, regexec will try a match beginning after every newline.
++
++     If REG_ICASE is set, then we considers upper- and lowercase
++     versions of letters to be equivalent when matching.
++
++     If REG_NOSUB is set, then when PREG is passed to regexec, that
++     routine will report only success or failure, and nothing about the
++     registers.
++
++   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
++   the return codes and their meanings.)  */
++
++int
++regcomp (regex_t *preg, const char *pattern, int cflags)
++{
++  reg_errcode_t ret;
++  reg_syntax_t syntax
++    = (cflags & REG_EXTENDED) ?
++      RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
++
++  /* regex_compile will allocate the space for the compiled pattern.  */
++  preg->buffer = 0;
++  preg->allocated = 0;
++  preg->used = 0;
++
++  /* Try to allocate space for the fastmap.  */
++  preg->fastmap = (char *) malloc (1 << BYTEWIDTH);
++
++  if (cflags & REG_ICASE)
++    {
++      int i;
++
++      preg->translate
++	= (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
++				      * sizeof (*(RE_TRANSLATE_TYPE)0));
++      if (preg->translate == NULL)
++        return (int) REG_ESPACE;
++
++      /* Map uppercase characters to corresponding lowercase ones.  */
++      for (i = 0; i < CHAR_SET_SIZE; i++)
++        preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i;
++    }
++  else
++    preg->translate = NULL;
++
++  /* If REG_NEWLINE is set, newlines are treated differently.  */
++  if (cflags & REG_NEWLINE)
++    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
++      syntax &= ~RE_DOT_NEWLINE;
++      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
++      /* It also changes the matching behavior.  */
++      preg->newline_anchor = 1;
++    }
++  else
++    preg->newline_anchor = 0;
++
++  preg->no_sub = !!(cflags & REG_NOSUB);
++
++  /* POSIX says a null character in the pattern terminates it, so we
++     can use strlen here in compiling the pattern.  */
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (pattern, strlen (pattern), syntax, preg);
++  else
++# endif
++    ret = byte_regex_compile (pattern, strlen (pattern), syntax, preg);
++
++  /* POSIX doesn't distinguish between an unmatched open-group and an
++     unmatched close-group: both are REG_EPAREN.  */
++  if (ret == REG_ERPAREN) ret = REG_EPAREN;
++
++  if (ret == REG_NOERROR && preg->fastmap)
++    {
++      /* Compute the fastmap now, since regexec cannot modify the pattern
++	 buffer.  */
++      if (re_compile_fastmap (preg) == -2)
++	{
++	  /* Some error occurred while computing the fastmap, just forget
++	     about it.  */
++	  free (preg->fastmap);
++	  preg->fastmap = NULL;
++	}
++    }
++
++  return (int) ret;
++}
++#ifdef _LIBC
++weak_alias (__regcomp, regcomp)
++#endif
++
++
++/* regexec searches for a given pattern, specified by PREG, in the
++   string STRING.
++
++   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
++   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
++   least NMATCH elements, and we set them to the offsets of the
++   corresponding matched substrings.
++
++   EFLAGS specifies `execution flags' which affect matching: if
++   REG_NOTBOL is set, then ^ does not match at the beginning of the
++   string; if REG_NOTEOL is set, then $ does not match at the end.
++
++   We return 0 if we find a match and REG_NOMATCH if not.  */
++
++int
++regexec (const regex_t *preg, const char *string, size_t nmatch,
++         regmatch_t pmatch[], int eflags)
++{
++  int ret;
++  struct re_registers regs;
++  regex_t private_preg;
++  int len = strlen (string);
++  boolean want_reg_info = !preg->no_sub && nmatch > 0;
++
++  private_preg = *preg;
++
++  private_preg.not_bol = !!(eflags & REG_NOTBOL);
++  private_preg.not_eol = !!(eflags & REG_NOTEOL);
++
++  /* The user has told us exactly how many registers to return
++     information about, via `nmatch'.  We have to pass that on to the
++     matching routines.  */
++  private_preg.regs_allocated = REGS_FIXED;
++
++  if (want_reg_info)
++    {
++      regs.num_regs = nmatch;
++      regs.start = TALLOC (nmatch * 2, regoff_t);
++      if (regs.start == NULL)
++        return (int) REG_NOMATCH;
++      regs.end = regs.start + nmatch;
++    }
++
++  /* Perform the searching operation.  */
++  ret = re_search (&private_preg, string, len,
++                   /* start: */ 0, /* range: */ len,
++                   want_reg_info ? &regs : (struct re_registers *) 0);
++
++  /* Copy the register information to the POSIX structure.  */
++  if (want_reg_info)
++    {
++      if (ret >= 0)
++        {
++          unsigned r;
++
++          for (r = 0; r < nmatch; r++)
++            {
++              pmatch[r].rm_so = regs.start[r];
++              pmatch[r].rm_eo = regs.end[r];
++            }
++        }
++
++      /* If we needed the temporary register info, free the space now.  */
++      free (regs.start);
++    }
++
++  /* We want zero return to mean success, unlike `re_search'.  */
++  return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
++}
++#ifdef _LIBC
++/* EGLIBC: This is handled in regexec-compat.c.  */
++/*weak_alias (__regexec, regexec)*/
++#include "regexec-compat.c"
++#endif
++
++
++/* Returns a message corresponding to an error code, ERRCODE, returned
++   from either regcomp or regexec.   We don't use PREG here.  */
++
++size_t
++regerror (int errcode, const regex_t *preg __attribute__ ((unused)),
++          char *errbuf, size_t errbuf_size)
++{
++  const char *msg;
++  size_t msg_size;
++
++  if (errcode < 0
++      || errcode >= (int) (sizeof (re_error_msgid)
++			   / sizeof (re_error_msgid[0])))
++    /* Only error codes returned by the rest of the code should be passed
++       to this routine.  If we are given anything else, or if other regex
++       code generates an invalid error code, then the program has a bug.
++       Dump core so we can fix it.  */
++    abort ();
++
++  msg = gettext (re_error_msgid[errcode]);
++
++  msg_size = strlen (msg) + 1; /* Includes the null.  */
++
++  if (errbuf_size != 0)
++    {
++      if (msg_size > errbuf_size)
++        {
++#if defined HAVE_MEMPCPY || defined _LIBC
++	  *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
++#else
++          memcpy (errbuf, msg, errbuf_size - 1);
++          errbuf[errbuf_size - 1] = 0;
++#endif
++        }
++      else
++        memcpy (errbuf, msg, msg_size);
++    }
++
++  return msg_size;
++}
++#ifdef _LIBC
++weak_alias (__regerror, regerror)
++#endif
++
++
++/* Free dynamically allocated space used by PREG.  */
++
++void
++regfree (regex_t *preg)
++{
++  if (preg->buffer != NULL)
++    free (preg->buffer);
++  preg->buffer = NULL;
++
++  preg->allocated = 0;
++  preg->used = 0;
++
++  if (preg->fastmap != NULL)
++    free (preg->fastmap);
++  preg->fastmap = NULL;
++  preg->fastmap_accurate = 0;
++
++  if (preg->translate != NULL)
++    free (preg->translate);
++  preg->translate = NULL;
++}
++#ifdef _LIBC
++weak_alias (__regfree, regfree)
++#endif
++
++#endif /* not emacs  */
++
++#endif /* not INSIDE_RECURSION */
++
++\f
++#undef STORE_NUMBER
++#undef STORE_NUMBER_AND_INCR
++#undef EXTRACT_NUMBER
++#undef EXTRACT_NUMBER_AND_INCR
++
++#undef DEBUG_PRINT_COMPILED_PATTERN
++#undef DEBUG_PRINT_DOUBLE_STRING
++
++#undef INIT_FAIL_STACK
++#undef RESET_FAIL_STACK
++#undef DOUBLE_FAIL_STACK
++#undef PUSH_PATTERN_OP
++#undef PUSH_FAILURE_POINTER
++#undef PUSH_FAILURE_INT
++#undef PUSH_FAILURE_ELT
++#undef POP_FAILURE_POINTER
++#undef POP_FAILURE_INT
++#undef POP_FAILURE_ELT
++#undef DEBUG_PUSH
++#undef DEBUG_POP
++#undef PUSH_FAILURE_POINT
++#undef POP_FAILURE_POINT
++
++#undef REG_UNSET_VALUE
++#undef REG_UNSET
++
++#undef PATFETCH
++#undef PATFETCH_RAW
++#undef PATUNFETCH
++#undef TRANSLATE
++
++#undef INIT_BUF_SIZE
++#undef GET_BUFFER_SPACE
++#undef BUF_PUSH
++#undef BUF_PUSH_2
++#undef BUF_PUSH_3
++#undef STORE_JUMP
++#undef STORE_JUMP2
++#undef INSERT_JUMP
++#undef INSERT_JUMP2
++#undef EXTEND_BUFFER
++#undef GET_UNSIGNED_NUMBER
++#undef FREE_STACK_RETURN
++
++# undef POINTER_TO_OFFSET
++# undef MATCHING_IN_FRST_STRING
++# undef PREFETCH
++# undef AT_STRINGS_BEG
++# undef AT_STRINGS_END
++# undef WORDCHAR_P
++# undef FREE_VAR
++# undef FREE_VARIABLES
++# undef NO_HIGHEST_ACTIVE_REG
++# undef NO_LOWEST_ACTIVE_REG
++
++# undef CHAR_T
++# undef UCHAR_T
++# undef COMPILED_BUFFER_VAR
++# undef OFFSET_ADDRESS_SIZE
++# undef CHAR_CLASS_SIZE
++# undef PREFIX
++# undef ARG_PREFIX
++# undef PUT_CHAR
++# undef BYTE
++# undef WCHAR
++
++# define DEFINED_ONCE
+diff -Naur glibc-2.20/pwd/Makefile glibc-2.20-patch/pwd/Makefile
+--- glibc-2.20/pwd/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/pwd/Makefile	2015-03-04 00:51:32.416952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for pwd portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= pwd
+ 
+ include ../Makeconfig
+diff -Naur glibc-2.20/resolv/Makefile glibc-2.20-patch/resolv/Makefile
+--- glibc-2.20/resolv/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/resolv/Makefile	2015-03-04 00:51:32.416952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for resolv portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= resolv
+ 
+ include ../Makeconfig
+@@ -27,20 +29,21 @@
+ 	   arpa/nameser.h arpa/nameser_compat.h \
+ 	   sys/bitypes.h
+ 
+-routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
+-	    res_hconf res_libc res-state
++routines-$(OPTION_EGLIBC_INET) \
++	+= herror inet_addr inet_ntop inet_pton nsap_addr res_init \
++	   res_hconf res_libc res-state
+ 
+-tests = tst-aton tst-leaks tst-inet_ntop
+-xtests = tst-leaks2
++tests-$(OPTION_EGLIBC_INET) += tst-aton tst-leaks tst-inet_ntop
++xtests-$(OPTION_EGLIBC_INET) += tst-leaks2
+ 
+ generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
+ 
+-extra-libs := libresolv libnss_dns
++extra-libs-$(OPTION_EGLIBC_INET) += libresolv libnss_dns
+ ifeq ($(have-thread-library),yes)
+-extra-libs += libanl
+-routines += gai_sigqueue
++extra-libs-$(OPTION_EGLIBC_INET_ANL) += libanl
++routines-$(OPTION_EGLIBC_INET) += gai_sigqueue
+ endif
+-extra-libs-others = $(extra-libs)
++extra-libs-others-y += $(extra-libs-y)
+ libresolv-routines := gethnamaddr res_comp res_debug	\
+ 		      res_data res_mkquery res_query res_send		\
+ 		      inet_net_ntop inet_net_pton inet_neta base64	\
+@@ -60,7 +63,7 @@
+ static-only-routines    += $(libnss_dns-routines) $(libresolv-routines)
+ endif
+ 
+-ifeq (yesyes,$(build-shared)$(have-thread-library))
++ifeq (yesyesy,$(build-shared)$(have-thread-library)$(OPTION_EGLIBC_INET_ANL))
+ tests: $(objpfx)ga_test
+ endif
+ 
+diff -Naur glibc-2.20/stdio-common/fxprintf.c glibc-2.20-patch/stdio-common/fxprintf.c
+--- glibc-2.20/stdio-common/fxprintf.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/fxprintf.c	2015-03-04 00:51:32.416952006 -0600
+@@ -23,6 +23,7 @@
+ #include <wchar.h>
+ #include <string.h>
+ #include <libioP.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -37,6 +38,7 @@
+   int res;
+   if (_IO_fwide (fp, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       size_t len = strlen (fmt) + 1;
+       wchar_t wfmt[len];
+       for (size_t i = 0; i < len; ++i)
+@@ -45,6 +47,9 @@
+ 	  wfmt[i] = fmt[i];
+ 	}
+       res = __vfwprintf (fp, wfmt, ap);
++#else
++      abort();
++#endif
+     }
+   else
+     res = _IO_vfprintf (fp, fmt, ap);
+diff -Naur glibc-2.20/stdio-common/_i18n_number.h glibc-2.20-patch/stdio-common/_i18n_number.h
+--- glibc-2.20/stdio-common/_i18n_number.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/_i18n_number.h	2015-03-04 00:51:32.417952006 -0600
+@@ -19,10 +19,13 @@
+ #include <stdbool.h>
+ #include <wchar.h>
+ #include <wctype.h>
++#include <gnu/option-groups.h>
+ 
+ #include "../locale/outdigits.h"
+ #include "../locale/outdigitswc.h"
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
++
+ static CHAR_T *
+ _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
+ {
+@@ -115,3 +118,13 @@
+ 
+   return w;
+ }
++
++#else
++
++static CHAR_T *
++_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
++{
++  return w;
++}
++
++#endif
+diff -Naur glibc-2.20/stdio-common/Makefile glibc-2.20-patch/stdio-common/Makefile
+--- glibc-2.20/stdio-common/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/Makefile	2015-03-04 00:51:32.417952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Specific makefile for stdio-common.
+ #
++include ../option-groups.mak
++
+ subdir	:= stdio-common
+ 
+ include ../Makeconfig
+@@ -30,7 +32,7 @@
+ 	vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex	      \
+ 	reg-modifier reg-type						      \
+ 	printf_size fprintf printf snprintf sprintf asprintf dprintf	      \
+-	vfwprintf vfscanf vfwscanf					      \
++	vfscanf								      \
+ 	fscanf scanf sscanf						      \
+ 	perror psignal							      \
+ 	tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname		      \
+@@ -41,23 +43,37 @@
+ 	isoc99_vsscanf							      \
+ 	psiginfo
+ 
+-aux	:= errlist siglist printf-parsemb printf-parsewc fxprintf
++# Ideally, _itowa and itowa-digits would be in this option group as
++# well, but it is used unconditionally by printf_fp and printf_fphex,
++# and it didn't seem straightforward to disentangle it.
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	vfwprintf vfwscanf
++
++aux    := errlist siglist printf-parsemb fxprintf
++aux-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += printf-parsewc
+ 
+ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
+ 	 temptest tst-fileno test-fwrite tst-ungetc tst-ferror \
+ 	 xbug errnobug \
+ 	 bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \
+-	 tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \
++	 tfformat tiformat tllformat tstdiomisc tst-printfsz \
+ 	 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \
+-	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
+-	 tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
+-	 tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \
++	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
++	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
++	 tst-fseek tst-fmemopen tst-gets \
++	 tst-sprintf tst-rndseek tst-fdopen tst-fphex \
+ 	 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
+-	 tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
+-	 bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
+-	 scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
+-	 bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
+-	 bug25 tst-printf-round bug26
++	 tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
++	 bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17 \
++	 tst-setvbuf1 bug23 bug24 bug-vfprintf-nargs tst-sprintf3 bug25 \
++	 tst-printf-round bug26
++
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++      += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
++      += tst-perror bug19a bug20 tst-long-dbl-fphex tst-fphex-wide
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++      += bug18a tst-swscanf tst-wc-printf
+ 
+ test-srcs = tst-unbputc tst-printf
+ 
+diff -Naur glibc-2.20/stdio-common/printf_fp.c glibc-2.20-patch/stdio-common/printf_fp.c
+--- glibc-2.20/stdio-common/printf_fp.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/printf_fp.c	2015-03-04 00:51:32.417952006 -0600
+@@ -39,6 +39,7 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ #include <stdbool.h>
+ #include <rounding-mode.h>
+ 
+@@ -148,6 +149,10 @@
+ 			      wchar_t thousands_sep, int ngroups)
+      internal_function;
+ 
++/* Ideally, when OPTION_EGLIBC_LOCALE_CODE is disabled, this should do
++   all its work in ordinary characters, rather than doing it in wide
++   characters and then converting at the end.  But that is a challenge
++   for another day.  */
+ 
+ int
+ ___printf_fp (FILE *fp,
+@@ -206,7 +211,14 @@
+   mp_limb_t cy;
+ 
+   /* Nonzero if this is output on a wide character stream.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+ 
+   /* Buffer in which we produce the output.  */
+   wchar_t *wbuffer = NULL;
+@@ -258,6 +270,7 @@
+ 
+ 
+   /* Figure out the decimal point character.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->extra == 0)
+     {
+       decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+@@ -277,7 +290,13 @@
+   /* The decimal point character must not be zero.  */
+   assert (*decimal != '\0');
+   assert (decimalwc != L'\0');
++#else
++  /* Hard-code values from 'C' locale.  */
++  decimal = ".";
++  decimalwc = L'.';
++#endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->group)
+     {
+       if (info->extra == 0)
+@@ -321,6 +340,9 @@
+     }
+   else
+     grouping = NULL;
++#else
++  grouping = NULL;
++#endif
+ 
+   /* Fetch the argument value.	*/
+ #ifndef __NO_LONG_DOUBLE_MATH
+diff -Naur glibc-2.20/stdio-common/printf_fphex.c glibc-2.20-patch/stdio-common/printf_fphex.c
+--- glibc-2.20/stdio-common/printf_fphex.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/printf_fphex.c	2015-03-04 00:51:32.418952006 -0600
+@@ -28,6 +28,7 @@
+ #include <_itoa.h>
+ #include <_itowa.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ #include <stdbool.h>
+ #include <rounding-mode.h>
+ 
+@@ -139,10 +140,18 @@
+   int done = 0;
+ 
+   /* Nonzero if this is output on a wide character stream.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+ 
+ 
+   /* Figure out the decimal point character.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->extra == 0)
+     {
+       decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+@@ -156,6 +165,10 @@
+     }
+   /* The decimal point character must never be zero.  */
+   assert (*decimal != '\0' && decimalwc != L'\0');
++#else
++  decimal = ".";
++  decimalwc = L'.';
++#endif
+ 
+ 
+   /* Fetch the argument value.	*/
+diff -Naur glibc-2.20/stdio-common/printf_size.c glibc-2.20-patch/stdio-common/printf_size.c
+--- glibc-2.20/stdio-common/printf_size.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/printf_size.c	2015-03-04 00:51:32.418952006 -0600
+@@ -23,6 +23,7 @@
+ #include <math.h>
+ #include <printf.h>
+ #include <libioP.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ /* This defines make it possible to use the same code for GNU C library and
+@@ -116,7 +117,14 @@
+ 
+   struct printf_info fp_info;
+   int done = 0;
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+   int res;
+ 
+   /* Fetch the argument value.	*/
+diff -Naur glibc-2.20/stdio-common/scanf14.c glibc-2.20-patch/stdio-common/scanf14.c
+--- glibc-2.20/stdio-common/scanf14.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/scanf14.c	2015-03-04 00:51:32.418952006 -0600
+@@ -2,6 +2,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ #define FAIL() \
+   do {							\
+@@ -36,6 +37,7 @@
+     FAIL ();
+   else if (d != 2.25 || memcmp (c, " x", 2) != 0)
+     FAIL ();
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2)
+     FAIL ();
+   else
+@@ -45,6 +47,7 @@
+       memset (lsp, 'x', sizeof L"3.25");
+       free (lsp);
+     }
++#endif
+   if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2)
+     FAIL ();
+   else
+diff -Naur glibc-2.20/stdio-common/tstdiomisc.c glibc-2.20-patch/stdio-common/tstdiomisc.c
+--- glibc-2.20/stdio-common/tstdiomisc.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/tstdiomisc.c	2015-03-04 00:51:32.418952006 -0600
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ t1 (void)
+@@ -125,6 +126,7 @@
+   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+ 	  buf);
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
+ 	    qnanval, qnanval, qnanval, qnanval,
+ 	    qnanval, qnanval, qnanval, qnanval);
+@@ -162,6 +164,7 @@
+   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+ 	  wbuf);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   lqnanval = NAN;
+ 
+@@ -206,6 +209,7 @@
+   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+ 	  buf);
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
+ 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
+ 	    lqnanval, lqnanval, lqnanval, lqnanval,
+@@ -250,6 +254,7 @@
+   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+ 	  wbuf);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   return result;
+ }
+diff -Naur glibc-2.20/stdio-common/tst-popen.c glibc-2.20-patch/stdio-common/tst-popen.c
+--- glibc-2.20/stdio-common/tst-popen.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/tst-popen.c	2015-03-04 00:51:32.419952006 -0600
+@@ -19,6 +19,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ do_test (void)
+@@ -34,12 +35,14 @@
+       return 1;
+     }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+   /* POSIX says that pipe streams are byte-oriented.  */
+   if (fwide (f, 0) >= 0)
+     {
+       puts ("popen did not return byte-oriented stream");
+       result = 1;
+     }
++#endif
+ 
+   if (getline (&line, &len, f) != 5)
+     {
+diff -Naur glibc-2.20/stdio-common/tst-sprintf.c glibc-2.20-patch/stdio-common/tst-sprintf.c
+--- glibc-2.20/stdio-common/tst-sprintf.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/tst-sprintf.c	2015-03-04 00:51:32.419952006 -0600
+@@ -2,6 +2,7 @@
+ #include <stdlib.h>
+ #include <locale.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -10,12 +11,14 @@
+   char buf[100];
+   int result = 0;
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (sprintf (buf, "%.0ls", L"foo") != 0
+       || strlen (buf) != 0)
+     {
+       puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output");
+       result = 1;
+     }
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+ #define SIZE (1024*70000)
+ #define STR(x) #x
+diff -Naur glibc-2.20/stdio-common/vfprintf.c glibc-2.20-patch/stdio-common/vfprintf.c
+--- glibc-2.20/stdio-common/vfprintf.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/vfprintf.c	2015-03-04 00:51:32.419952006 -0600
+@@ -29,6 +29,7 @@
+ #include <_itoa.h>
+ #include <locale/localeinfo.h>
+ #include <stdio.h>
++#include <gnu/option-groups.h>
+ 
+ /* This code is shared between the standard stdio implementation found
+    in GNU C library and the libio implementation originally found in
+@@ -138,6 +139,18 @@
+ # define EOF WEOF
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define MULTIBYTE_SUPPORT (1)
++#else
++# define MULTIBYTE_SUPPORT (0)
++#endif
++
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define LOCALE_SUPPORT (1)
++#else
++# define LOCALE_SUPPORT (0)
++#endif
++
+ #include "_i18n_number.h"
+ 
+ /* Include the shared code for parsing the format string.  */
+@@ -1123,8 +1136,11 @@
+ # define process_string_arg(fspec) \
+     LABEL (form_character):						      \
+       /* Character.  */							      \
+-      if (is_long)							      \
+-	goto LABEL (form_wcharacter);					      \
++      if (is_long)                                                            \
++        {                                                                     \
++          assert (MULTIBYTE_SUPPORT);                                         \
++          goto LABEL (form_wcharacter);                                       \
++        }                                                                     \
+       --width;	/* Account for the character itself.  */		      \
+       if (!left)							      \
+ 	PAD (' ');							      \
+@@ -1137,6 +1153,7 @@
+       break;								      \
+ 									      \
+     LABEL (form_wcharacter):						      \
++      assert (MULTIBYTE_SUPPORT);                                             \
+       {									      \
+ 	/* Wide character.  */						      \
+ 	char buf[MB_CUR_MAX];						      \
+@@ -1203,6 +1220,7 @@
+ 	  }								      \
+ 	else								      \
+ 	  {								      \
++            assert (MULTIBYTE_SUPPORT);                                       \
+ 	    const wchar_t *s2 = (const wchar_t *) string;		      \
+ 	    mbstate_t mbstate;						      \
+ 									      \
+@@ -1403,7 +1421,9 @@
+     LABEL (flag_quote):
+       group = 1;
+ 
+-      if (grouping == (const char *) -1)
++      if (! LOCALE_SUPPORT)
++        grouping = NULL;
++      else if (grouping == (const char *) -1)
+ 	{
+ #ifdef COMPILE_WPRINTF
+ 	  thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+@@ -1702,7 +1722,9 @@
+       free (workstart);
+     workstart = NULL;
+ 
+-    if (grouping == (const char *) -1)
++    if (! LOCALE_SUPPORT)
++      grouping = NULL;
++    else if (grouping == (const char *) -1)
+       {
+ #ifdef COMPILE_WPRINTF
+ 	thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+diff -Naur glibc-2.20/stdio-common/vfscanf.c glibc-2.20-patch/stdio-common/vfscanf.c
+--- glibc-2.20/stdio-common/vfscanf.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdio-common/vfscanf.c	2015-03-04 00:51:32.420952006 -0600
+@@ -29,6 +29,7 @@
+ #include <wctype.h>
+ #include <bits/libc-lock.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ 
+ #ifdef	__GNUC__
+ # define HAVE_LONGLONG
+@@ -133,6 +134,12 @@
+ # define WINT_T		int
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define MULTIBYTE_SUPPORT (1)
++#else
++# define MULTIBYTE_SUPPORT (0)
++#endif
++
+ #define encode_error() do {						      \
+ 			  errval = 4;					      \
+ 			  __set_errno (EILSEQ);				      \
+@@ -316,24 +323,35 @@
+   ARGCHECK (s, format);
+ 
+  {
+-#ifndef COMPILE_WSCANF
++#if __OPTION_EGLIBC_LOCALE_CODE && !defined (COMPILE_WSCANF)
+    struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
+ #endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+    /* Figure out the decimal point character.  */
+-#ifdef COMPILE_WSCANF
++# ifdef COMPILE_WSCANF
+    decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
+-#else
++# else
+    decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
+-#endif
++# endif
+    /* Figure out the thousands separator character.  */
+-#ifdef COMPILE_WSCANF
++# ifdef COMPILE_WSCANF
+    thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
+-#else
++# else
+    thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
+    if (*thousands == '\0')
+      thousands = NULL;
+-#endif
++# endif
++#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
++   /* Hard-code values from the C locale.  */
++# ifdef COMPILE_WSCANF
++   decimal = L'.';
++   thousands = L'\0';
++# else
++   decimal = ".";
++   thousands = NULL;
++# endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+  }
+ 
+   /* Lock the stream.  */
+@@ -385,6 +403,8 @@
+ #ifndef COMPILE_WSCANF
+       if (!isascii ((unsigned char) *f))
+ 	{
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  /* Non-ASCII, may be a multibyte.  */
+ 	  int len = __mbrlen (f, strlen (f), &state);
+ 	  if (len > 0)
+@@ -830,6 +850,8 @@
+ 	    }
+ 	  /* FALLTHROUGH */
+ 	case L_('C'):
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  if (width == -1)
+ 	    width = 1;
+ 
+@@ -1172,6 +1194,8 @@
+ 	  /* FALLTHROUGH */
+ 
+ 	case L_('S'):
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  {
+ #ifndef COMPILE_WSCANF
+ 	    mbstate_t cstate;
+@@ -1419,10 +1443,17 @@
+ 	      const char *mbdigits[10];
+ 	      const char *mbdigits_extended[10];
+ #endif
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	      /*  "to_inpunct" is a map from ASCII digits to their
+ 		  equivalent in locale. This is defined for locales
+ 		  which use an extra digits set.  */
+ 	      wctrans_t map = __wctrans ("to_inpunct");
++#else
++              /* This will always be the case when
++                 OPTION_EGLIBC_LOCALE_CODE is disabled, but the
++                 compiler can't figure that out.  */
++              wctrans_t map = NULL;
++#endif
+ 	      int n;
+ 
+ 	      from_level = 0;
+@@ -2088,6 +2119,7 @@
+ 		--width;
+ 	    }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	  wctrans_t map;
+ 	  if (__builtin_expect ((flags & I18N) != 0, 0)
+ 	      /* Hexadecimal floats make no sense, fixing localized
+@@ -2304,6 +2336,7 @@
+ 	      ;
+ #endif
+ 	    }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 
+ 	  /* Have we read any character?  If we try to read a number
+ 	     in hexadecimal notation and we have read only the `0x'
+@@ -2343,7 +2376,10 @@
+ 
+ 	case L_('['):	/* Character class.  */
+ 	  if (flags & LONG)
+-	    STRING_ARG (wstr, wchar_t, 100);
++            {
++              assert (MULTIBYTE_SUPPORT);
++              STRING_ARG (wstr, wchar_t, 100);
++            }
+ 	  else
+ 	    STRING_ARG (str, char, 100);
+ 
+@@ -2417,6 +2453,7 @@
+ 	  if (flags & LONG)
+ 	    {
+ 	      size_t now = read_in;
++              assert (MULTIBYTE_SUPPORT);
+ #ifdef COMPILE_WSCANF
+ 	      if (__glibc_unlikely (inchar () == WEOF))
+ 		input_error ();
+diff -Naur glibc-2.20/stdlib/Makefile glibc-2.20-patch/stdlib/Makefile
+--- glibc-2.20/stdlib/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdlib/Makefile	2015-03-04 00:51:32.420952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for stdlib routines
+ #
++include ../option-groups.mak
++
+ subdir	:= stdlib
+ 
+ include ../Makeconfig
+@@ -30,7 +32,7 @@
+ 	   alloca.h fmtmsg.h						      \
+ 	   bits/stdlib-bsearch.h
+ 
+-routines	:=							      \
++routines-y	:=							      \
+ 	atof atoi atol atoll						      \
+ 	abort								      \
+ 	bsearch qsort msort						      \
+@@ -39,7 +41,6 @@
+ 	quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl     \
+ 	abs labs llabs							      \
+ 	div ldiv lldiv							      \
+-	mblen mbstowcs mbtowc wcstombs wctomb				      \
+ 	random random_r rand rand_r					      \
+ 	drand48 erand48 lrand48 nrand48 mrand48 jrand48			      \
+ 	srand48 seed48 lcong48						      \
+@@ -52,9 +53,18 @@
+ 	strtof_l strtod_l strtold_l					      \
+ 	system canonicalize						      \
+ 	a64l l64a							      \
+-	rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg		      \
+-	strtoimax strtoumax wcstoimax wcstoumax				      \
++	getsubopt xpg_basename						      \
++	strtoimax strtoumax						      \
+ 	getcontext setcontext makecontext swapcontext
++routines-$(OPTION_EGLIBC_LOCALE_CODE) +=				      \
++	strfmon strfmon_l
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	mblen mbstowcs mbtowc wcstombs wctomb				      \
++	wcstoimax wcstoumax
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP))
++routines-y += rpmatch
++endif
++routines-$(OPTION_EGLIBC_FMTMSG) += fmtmsg
+ aux =	grouping groupingwc tens_in_limb
+ 
+ # These routines will be omitted from the libc shared object.
+@@ -62,20 +72,22 @@
+ # linked against when the shared library will be used.
+ static-only-routines = atexit at_quick_exit
+ 
+-test-srcs	:= tst-fmtmsg
+-tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
++test-srcs-$(OPTION_EGLIBC_FMTMSG) := tst-fmtmsg
++tests		:= tst-strtol tst-strtod testrand testsort testdiv          \
+ 		   test-canon test-canon2 tst-strtoll tst-environ	    \
+ 		   tst-xpg-basename tst-random tst-random2 tst-bsearch	    \
+ 		   tst-limits tst-rand48 bug-strtod tst-setcontext	    \
+-		   test-a64l tst-qsort tst-system testmb2 bug-strtod2	    \
+-		   tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
+-		   tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2	    \
+-		   tst-makecontext2 tst-strtod6 tst-unsetenv1		    \
+-		   tst-makecontext3 bug-getcontext bug-fmtmsg1		    \
++		   test-a64l tst-qsort tst-system bug-strtod2		    \
++		   tst-atof1 tst-atof2 tst-strtod2 tst-rand48-2             \
++		   tst-makecontext tst-qsort2 tst-makecontext2 tst-strtod6  \
++		   tst-unsetenv1 tst-makecontext3 bug-getcontext bug-fmtmsg1 \
+ 		   tst-secure-getenv tst-strtod-overflow tst-strtod-round   \
+ 		   tst-tininess tst-strtod-underflow tst-tls-atexit
+ tests-static	:= tst-secure-getenv
+-
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= tst-strtod3 tst-strtod4 tst-strtod5 testmb2
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++		+= testmb
+ modules-names	= tst-tls-atexit-lib
+ 
+ ifeq ($(build-shared),yes)
+@@ -115,8 +127,10 @@
+ tests-special += $(objpfx)isomac.out
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_EGLIBC_FMTMSG))
+ tests-special += $(objpfx)tst-fmtmsg.out
+ endif
++endif
+ 
+ include ../Rules
+ 
+diff -Naur glibc-2.20/stdlib/strtod_l.c glibc-2.20-patch/stdlib/strtod_l.c
+--- glibc-2.20/stdlib/strtod_l.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdlib/strtod_l.c	2015-03-04 00:51:32.420952006 -0600
+@@ -17,6 +17,7 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
+ #include <xlocale.h>
+ 
+ extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
+@@ -548,6 +549,7 @@
+   /* Used in several places.  */
+   int cnt;
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   struct __locale_data *current = loc->__locales[LC_NUMERIC];
+ 
+   if (__glibc_unlikely (group))
+@@ -586,6 +588,17 @@
+   decimal_len = strlen (decimal);
+   assert (decimal_len > 0);
+ #endif
++#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
++  /* Hard-code values from the 'C' locale.  */
++  grouping = NULL;
++#ifdef USE_WIDE_CHAR
++  decimal = L'.';
++# define decimal_len 1
++#else
++  decimal = ".";
++  decimal_len = 1;
++#endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 
+   /* Prepare number representation.  */
+   exponent = 0;
+diff -Naur glibc-2.20/stdlib/tst-strtod.c glibc-2.20-patch/stdlib/tst-strtod.c
+--- glibc-2.20/stdlib/tst-strtod.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/stdlib/tst-strtod.c	2015-03-04 00:51:32.420952006 -0600
+@@ -23,6 +23,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <math.h>
++#include <gnu/option-groups.h>
+ 
+ struct ltest
+   {
+@@ -176,7 +177,9 @@
+ 
+   status |= long_dbl ();
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   status |= locale_test ();
++#endif
+ 
+   return status ? EXIT_FAILURE : EXIT_SUCCESS;
+ }
+@@ -219,6 +222,7 @@
+   return 0;
+ }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ /* Perform a few tests in a locale with thousands separators.  */
+ static int
+ locale_test (void)
+@@ -276,3 +280,4 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+diff -Naur glibc-2.20/streams/Makefile glibc-2.20-patch/streams/Makefile
+--- glibc-2.20/streams/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/streams/Makefile	2015-03-04 00:51:32.421952006 -0600
+@@ -18,11 +18,14 @@
+ #
+ #	Makefile for streams.
+ #
++include ../option-groups.mak
++
+ subdir	:= streams
+ 
+ include ../Makeconfig
+ 
+ headers		= stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
+-routines	= isastream getmsg getpmsg putmsg putpmsg fattach fdetach
++routines-$(OPTION_EGLIBC_STREAMS) \
++	+= isastream getmsg getpmsg putmsg putpmsg fattach fdetach
+ 
+ include ../Rules
+diff -Naur glibc-2.20/string/Makefile glibc-2.20-patch/string/Makefile
+--- glibc-2.20/string/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/string/Makefile	2015-03-04 00:51:32.421952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for string portion of library.
+ #
++include ../option-groups.mak
++
+ subdir	:= string
+ 
+ include ../Makeconfig
+@@ -39,10 +41,12 @@
+ 		   $(addprefix argz-,append count create ctsep next	\
+ 				     delete extract insert stringify	\
+ 				     addsep replace)			\
+-		   envz basename					\
++		   basename						\
+ 		   strcoll_l strxfrm_l string-inlines memrchr		\
+ 		   xpg-strerror strerror_l
+ 
++routines-$(OPTION_EGLIBC_ENVZ) += envz
++
+ strop-tests	:= memchr memcmp memcpy memmove mempcpy memset memccpy	\
+ 		   stpcpy stpncpy strcat strchr strcmp strcpy strcspn	\
+ 		   strlen strncmp strncpy strpbrk strrchr strspn memmem	\
+@@ -51,10 +55,12 @@
+ tests		:= tester inl-tester noinl-tester testcopy test-ffs	\
+ 		   tst-strlen stratcliff tst-svc tst-inlcall		\
+ 		   bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap	\
+-		   tst-strtok tst-strxfrm bug-strcoll1 tst-strfry	\
++		   tst-strtok tst-strfry	\
+ 		   bug-strtok1 $(addprefix test-,$(strop-tests))	\
+-		   bug-envz1 tst-strxfrm2 tst-endian tst-svc2		\
+-		   tst-strtok_r
++		   tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r
++tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= tst-strxfrm bug-strcoll1
+ 
+ xtests = tst-strcoll-overflow
+ 
+diff -Naur glibc-2.20/string/strcoll_l.c glibc-2.20-patch/string/strcoll_l.c
+--- glibc-2.20/string/strcoll_l.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/string/strcoll_l.c	2015-03-04 00:51:32.421952006 -0600
+@@ -25,6 +25,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ #ifndef STRING_TYPE
+ # define STRING_TYPE char
+@@ -472,7 +473,11 @@
+ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ {
+   struct __locale_data *current = l->__locales[LC_COLLATE];
++#if __OPTION_EGLIBC_LOCALE_CODE
+   uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++#else
++  const uint_fast32_t nrules = 0;
++#endif
+   /* We don't assign the following values right away since it might be
+      unnecessary in case there are no rules.  */
+   const unsigned char *rulesets;
+diff -Naur glibc-2.20/string/strerror_l.c glibc-2.20-patch/string/strerror_l.c
+--- glibc-2.20/string/strerror_l.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/string/strerror_l.c	2015-03-04 00:51:32.421952006 -0600
+@@ -21,6 +21,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ static __thread char *last_value;
+@@ -29,10 +30,14 @@
+ static const char *
+ translate (const char *str, locale_t loc)
+ {
++#if __OPTION_EGLIBC_LOCALE_CODE
+   locale_t oldloc = __uselocale (loc);
+   const char *res = _(str);
+   __uselocale (oldloc);
+   return res;
++#else
++  return str;
++#endif
+ }
+ 
+ 
+diff -Naur glibc-2.20/string/strxfrm_l.c glibc-2.20-patch/string/strxfrm_l.c
+--- glibc-2.20/string/strxfrm_l.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/string/strxfrm_l.c	2015-03-04 00:51:32.421952006 -0600
+@@ -24,6 +24,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ #ifndef STRING_TYPE
+ # define STRING_TYPE char
+@@ -85,7 +86,11 @@
+ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+ {
+   struct __locale_data *current = l->__locales[LC_COLLATE];
++#if __OPTION_EGLIBC_LOCALE_CODE
+   uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++#else
++  const uint_fast32_t nrules = 0;
++#endif
+   /* We don't assign the following values right away since it might be
+      unnecessary in case there are no rules.  */
+   const unsigned char *rulesets;
+diff -Naur glibc-2.20/string/test-strcmp.c glibc-2.20-patch/string/test-strcmp.c
+--- glibc-2.20/string/test-strcmp.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/string/test-strcmp.c	2015-03-04 00:51:32.422952006 -0600
+@@ -329,34 +329,6 @@
+ 		FOR_EACH_IMPL (impl, 0)
+ 		check_result (impl, s1 + i1, s2 + i2, exp_result);
+       }
+-
+-  /* Test cases where there are multiple zero bytes after the first.  */
+-
+-  for (size_t i = 0; i < 16 + 1; i++)
+-    {
+-      s1[i] = 0x00;
+-      s2[i] = 0x00;
+-    }
+-
+-  for (size_t i = 0; i < 16; i++)
+-    {
+-      int exp_result;
+-
+-      for (int val = 0x01; val < 0x100; val++)
+-	{
+-	  for (size_t j = 0; j < i; j++)
+-	    {
+-	      s1[j] = val;
+-	      s2[j] = val;
+-	    }
+-
+-	  s2[i] = val;
+-
+-	  exp_result = SIMPLE_STRCMP (s1, s2);
+-	  FOR_EACH_IMPL (impl, 0)
+-	    check_result (impl, s1, s2, exp_result);
+-	}
+-    }
+ }
+ 
+ 
+diff -Naur glibc-2.20/string/tst-strxfrm2.c glibc-2.20-patch/string/tst-strxfrm2.c
+--- glibc-2.20/string/tst-strxfrm2.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/string/tst-strxfrm2.c	2015-03-04 00:51:32.422952006 -0600
+@@ -1,6 +1,7 @@
+ #include <locale.h>
+ #include <stdio.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ do_test (void)
+@@ -38,6 +39,7 @@
+       res = 1;
+     }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
+     {
+       puts ("setlocale failed");
+@@ -75,6 +77,7 @@
+ 	  res = 1;
+ 	}
+     }
++#endif
+ 
+   return res;
+ }
+diff -Naur glibc-2.20/string/tst-strxfrm.c glibc-2.20-patch/string/tst-strxfrm.c
+--- glibc-2.20/string/tst-strxfrm.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/string/tst-strxfrm.c	2015-03-04 00:51:32.422952006 -0600
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ char const string[] = "";
+@@ -64,8 +65,10 @@
+   int result = 0;
+ 
+   result |= test ("C");
++#if __OPTION_EGLIBC_LOCALE_CODE
+   result |= test ("en_US.ISO-8859-1");
+   result |= test ("de_DE.UTF-8");
++#endif
+ 
+   return result;
+ }
+diff -Naur glibc-2.20/sunrpc/Makefile glibc-2.20-patch/sunrpc/Makefile
+--- glibc-2.20/sunrpc/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sunrpc/Makefile	2015-03-04 00:51:32.422952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for sunrpc portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= sunrpc
+ 
+ include ../Makeconfig
+@@ -55,7 +57,6 @@
+ headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \
+ 		       $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h
+ headers = rpc/netdb.h
+-install-others = $(inst_sysconfdir)/rpc
+ generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \
+ 	     $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen
+ generated-dirs += rpcsvc
+@@ -65,18 +66,28 @@
+ endif
+ 
+ ifeq ($(build-shared),yes)
+-need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
++need-export-routines-$(OPTION_EGLIBC_SUNRPC) += \
++			auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
+ 			clnt_udp get_myaddr key_call netname pm_getport \
+-			rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \
++			rpc_thread svc svc_tcp svc_udp xdr_array xdr \
+ 			xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \
+ 			svc_run
+ 
+-routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
++need-export-routines-y += xcrypt
++
++need-export-routines := $(need-export-routines-y)
++
++routines-$(OPTION_EGLIBC_SUNRPC) \
++	 += auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
+ 	    rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \
+ 	    pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \
+ 	    svc_simple xdr_float xdr_rec publickey authdes_prot \
+-	    des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \
+-	    clnt_unix svc_unix create_xid $(need-export-routines)
++	    key_prot openchild rtime svcauth_des \
++	    clnt_unix svc_unix create_xid
++
++# xdecrypt is also used by nss/nss_files/files-key.c.
++routines-y += des_crypt des_impl des_soft $(need-export-routines)
++
+ ifneq ($(link-obsolete-rpc),yes)
+ # We only add the RPC for compatibility to libc.so.
+ shared-only-routines = $(routines)
+@@ -85,25 +96,28 @@
+ 
+ # We do not build rpcinfo anymore.  It is not needed for a bootstrap
+ # and not wanted on complete systems.
+-# others := rpcinfo
+-# install-sbin := rpcinfo
+-install-bin := rpcgen
++# others-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
++# install-sbin-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
++install-bin-$(OPTION_EGLIBC_SUNRPC) += rpcgen
+ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
+ 	      rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
+ 	      rpc_tblout.o rpc_sample.o
+-extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
+-others += rpcgen
++extra-objs-$(OPTION_EGLIBC_SUNRPC) = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
++others-$(OPTION_EGLIBC_SUNRPC) += rpcgen
++
++install-others-$(OPTION_EGLIBC_SUNRPC) += $(inst_sysconfdir)/rpc
+ 
+-tests = tst-xdrmem tst-xdrmem2
+-xtests := tst-getmyaddr
++tests-$(OPTION_EGLIBC_SUNRPC) = tst-xdrmem tst-xdrmem2
++xtests-$(OPTION_EGLIBC_SUNRPC) := tst-getmyaddr
+ 
+ ifeq ($(have-thread-library),yes)
+-xtests += thrsvc
++xtests-$(OPTION_EGLIBC_SUNRPC) += thrsvc
+ endif
+ 
+ headers += $(rpcsvc:%.x=rpcsvc/%.h)
+-extra-libs := librpcsvc
+-extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass.
++extra-libs-$(OPTION_EGLIBC_SUNRPC) += librpcsvc
++# Make it in `others' pass, not `lib' pass.
++extra-libs-others-y += $(extra-libs-y)
+ librpcsvc-routines = $(rpcsvc:%.x=x%)
+ librpcsvc-inhibit-o = .os # Build no shared rpcsvc library.
+ omit-deps = $(librpcsvc-routines)
+diff -Naur glibc-2.20/sysdeps/arm/Makefile glibc-2.20-patch/sysdeps/arm/Makefile
+--- glibc-2.20/sysdeps/arm/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/arm/Makefile	2015-03-04 00:51:32.422952006 -0600
+@@ -37,10 +37,13 @@
+ # get offset to rtld_global._dl_hwcap
+ gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym
+ aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math
+-aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \
++aeabi_routines = aeabi_assert aeabi_errno_addr \
+ 		 aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \
+ 		 aeabi_memmove aeabi_memset \
+ 		 aeabi_read_tp libc-aeabi_read_tp
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++aeabi_routines += aeabi_localeconv
++endif
+ 
+ sysdep_routines += $(aeabi_constants) $(aeabi_routines)
+ static-only-routines += $(aeabi_constants) aeabi_read_tp
+diff -Naur glibc-2.20/sysdeps/generic/ldsodefs.h glibc-2.20-patch/sysdeps/generic/ldsodefs.h
+--- glibc-2.20/sysdeps/generic/ldsodefs.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/generic/ldsodefs.h	2015-03-04 00:51:32.423952006 -0600
+@@ -425,6 +425,12 @@
+ # undef __rtld_global_attribute__
+ #endif
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
++# define GLRO_dl_debug_mask GLRO(dl_debug_mask)
++#else
++# define GLRO_dl_debug_mask 0
++#endif
++
+ #ifndef SHARED
+ # define GLRO(name) _##name
+ #else
+@@ -437,8 +443,10 @@
+ {
+ #endif
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
+   /* If nonzero the appropriate debug information is printed.  */
+   EXTERN int _dl_debug_mask;
++#endif
+ #define DL_DEBUG_LIBS	    (1 << 0)
+ #define DL_DEBUG_IMPCALLS   (1 << 1)
+ #define DL_DEBUG_BINDINGS   (1 << 2)
+diff -Naur glibc-2.20/sysdeps/gnu/Makefile glibc-2.20-patch/sysdeps/gnu/Makefile
+--- glibc-2.20/sysdeps/gnu/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/gnu/Makefile	2015-03-04 00:51:32.423952006 -0600
+@@ -57,7 +57,8 @@
+ endif
+ 
+ ifeq ($(subdir),login)
+-sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
++sysdep_routines-$(OPTION_EGLIBC_UTMPX) \
++		+= setutxent getutxent endutxent getutxid getutxline \
+ 		   pututxline utmpxname updwtmpx getutmpx getutmp
+ 
+ sysdep_headers += utmpx.h bits/utmpx.h
+diff -Naur glibc-2.20/sysdeps/ieee754/dbl-64/s_sin.c glibc-2.20-patch/sysdeps/ieee754/dbl-64/s_sin.c
+--- glibc-2.20/sysdeps/ieee754/dbl-64/s_sin.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/ieee754/dbl-64/s_sin.c	2015-03-04 00:51:32.423952006 -0600
+@@ -447,21 +447,19 @@
+ 	    }
+ 	  else
+ 	    {
+-	      double t;
+ 	      if (a > 0)
+ 		{
+ 		  m = 1;
+-		  t = a;
+ 		  db = da;
+ 		}
+ 	      else
+ 		{
+ 		  m = 0;
+-		  t = -a;
++		  a = -a;
+ 		  db = -da;
+ 		}
+-	      u.x = big + t;
+-	      y = t - (u.x - big);
++	      u.x = big + a;
++	      y = a - (u.x - big);
+ 	      res = do_sin (u, y, db, &cor);
+ 	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
+ 	      retval = ((res == res + cor) ? ((m) ? res : -res)
+@@ -673,21 +671,19 @@
+ 	    }
+ 	  else
+ 	    {
+-	      double t;
+ 	      if (a > 0)
+ 		{
+ 		  m = 1;
+-		  t = a;
+ 		  db = da;
+ 		}
+ 	      else
+ 		{
+ 		  m = 0;
+-		  t = -a;
++		  a = -a;
+ 		  db = -da;
+ 		}
+-	      u.x = big + t;
+-	      y = t - (u.x - big);
++	      u.x = big + a;
++	      y = a - (u.x - big);
+ 	      res = do_sin (u, y, db, &cor);
+ 	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
+ 	      retval = ((res == res + cor) ? ((m) ? res : -res)
+diff -Naur glibc-2.20/sysdeps/ieee754/ldbl-opt/Makefile glibc-2.20-patch/sysdeps/ieee754/ldbl-opt/Makefile
+--- glibc-2.20/sysdeps/ieee754/ldbl-opt/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/ieee754/ldbl-opt/Makefile	2015-03-04 00:51:32.423952006 -0600
+@@ -11,19 +11,18 @@
+ routines += math_ldbl_opt nldbl-compat
+ 
+ extra-libs += libnldbl
+-libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
++libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \
+ 		 obstack_printf obstack_vprintf printf scanf snprintf \
+-		 sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \
+-		 vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \
+-		 vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \
+-		 wprintf wscanf printf_fp printf_size \
+-		 fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \
+-		 swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \
+-		 vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \
+-		 wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \
++		 sprintf sscanf vasprintf vdprintf vfprintf \
++		 vfscanf vprintf vscanf vsnprintf \
++		 vsprintf vsscanf \
++		 printf_fp printf_size \
++		 fprintf_chk printf_chk snprintf_chk sprintf_chk \
++		 vfprintf_chk vprintf_chk \
++		 vsnprintf_chk vsprintf_chk \
++		 asprintf_chk vasprintf_chk dprintf_chk \
+ 		 vdprintf_chk obstack_printf_chk obstack_vprintf_chk \
+ 		 syslog syslog_chk vsyslog vsyslog_chk \
+-		 strfmon strfmon_l \
+ 		 strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
+ 		 qecvt qfcvt qgcvt qecvt_r qfcvt_r \
+ 		 isinf isnan finite signbit scalb log2 lgamma_r ceil \
+@@ -38,9 +37,15 @@
+ 		 casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \
+ 		 cabs carg cimag creal clog10 \
+ 		 isoc99_scanf isoc99_fscanf isoc99_sscanf \
+-		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
++		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf
++libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l
++libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \
++		 swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \
++		 vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \
++		 vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \
+ 		 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
+ 		 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
++libnldbl-calls += $(libnldbl-calls-y)
+ libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
+ libnldbl-inhibit-o = $(object-suffixes)
+ libnldbl-static-only-routines = $(libnldbl-routines)
+diff -Naur glibc-2.20/sysdeps/ieee754/ldbl-opt/nldbl-compat.c glibc-2.20-patch/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
+--- glibc-2.20/sysdeps/ieee754/ldbl-opt/nldbl-compat.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/ieee754/ldbl-opt/nldbl-compat.c	2015-03-04 00:51:32.424952006 -0600
+@@ -26,6 +26,7 @@
+ #include <locale/localeinfo.h>
+ #include <sys/syslog.h>
+ #include <bits/libc-lock.h>
++#include <gnu/option-groups.h>
+ 
+ #include "nldbl-compat.h"
+ 
+@@ -33,20 +34,14 @@
+ libc_hidden_proto (__nldbl_vsscanf)
+ libc_hidden_proto (__nldbl_vsprintf)
+ libc_hidden_proto (__nldbl_vfscanf)
+-libc_hidden_proto (__nldbl_vfwscanf)
+ libc_hidden_proto (__nldbl_vdprintf)
+-libc_hidden_proto (__nldbl_vswscanf)
+-libc_hidden_proto (__nldbl_vfwprintf)
+-libc_hidden_proto (__nldbl_vswprintf)
+ libc_hidden_proto (__nldbl_vsnprintf)
+ libc_hidden_proto (__nldbl_vasprintf)
+ libc_hidden_proto (__nldbl_obstack_vprintf)
+-libc_hidden_proto (__nldbl___vfwprintf_chk)
+ libc_hidden_proto (__nldbl___vsnprintf_chk)
+ libc_hidden_proto (__nldbl___vfprintf_chk)
+ libc_hidden_proto (__nldbl___vsyslog_chk)
+ libc_hidden_proto (__nldbl___vsprintf_chk)
+-libc_hidden_proto (__nldbl___vswprintf_chk)
+ libc_hidden_proto (__nldbl___vasprintf_chk)
+ libc_hidden_proto (__nldbl___vdprintf_chk)
+ libc_hidden_proto (__nldbl___obstack_vprintf_chk)
+@@ -54,8 +49,17 @@
+ libc_hidden_proto (__nldbl___vstrfmon_l)
+ libc_hidden_proto (__nldbl___isoc99_vsscanf)
+ libc_hidden_proto (__nldbl___isoc99_vfscanf)
++
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++libc_hidden_proto (__nldbl_vfwscanf)
++libc_hidden_proto (__nldbl_vswscanf)
++libc_hidden_proto (__nldbl_vfwprintf)
++libc_hidden_proto (__nldbl_vswprintf)
++libc_hidden_proto (__nldbl___vfwprintf_chk)
++libc_hidden_proto (__nldbl___vswprintf_chk)
+ libc_hidden_proto (__nldbl___isoc99_vswscanf)
+ libc_hidden_proto (__nldbl___isoc99_vfwscanf)
++#endif
+ 
+ static void
+ __nldbl_cleanup (void *arg)
+@@ -117,6 +121,7 @@
+ }
+ weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf)
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
+@@ -130,6 +135,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -226,6 +232,7 @@
+   return done;
+ }
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
+@@ -239,6 +246,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section weak_function
+@@ -264,6 +272,7 @@
+ }
+ libc_hidden_def (__nldbl_vdprintf)
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -275,6 +284,7 @@
+   return res;
+ }
+ libc_hidden_def (__nldbl_vfwprintf)
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -297,6 +307,7 @@
+ libc_hidden_def (__nldbl_vsnprintf)
+ weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf)
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
+@@ -330,6 +341,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -419,6 +431,7 @@
+   return done;
+ }
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -491,6 +504,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -506,6 +520,7 @@
+   return done;
+ }
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
+@@ -519,6 +534,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -563,6 +579,7 @@
+   return done;
+ }
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
+@@ -577,6 +594,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -590,6 +608,7 @@
+ }
+ libc_hidden_def (__nldbl___vfprintf_chk)
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
+@@ -601,6 +620,7 @@
+   return res;
+ }
+ libc_hidden_def (__nldbl___vfwprintf_chk)
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -635,6 +655,7 @@
+ }
+ libc_hidden_def (__nldbl___vsprintf_chk)
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
+@@ -668,6 +689,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -775,6 +797,7 @@
+   return ___printf_fp (fp, &info_no_ldbl, args);
+ }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ ssize_t
+ attribute_compat_text_section
+ __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...)
+@@ -829,6 +852,7 @@
+   return res;
+ }
+ libc_hidden_def (__nldbl___vstrfmon_l)
++#endif
+ 
+ void
+ attribute_compat_text_section
+@@ -941,6 +965,7 @@
+   return done;
+ }
+ 
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -1014,6 +1039,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+ compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0);
+@@ -1057,6 +1083,7 @@
+ compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1);
+ #endif
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2)
++# ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2);
+@@ -1069,6 +1096,7 @@
+ compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2);
++# endif
+ #endif
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
+ compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3);
+diff -Naur glibc-2.20/sysdeps/ieee754/ldbl-opt/nldbl-compat.h glibc-2.20-patch/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
+--- glibc-2.20/sysdeps/ieee754/ldbl-opt/nldbl-compat.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/ieee754/ldbl-opt/nldbl-compat.h	2015-03-04 00:51:32.424952006 -0600
+@@ -30,6 +30,7 @@
+ #include <math.h>
+ #include <monetary.h>
+ #include <sys/syslog.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ /* Declare the __nldbl_NAME function the wrappers call that's in libc.so.  */
+@@ -37,19 +38,15 @@
+ 
+ NLDBL_DECL (_IO_vfscanf);
+ NLDBL_DECL (vfscanf);
+-NLDBL_DECL (vfwscanf);
+ NLDBL_DECL (obstack_vprintf);
+ NLDBL_DECL (vasprintf);
+ NLDBL_DECL (dprintf);
+ NLDBL_DECL (vdprintf);
+ NLDBL_DECL (fprintf);
+ NLDBL_DECL (vfprintf);
+-NLDBL_DECL (vfwprintf);
+ NLDBL_DECL (vsnprintf);
+ NLDBL_DECL (vsprintf);
+ NLDBL_DECL (vsscanf);
+-NLDBL_DECL (vswprintf);
+-NLDBL_DECL (vswscanf);
+ NLDBL_DECL (__asprintf);
+ NLDBL_DECL (asprintf);
+ NLDBL_DECL (__printf_fp);
+@@ -66,12 +63,18 @@
+ NLDBL_DECL (__isoc99_vscanf);
+ NLDBL_DECL (__isoc99_vfscanf);
+ NLDBL_DECL (__isoc99_vsscanf);
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++NLDBL_DECL (vfwscanf);
++NLDBL_DECL (vfwprintf);
++NLDBL_DECL (vswprintf);
++NLDBL_DECL (vswscanf);
+ NLDBL_DECL (__isoc99_wscanf);
+ NLDBL_DECL (__isoc99_fwscanf);
+ NLDBL_DECL (__isoc99_swscanf);
+ NLDBL_DECL (__isoc99_vwscanf);
+ NLDBL_DECL (__isoc99_vfwscanf);
+ NLDBL_DECL (__isoc99_vswscanf);
++#endif
+ 
+ /* This one does not exist in the normal interface, only
+    __nldbl___vstrfmon really exists.  */
+@@ -82,22 +85,23 @@
+    since we don't compile with _FORTIFY_SOURCE.  */
+ extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
+ 				   const char *__restrict, _G_va_list);
+-extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
+-				    const wchar_t *__restrict, __gnuc_va_list);
+ extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
+ 				   const char *__restrict, _G_va_list) __THROW;
+ extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
+ 				    const char *__restrict, _G_va_list)
+   __THROW;
+-extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
+-				    const wchar_t *__restrict, __gnuc_va_list)
+-  __THROW;
+ extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list)
+   __THROW;
+ extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list);
+ extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *,
+ 					  _G_va_list) __THROW;
+ extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
+-
++#ifdef __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
++				    const wchar_t *__restrict, __gnuc_va_list);
++extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
++				    const wchar_t *__restrict, __gnuc_va_list)
++  __THROW;
++#endif
+ 
+ #endif /* __NLDBL_COMPAT_H */
+diff -Naur glibc-2.20/sysdeps/nptl/bits/libc-lock.h glibc-2.20-patch/sysdeps/nptl/bits/libc-lock.h
+--- glibc-2.20/sysdeps/nptl/bits/libc-lock.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/nptl/bits/libc-lock.h	2015-03-04 00:51:32.424952006 -0600
+@@ -24,6 +24,14 @@
+ #include <stddef.h>
+ 
+ 
++#ifdef _LIBC
++# include <lowlevellock.h>
++# include <tls.h>
++# include <pthread-functions.h>
++# include <errno.h> /* For EBUSY.  */
++# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS.  */
++#endif
++
+ /* Mutex type.  */
+ #if defined _LIBC || defined _IO_MTSAFE_IO
+ # if (defined NOT_IN_libc && !defined IS_IN_libpthread) || !defined _LIBC
+@@ -87,6 +95,14 @@
+ 
+ /* Lock the recursive named lock variable.  */
+ #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_lock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_lock_recursive(NAME) \
+   do {									      \
+     void *self = THREAD_SELF;						      \
+@@ -97,6 +113,10 @@
+       }									      \
+     ++(NAME).cnt;							      \
+   } while (0)
++# else
++# define __libc_lock_lock_recursive(NAME)				\
++  __libc_lock_lock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_lock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+@@ -104,6 +124,14 @@
+ 
+ /* Try to lock the recursive named lock variable.  */
+ #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_trylock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_trylock_recursive(NAME) \
+   ({									      \
+     int result = 0;							      \
+@@ -122,6 +150,10 @@
+       ++(NAME).cnt;							      \
+     result;								      \
+   })
++# else
++# define __libc_lock_trylock_recursive(NAME) \
++  __libc_lock_trylock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_trylock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
+@@ -129,6 +161,14 @@
+ 
+ /* Unlock the recursive named lock variable.  */
+ #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_unlock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ /* We do no error checking here.  */
+ # define __libc_lock_unlock_recursive(NAME) \
+   do {									      \
+@@ -138,6 +178,10 @@
+ 	lll_unlock ((NAME).lock, LLL_PRIVATE);				      \
+       }									      \
+   } while (0)
++# else
++# define __libc_lock_unlock_recursive(NAME) \
++  __libc_lock_unlock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_unlock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+diff -Naur glibc-2.20/sysdeps/nptl/bits/libc-lockP.h glibc-2.20-patch/sysdeps/nptl/bits/libc-lockP.h
+--- glibc-2.20/sysdeps/nptl/bits/libc-lockP.h	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/nptl/bits/libc-lockP.h	2015-03-04 00:51:32.424952006 -0600
+@@ -33,6 +33,8 @@
+ #include <lowlevellock.h>
+ #include <tls.h>
+ #include <pthread-functions.h>
++#include <errno.h> /* For EBUSY.  */
++#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS.  */
+ 
+ /* Mutex type.  */
+ #if defined NOT_IN_libc && !defined IS_IN_libpthread
+@@ -159,10 +161,22 @@
+ 
+ /* Lock the named lock variable.  */
+ #if !defined NOT_IN_libc || defined IS_IN_libpthread
+-# ifndef __libc_lock_lock
+-#  define __libc_lock_lock(NAME) \
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_lock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_lock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
++#  ifndef __libc_lock_lock
++#   define __libc_lock_lock(NAME) \
+   ({ lll_lock (NAME, LLL_PRIVATE); 0; })
+-# endif
++#  endif
++# else
++#  define __libc_lock_lock(NAME)		\
++  __libc_lock_lock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # undef __libc_lock_lock
+ # define __libc_lock_lock(NAME) \
+@@ -175,10 +189,22 @@
+ 
+ /* Try to lock the named lock variable.  */
+ #if !defined NOT_IN_libc || defined IS_IN_libpthread
+-# ifndef __libc_lock_trylock
+-#  define __libc_lock_trylock(NAME) \
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern int __libc_lock_trylock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_trylock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
++#  ifndef __libc_lock_trylock
++#   define __libc_lock_trylock(NAME) \
+   lll_trylock (NAME)
+-# endif
++#  endif
++# else
++# define __libc_lock_trylock(NAME) \
++  __libc_lock_trylock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # undef __libc_lock_trylock
+ # define __libc_lock_trylock(NAME) \
+@@ -194,8 +220,20 @@
+ 
+ /* Unlock the named lock variable.  */
+ #if !defined NOT_IN_libc || defined IS_IN_libpthread
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_unlock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_unlock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_unlock(NAME) \
+   lll_unlock (NAME, LLL_PRIVATE)
++# else
++# define __libc_lock_unlock(NAME) \
++  __libc_lock_unlock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_unlock(NAME) \
+   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
+diff -Naur glibc-2.20/sysdeps/nptl/Makefile glibc-2.20-patch/sysdeps/nptl/Makefile
+--- glibc-2.20/sysdeps/nptl/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/nptl/Makefile	2015-03-04 00:51:32.424952006 -0600
+@@ -18,6 +18,9 @@
+ 
+ ifeq ($(subdir),nptl)
+ libpthread-sysdep_routines += errno-loc
++ifeq ($(OPTION_EGLIBC_BIG_MACROS),n)
++sysdep_routines += small-macros-fns
++endif
+ endif
+ 
+ ifeq ($(subdir),rt)
+diff -Naur glibc-2.20/sysdeps/nptl/small-macros-fns.c glibc-2.20-patch/sysdeps/nptl/small-macros-fns.c
+--- glibc-2.20/sysdeps/nptl/small-macros-fns.c	1969-12-31 18:00:00.000000000 -0600
++++ glibc-2.20-patch/sysdeps/nptl/small-macros-fns.c	2015-03-04 00:51:32.424952006 -0600
+@@ -0,0 +1,72 @@
++/* EGLIBC: function wrappers for big macros.
++   Copyright (C) 2009 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; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++
++#include <gnu/option-groups.h>
++
++/* Handle macros from ./bits/libc-lock.h.  */
++#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++
++/* Get the macros for function bodies through a back door.  */
++# undef __OPTION_EGLIBC_BIG_MACROS
++# define __OPTION_EGLIBC_BIG_MACROS 2
++# include <bits/libc-lock.h>
++
++void
++__libc_lock_lock_fn (__libc_lock_t *name)
++{
++  __libc_lock_lock (*name);
++}
++libc_hidden_def (__libc_lock_lock_fn);
++
++void
++__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  __libc_lock_lock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_lock_recursive_fn);
++
++int
++__libc_lock_trylock_fn (__libc_lock_t *name)
++{
++  return __libc_lock_trylock (*name);
++}
++libc_hidden_def (__libc_lock_trylock_fn);
++
++int
++__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  return __libc_lock_trylock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_trylock_recursive_fn);
++
++void
++__libc_lock_unlock_fn (__libc_lock_t *name)
++{
++  __libc_lock_unlock (*name);
++}
++libc_hidden_def (__libc_lock_unlock_fn);
++
++void
++__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  __libc_lock_unlock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_unlock_recursive_fn);
++
++#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/gethostid.c glibc-2.20-patch/sysdeps/unix/sysv/linux/gethostid.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/gethostid.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/gethostid.c	2015-03-04 00:51:32.425952006 -0600
+@@ -21,6 +21,7 @@
+ #include <unistd.h>
+ #include <netdb.h>
+ #include <not-cancel.h>
++#include <gnu/option-groups.h>
+ 
+ #define HOSTIDFILE "/etc/hostid"
+ 
+@@ -89,6 +90,7 @@
+ 	return id;
+     }
+ 
++#if __OPTION_EGLIBC_INET
+   /* Getting from the file was not successful.  An intelligent guess for
+      a unique number of a host is its IP address.  Return this.  */
+   if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0')
+@@ -115,5 +117,9 @@
+   /* For the return value to be not exactly the IP address we do some
+      bit fiddling.  */
+   return (int32_t) (in.s_addr << 16 | in.s_addr >> 16);
++#else
++  /* Return an arbitrary value.  */
++  return 0;
++#endif
+ }
+ #endif
+diff -Naur glibc-2.20/sysdeps/unix/sysv/linux/libc_fatal.c glibc-2.20-patch/sysdeps/unix/sysv/linux/libc_fatal.c
+--- glibc-2.20/sysdeps/unix/sysv/linux/libc_fatal.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/sysdeps/unix/sysv/linux/libc_fatal.c	2015-03-04 00:51:32.425952006 -0600
+@@ -23,6 +23,7 @@
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/uio.h>
++#include <gnu/option-groups.h>
+ 
+ static bool
+ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
+@@ -40,6 +41,7 @@
+ static void
+ backtrace_and_maps (int do_abort, bool written, int fd)
+ {
++#if __OPTION_EGLIBC_BACKTRACE
+   if (do_abort > 1 && written)
+     {
+       void *addrs[64];
+@@ -62,6 +64,7 @@
+           close_not_cancel_no_status (fd2);
+         }
+     }
++#endif /* __OPTION_EGLIBC_BACKTRACE */
+ }
+ #define BEFORE_ABORT		backtrace_and_maps
+ 
+diff -Naur glibc-2.20/time/Makefile glibc-2.20-patch/time/Makefile
+--- glibc-2.20/time/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/time/Makefile	2015-03-04 00:51:32.425952006 -0600
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for time routines
+ #
++include ../option-groups.mak
++
+ subdir	:= time
+ 
+ include ../Makeconfig
+@@ -30,14 +32,20 @@
+ 	    tzfile getitimer setitimer			 \
+ 	    stime dysize timegm ftime			 \
+ 	    getdate strptime strptime_l			 \
+-	    strftime wcsftime strftime_l wcsftime_l	 \
++	    strftime strftime_l				 \
+ 	    timespec_get
+-aux :=	    era alt_digit lc-time-cleanup
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR)		 \
++	 := wcsftime wcsftime_l
++aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup
+ 
+-tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
+-	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
++tests	:= test_time clocktest tst-posixtz \
++	   tst-getdate tst-mktime tst-mktime2 tst-strftime \
+ 	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
+ 	   tst-strptime3 bug-getdate1 tst-strptime-whitespace
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++	+= tst-strptime tst-ftime_l
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
++	+= tst_wcsftime
+ 
+ include ../Rules
+ 
+diff -Naur glibc-2.20/time/strftime_l.c glibc-2.20-patch/time/strftime_l.c
+--- glibc-2.20/time/strftime_l.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/time/strftime_l.c	2015-03-04 00:51:32.426952006 -0600
+@@ -35,6 +35,10 @@
+ # include "../locale/localeinfo.h"
+ #endif
+ 
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined emacs && !defined HAVE_BCOPY
+ # define HAVE_MEMCPY 1
+ #endif
+@@ -882,7 +886,7 @@
+ 	case L_('C'):
+ 	  if (modifier == L_('E'))
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+@@ -955,7 +959,7 @@
+ 
+ 	  if (modifier == L_('O') && 0 <= number_value)
+ 	    {
+-#ifdef _NL_CURRENT
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
+ 	      /* Get the locale specific alternate representation of
+ 		 the number NUMBER_VALUE.  If none exist NULL is returned.  */
+ 	      const CHAR_T *cp = nl_get_alt_digit (number_value
+@@ -1260,7 +1264,7 @@
+ 	case L_('Y'):
+ 	  if (modifier == 'E')
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+@@ -1285,7 +1289,7 @@
+ 	case L_('y'):
+ 	  if (modifier == L_('E'))
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+diff -Naur glibc-2.20/time/strptime_l.c glibc-2.20-patch/time/strptime_l.c
+--- glibc-2.20/time/strptime_l.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/time/strptime_l.c	2015-03-04 00:51:32.426952006 -0600
+@@ -29,6 +29,7 @@
+ 
+ #ifdef _LIBC
+ # define HAVE_LOCALTIME_R 0
++# include <gnu/option-groups.h>
+ # include "../locale/localeinfo.h"
+ #endif
+ 
+@@ -84,7 +85,7 @@
+     if (val < from || val > to)						      \
+       return NULL;							      \
+   } while (0)
+-#ifdef _NL_CURRENT
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
+ # define get_alt_number(from, to, n) \
+   ({									      \
+      __label__ do_normal;						      \
+@@ -820,6 +821,7 @@
+ 	      s.want_xday = 1;
+ 	      break;
+ 	    case 'C':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  if (s.era_cnt >= 0)
+@@ -856,10 +858,12 @@
+ 
+ 		  s.decided = raw;
+ 		}
++#endif
+ 	      /* The C locale has no era information, so use the
+ 		 normal representation.  */
+ 	      goto match_century;
+  	    case 'y':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  get_number(0, 9999, 4);
+@@ -918,9 +922,10 @@
+ 
+ 		  s.decided = raw;
+ 		}
+-
++#endif
+ 	      goto match_year_in_century;
+ 	    case 'Y':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  num_eras = _NL_CURRENT_WORD (LC_TIME,
+@@ -948,6 +953,7 @@
+ 
+ 		  s.decided = raw;
+ 		}
++#endif
+ 	      get_number (0, 9999, 4);
+ 	      tm->tm_year = val - 1900;
+ 	      s.want_century = 0;
+@@ -1118,6 +1124,7 @@
+ 	tm->tm_year = (s.century - 19) * 100;
+     }
+ 
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+   if (s.era_cnt != -1)
+     {
+       era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);
+@@ -1132,6 +1139,7 @@
+ 	tm->tm_year = era->start_date[0];
+     }
+   else
++#endif
+     if (s.want_era)
+       {
+ 	/* No era found but we have seen an E modifier.  Rectify some
+diff -Naur glibc-2.20/timezone/Makefile glibc-2.20-patch/timezone/Makefile
+--- glibc-2.20/timezone/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/timezone/Makefile	2015-03-04 00:51:32.426952006 -0600
+@@ -115,7 +115,7 @@
+ 
+ $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
+ 	sed -e 's|/bin/bash|$(BASH)|' \
+-	    -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
++            -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \
+ 	    -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
+ 	    -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
+ 	    -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \
+diff -Naur glibc-2.20/wcsmbs/Makefile glibc-2.20-patch/wcsmbs/Makefile
+--- glibc-2.20/wcsmbs/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/wcsmbs/Makefile	2015-03-04 00:51:32.426952006 -0600
+@@ -18,15 +18,21 @@
+ #
+ #	Sub-makefile for wcsmbs portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= wcsmbs
+ 
+ include ../Makeconfig
+ 
+ headers	:= wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h
+ 
+-routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
++# These functions are used by printf_fp.c, even in the plain case; see
++# comments there for OPTION_EGLIBC_LOCALE_CODE.
++routines  := wmemcpy wmemset
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++	  := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
+ 	    wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
+-	    wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \
++	    wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \
+ 	    btowc wctob mbsinit \
+ 	    mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
+ 	    mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \
+@@ -38,14 +44,19 @@
+ 	    wcscoll_l wcsxfrm_l \
+ 	    wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
+ 	    wcsmbsload mbsrtowcs_l \
+-	    isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
+ 	    isoc99_swscanf isoc99_vswscanf \
+ 	    mbrtoc16 c16rtomb
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)				\
++	 += isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf
+ 
+ strop-tests :=  wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy
+-tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
+-	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
+-	 tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests))
++tests := tst-wchar-h
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++      += tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++      += tst-wcstof wcsmbs-tst1 tst-wcsnlen \
++	 tst-wcpncpy tst-mbsrtowcs \
++	 wcsatcliff $(addprefix test-,$(strop-tests))
+ tests-ifunc := $(strop-tests:%=test-%-ifunc)
+ tests += $(tests-ifunc)
+ 
+diff -Naur glibc-2.20/wcsmbs/wcsmbsload.c glibc-2.20-patch/wcsmbs/wcsmbsload.c
+--- glibc-2.20/wcsmbs/wcsmbsload.c	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/wcsmbs/wcsmbsload.c	2015-03-04 00:51:32.426952006 -0600
+@@ -21,6 +21,7 @@
+ #include <limits.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ #include <locale/localeinfo.h>
+ #include <wcsmbsload.h>
+@@ -143,6 +144,7 @@
+   })
+ 
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ /* Some of the functions here must not be used while setlocale is called.  */
+ __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
+ 
+@@ -211,6 +213,17 @@
+ 
+   __libc_rwlock_unlock (__libc_setlocale_lock);
+ }
++#else
++void
++internal_function
++__wcsmbs_load_conv (struct __locale_data *new_category)
++{
++  /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach
++     this point: there is no way to change locales, so every locale
++     passed to get_gconv_fcts should be _nl_C_LC_CTYPE.  */
++  abort ();
++}
++#endif
+ 
+ 
+ /* Clone the current conversion function set.  */
+diff -Naur glibc-2.20/wctype/Makefile glibc-2.20-patch/wctype/Makefile
+--- glibc-2.20/wctype/Makefile	2014-09-07 03:09:09.000000000 -0500
++++ glibc-2.20-patch/wctype/Makefile	2015-03-04 00:51:32.427952006 -0600
+@@ -18,14 +18,20 @@
+ #
+ #	Sub-makefile for wctype portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= wctype
+ 
+ include ../Makeconfig
+ 
+ headers		:= wctype.h
+-routines	:= wcfuncs wctype iswctype wctrans towctrans \
+-		   wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l
++routines 	:= wctrans towctrans towctrans_l
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++		:= wcfuncs wctype iswctype \
++		   wcfuncs_l wctype_l iswctype_l wctrans_l
+ 
+-tests	:= test_wctype test_wcfuncs bug-wctypeh
++tests	:=
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++     += test_wctype test_wcfuncs bug-wctypeh
+ 
+ include ../Rules
diff --git a/recipes-core/glibc/glibc-initial.inc b/recipes-core/glibc/glibc-initial.inc
new file mode 100644
index 0000000..9d3a736
--- /dev/null
+++ b/recipes-core/glibc/glibc-initial.inc
@@ -0,0 +1,83 @@
+DEPENDS = "linux-libc-headers virtual/${TARGET_PREFIX}gcc-initial libgcc-initial"
+PROVIDES = "virtual/${TARGET_PREFIX}libc-initial"
+
+PACKAGES = ""
+PACKAGES_DYNAMIC = ""
+
+STAGINGCC = "gcc-cross-initial-${TARGET_ARCH}"
+STAGINGCC_class-nativesdk = "gcc-crosssdk-initial-${SDK_SYS}"
+#TOOLCHAIN_OPTIONS = " --sysroot=${STAGING_DIR_TARGET}"
+
+do_configure () {
+	sed -ie 's,{ (exit 1); exit 1; }; },{ (exit 0); }; },g' ${S}/configure
+	chmod +x ${S}/configure
+	(cd ${S} && gnu-configize) || die "failure in running gnu-configize"
+	find ${S} -name "configure" | xargs touch
+	${S}/configure --host=${TARGET_SYS} --build=${BUILD_SYS} \
+		--prefix=/usr \
+		--without-cvs --disable-sanity-checks \
+		--with-headers=${STAGING_DIR_TARGET}${includedir} \
+		--with-kconfig=${STAGING_BINDIR_NATIVE} \
+		--enable-hacker-mode --enable-addons
+}
+
+do_compile () {
+	:
+}
+
+do_install () {
+	oe_runmake cross-compiling=yes install_root=${D} \
+	includedir='${includedir}' prefix='${prefix}' \
+	install-bootstrap-headers=yes install-headers
+
+	oe_runmake csu/subdir_lib
+	mkdir -p ${D}${libdir}/
+	install -m 644 csu/crt[1in].o ${D}${libdir}
+
+	# Two headers -- stubs.h and features.h -- aren't installed by install-headers,
+	# so do them by hand.  We can tolerate an empty stubs.h for the moment.
+	# See e.g. http://gcc.gnu.org/ml/gcc/2002-01/msg00900.html
+	mkdir -p ${D}${includedir}/gnu/
+	touch ${D}${includedir}/gnu/stubs.h
+	cp ${S}/include/features.h ${D}${includedir}/features.h
+
+	if [ -e ${B}/bits/stdio_lim.h ]; then
+		cp ${B}/bits/stdio_lim.h  ${D}${includedir}/bits/
+	fi
+	# add links to linux-libc-headers: final glibc build need this.
+       	#for t in linux asm asm-generic; do
+	#	ln -s ${STAGING_DIR_TARGET}${includedir}/$t ${D}${includedir}/
+	#done
+}
+
+do_stash_locale() {
+	:
+}
+
+do_siteconfig () {
+	:
+}
+
+#SSTATEPOSTINSTFUNCS += "glibcinitial_sstate_postinst"
+#glibcinitial_sstate_postinst() {
+#	if [ "${BB_CURRENTTASK}" = "populate_sysroot" -o "${BB_CURRENTTASK}" = "populate_sysroot_setscene" ]
+#	then
+#		# Recreate the symlinks to ensure they point to the correct location
+#		for t in linux asm asm-generic; do
+#			rm -f ${STAGING_DIR_TARGET}${includedir}/$t
+#		#	ln -s ${STAGING_DIR_TARGET}${includedir}/$t ${STAGING_DIR_TARGET}${includedir}/
+#		done
+#	fi
+#}
+
+#do_populate_sysroot[sstate-outputdirs] = "${STAGING_DIR_TARGET}/"
+
+# We don't install any scripts so there is nothing to evacuate
+#do_evacuate_scripts () {
+#	:
+#}
+
+#inherit nopackages
+
+# We really only want this built by things that need it, not any recrdeptask
+#deltask do_build
diff --git a/recipes-core/glibc/glibc-initial_2.20.bb b/recipes-core/glibc/glibc-initial_2.20.bb
new file mode 100644
index 0000000..8ab01dc
--- /dev/null
+++ b/recipes-core/glibc/glibc-initial_2.20.bb
@@ -0,0 +1,11 @@
+require glibc_${PV}.bb
+require glibc-initial.inc
+
+DEPENDS += "kconfig-frontends-native"
+
+# main glibc recipes muck with TARGET_CPPFLAGS to point into
+# final target sysroot but we
+# are not there when building glibc-initial
+# so reset it here
+
+TARGET_CPPFLAGS = ""
diff --git a/recipes-core/glibc/glibc-ld.inc b/recipes-core/glibc/glibc-ld.inc
new file mode 100644
index 0000000..962d666
--- /dev/null
+++ b/recipes-core/glibc/glibc-ld.inc
@@ -0,0 +1,56 @@
+def ld_append_if_tune_exists(d, infos, dict):
+    tune = d.getVar("DEFAULTTUNE", True) or ""
+    libdir = d.getVar("base_libdir", True) or ""
+    if tune in dict:
+        infos['ldconfig'].add('{"' + libdir + '/' + dict[tune][0] + '",' + dict[tune][1] + ' }')
+        infos['lddrewrite'].add(libdir+'/'+dict[tune][0])
+
+def glibc_dl_info(d):
+    ld_info_all = {
+        "mips": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64-n32": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mipsel": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64el-n32": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64el": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips-nf": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64-nf-n32": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64-nf": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64el-nf-n32": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "mips64el-nf": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "powerpc": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "powerpc-nf": ["ld.so.1", "FLAG_ELF_LIBC6"],
+        "powerpc64": ["ld64.so.1", "FLAG_ELF_LIBC6"],
+        "powerpc64-nf": ["ld64.so.1", "FLAG_ELF_LIBC6"],
+        "core2-32": ["ld-linux.so.2", "FLAG_ELF_LIBC6"],
+        "core2-64": ["ld-linux-x86-64.so.2", "FLAG_ELF_LIBC6"],
+        "x86": ["ld-linux.so.2", "FLAG_ELF_LIBC6"],
+        "x86-64": ["ld-linux-x86-64.so.2", "FLAG_ELF_LIBC6"],
+        "i586": ["ld-linux.so.2", "FLAG_ELF_LIBC6"],
+        "corei7-32": ["ld-linux.so.2", "FLAG_ELF_LIBC6"],
+        "corei7-64": ["ld-linux-x86-64.so.2", "FLAG_ELF_LIBC6"],
+    }
+
+    infos = {'ldconfig':set(), 'lddrewrite':set()}
+    ld_append_if_tune_exists(d, infos, ld_info_all)
+
+    #DEFAULTTUNE_MULTILIB_ORIGINAL
+    original_tune=d.getVar("DEFAULTTUNE_MULTILIB_ORIGINAL",True)
+    if original_tune:
+        localdata = bb.data.createCopy(d)
+        localdata.setVar("DEFAULTTUNE", original_tune)
+        ld_append_if_tune_exists(localdata, infos, ld_info_all)
+
+    variants = d.getVar("MULTILIB_VARIANTS", True) or ""
+    for item in variants.split():
+        localdata = bb.data.createCopy(d)
+        overrides = localdata.getVar("OVERRIDES", False) + ":virtclass-multilib-" + item
+        localdata.setVar("OVERRIDES", overrides)
+        bb.data.update_data(localdata)
+        ld_append_if_tune_exists(localdata, infos, ld_info_all)
+    infos['ldconfig'] = ','.join(infos['ldconfig'])
+    infos['lddrewrite'] = ' '.join(infos['lddrewrite'])
+    return infos
+
+EGLIBC_KNOWN_INTERPRETER_NAMES = "${@glibc_dl_info(d)['ldconfig']}"
+RTLDLIST = "${@glibc_dl_info(d)['lddrewrite']}"
diff --git a/recipes-core/glibc/glibc-locale_2.20.bb b/recipes-core/glibc/glibc-locale_2.20.bb
new file mode 100644
index 0000000..8d22aff
--- /dev/null
+++ b/recipes-core/glibc/glibc-locale_2.20.bb
@@ -0,0 +1 @@
+require recipes-core/glibc/glibc-locale.inc
diff --git a/recipes-core/glibc/glibc-mtrace_2.20.bb b/recipes-core/glibc/glibc-mtrace_2.20.bb
new file mode 100644
index 0000000..436605c
--- /dev/null
+++ b/recipes-core/glibc/glibc-mtrace_2.20.bb
@@ -0,0 +1 @@
+require  recipes-core/glibc/glibc-mtrace.inc
diff --git a/recipes-core/glibc/glibc-options.inc b/recipes-core/glibc/glibc-options.inc
new file mode 100644
index 0000000..9fd27f3
--- /dev/null
+++ b/recipes-core/glibc/glibc-options.inc
@@ -0,0 +1,162 @@
+def glibc_cfg(feature, tokens, cnf):
+    if type(tokens) == type(""):
+        tokens = [tokens]
+    if feature:
+        cnf.extend([token + '=y' for token in tokens])
+    else:
+        for token in tokens:
+            cnf.extend([token + '=n'])
+            if token == 'OPTION_EGLIBC_NSSWITCH':
+                cnf.extend(["OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG=\"${S}/nss/nsswitch.conf\""])
+                cnf.extend(["OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS=\"${S}/nss/fixed-nsswitch.functions\""])
+
+# Map distro features to glibc options settings
+def features_to_glibc_settings(d):
+    cnf = ([])
+
+    ipv4 = bb.utils.contains('DISTRO_FEATURES', 'ipv4', True, False, d)
+    ipv6 = bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d)
+    libc_backtrace = bb.utils.contains('DISTRO_FEATURES', 'libc-backtrace', True, False, d) 
+    libc_big_macros = bb.utils.contains('DISTRO_FEATURES', 'libc-big-macros', True, False, d)
+    libc_bsd = bb.utils.contains('DISTRO_FEATURES', 'libc-bsd', True, False, d)
+    libc_cxx_tests = bb.utils.contains('DISTRO_FEATURES', 'libc-cxx-tests', True, False, d)
+    libc_catgets = bb.utils.contains('DISTRO_FEATURES', 'libc-catgets', True, False, d)
+    libc_charsets = bb.utils.contains('DISTRO_FEATURES', 'libc-charsets', True, False, d)
+    libc_crypt = bb.utils.contains('DISTRO_FEATURES', 'libc-crypt', True, False, d)
+    libc_crypt_ufc = bb.utils.contains('DISTRO_FEATURES', 'libc-crypt-ufc', True, False, d)
+    libc_db_aliases = bb.utils.contains('DISTRO_FEATURES', 'libc-db-aliases', True, False, d)
+    libc_envz = bb.utils.contains('DISTRO_FEATURES', 'libc-envz', True, False, d)
+    libc_fcvt = bb.utils.contains('DISTRO_FEATURES', 'libc-fcvt', True, False, d)
+    libc_fmtmsg = bb.utils.contains('DISTRO_FEATURES', 'libc-fmtmsg', True, False, d)
+    libc_fstab = bb.utils.contains('DISTRO_FEATURES', 'libc-fstab', True, False, d)
+    libc_ftraverse = bb.utils.contains('DISTRO_FEATURES', 'libc-ftraverse', True, False, d)
+    libc_getlogin = bb.utils.contains('DISTRO_FEATURES', 'libc-getlogin', True, False, d)
+    libc_idn = bb.utils.contains('DISTRO_FEATURES', 'libc-idn', True, False, d)
+    libc_inet_anl = bb.utils.contains('DISTRO_FEATURES', 'libc-inet-anl', True, False, d)
+    libc_libm = bb.utils.contains('DISTRO_FEATURES', 'libc-libm', True, False, d)
+    libc_locales = bb.utils.contains('DISTRO_FEATURES', 'libc-locales', True, False, d)
+    libc_locale_code = bb.utils.contains('DISTRO_FEATURES', 'libc-locale-code', True, False, d)
+    libc_memusage = bb.utils.contains('DISTRO_FEATURES', 'libc-memusage', True, False, d)
+    libc_nis = bb.utils.contains('DISTRO_FEATURES', 'libc-nis', True, False, d)
+    libc_nsswitch = bb.utils.contains('DISTRO_FEATURES', 'libc-nsswitch', True, False, d)
+    libc_rcmd = bb.utils.contains('DISTRO_FEATURES', 'libc-rcmd', True, False, d)
+    libc_rtld_debug = bb.utils.contains('DISTRO_FEATURES', 'libc-rtld-debug', True, False, d)
+    libc_spawn = bb.utils.contains('DISTRO_FEATURES', 'libc-spawn', True, False, d)
+    libc_streams = bb.utils.contains('DISTRO_FEATURES', 'libc-streams', True, False, d)
+    libc_sunrpc = bb.utils.contains('DISTRO_FEATURES', 'libc-sunrpc', True, False, d)
+    libc_utmp = bb.utils.contains('DISTRO_FEATURES', 'libc-utmp', True, False, d)
+    libc_utmpx = bb.utils.contains('DISTRO_FEATURES', 'libc-utmpx', True, False, d)
+    libc_wordexp = bb.utils.contains('DISTRO_FEATURES', 'libc-wordexp', True, False, d)
+    libc_posix_clang_wchar = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-clang-wchar', True, False, d)
+    libc_posix_regexp = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-regexp', True, False, d)
+    libc_posix_regexp_glibc = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-regexp-glibc', True, False, d)
+    libc_posix_wchar_io = bb.utils.contains('DISTRO_FEATURES', 'libc-posix-wchar-io', True, False, d)
+
+    # arrange the dependencies among glibc configuable options according to file option-groups.def from glibc source code
+    new_dep = True
+    while new_dep:
+        new_dep = False
+
+        if ipv6 and not ipv4:
+            new_dep = True
+            ipv4 = True
+
+        if ipv4 and not libc_nsswitch:
+            new_dep = True
+            libc_nsswitch = True
+
+        if libc_cxx_tests:
+            if not libc_posix_wchar_io:
+                new_dep = True
+                libc_posix_wchar_io = True
+            if not libc_libm:
+                new_dep = True
+                libc_libm = True
+
+        if libc_catgets and not libc_locale_code:
+            new_dep = True
+            libc_locale_code = True
+
+        if libc_crypt_ufc and not libc_crypt:
+            new_dep = True
+            libc_crypt = True
+
+        if libc_getlogin and not libc_utmp:
+            new_dep = True
+            libc_utmp = True
+
+        if libc_inet_anl and not ipv4:
+            new_dep = True
+            ipv4 = True
+
+        if libc_locale_code and not libc_posix_clang_wchar:
+            new_dep = True
+            libc_posix_clang_wchar = True
+
+        if libc_nis:
+            if not ipv4:
+                new_dep = True
+                ipv4 = True
+            if not libc_sunrpc:
+                new_dep = True
+                libc_sunrpc = True
+
+        if libc_rcmd and not ipv4:
+            new_dep = True
+            ipv4 = True
+
+        if libc_sunrpc and not ipv4:
+            new_dep = True
+            ipv4 = True
+
+        if libc_utmpx and not libc_utmp:
+            new_dep = True
+            libc_utmp = True
+
+        if libc_posix_regexp_glibc and not libc_posix_regexp:
+            new_dep = True
+            libc_posix_regexp = True
+
+        if libc_posix_wchar_io and not libc_posix_clang_wchar:
+            new_dep = True
+            libc_posix_clang_wchar = True
+
+    glibc_cfg(ipv6, 'OPTION_EGLIBC_ADVANCED_INET6', cnf)
+    glibc_cfg(libc_backtrace, 'OPTION_EGLIBC_BACKTRACE', cnf)
+    glibc_cfg(libc_big_macros, 'OPTION_EGLIBC_BIG_MACROS', cnf)
+    glibc_cfg(libc_bsd, 'OPTION_EGLIBC_BSD', cnf)
+    glibc_cfg(libc_cxx_tests, 'OPTION_EGLIBC_CXX_TESTS', cnf)
+    glibc_cfg(libc_catgets, 'OPTION_EGLIBC_CATGETS', cnf)
+    glibc_cfg(libc_charsets, 'OPTION_EGLIBC_CHARSETS', cnf)
+    glibc_cfg(libc_crypt, 'OPTION_EGLIBC_CRYPT', cnf)
+    glibc_cfg(libc_crypt_ufc, 'OPTION_EGLIBC_CRYPT_UFC', cnf)
+    glibc_cfg(libc_db_aliases, 'OPTION_EGLIBC_DB_ALIASES', cnf)
+    glibc_cfg(libc_envz, 'OPTION_EGLIBC_ENVZ', cnf)
+    glibc_cfg(libc_fcvt, 'OPTION_EGLIBC_FCVT', cnf)
+    glibc_cfg(libc_fmtmsg, 'OPTION_EGLIBC_FMTMSG', cnf)
+    glibc_cfg(libc_fstab, 'OPTION_EGLIBC_FSTAB', cnf)
+    glibc_cfg(libc_ftraverse, 'OPTION_EGLIBC_FTRAVERSE', cnf)
+    glibc_cfg(libc_getlogin, 'OPTION_EGLIBC_GETLOGIN', cnf)
+    glibc_cfg(libc_idn, 'OPTION_EGLIBC_IDN', cnf)
+    glibc_cfg(ipv4, 'OPTION_EGLIBC_INET', cnf)
+    glibc_cfg(libc_inet_anl, 'OPTION_EGLIBC_INET_ANL', cnf)
+    glibc_cfg(libc_libm, 'OPTION_EGLIBC_LIBM', cnf)
+    glibc_cfg(libc_locales, 'OPTION_EGLIBC_LOCALES', cnf)
+    glibc_cfg(libc_locale_code, 'OPTION_EGLIBC_LOCALE_CODE', cnf)
+    glibc_cfg(libc_memusage, 'OPTION_EGLIBC_MEMUSAGE', cnf)
+    glibc_cfg(libc_nis, 'OPTION_EGLIBC_NIS', cnf)
+    glibc_cfg(libc_nsswitch, 'OPTION_EGLIBC_NSSWITCH', cnf)
+    glibc_cfg(libc_rcmd, 'OPTION_EGLIBC_RCMD', cnf)
+    glibc_cfg(libc_rtld_debug, 'OPTION_EGLIBC_RTLD_DEBUG', cnf)
+    glibc_cfg(libc_spawn, 'OPTION_EGLIBC_SPAWN', cnf)
+    glibc_cfg(libc_streams, 'OPTION_EGLIBC_STREAMS', cnf)
+    glibc_cfg(libc_sunrpc, 'OPTION_EGLIBC_SUNRPC', cnf)
+    glibc_cfg(libc_utmp, 'OPTION_EGLIBC_UTMP', cnf)
+    glibc_cfg(libc_utmpx, 'OPTION_EGLIBC_UTMPX', cnf)
+    glibc_cfg(libc_wordexp, 'OPTION_EGLIBC_WORDEXP', cnf)
+    glibc_cfg(libc_posix_clang_wchar, 'OPTION_POSIX_C_LANG_WIDE_CHAR', cnf)
+    glibc_cfg(libc_posix_regexp, 'OPTION_POSIX_REGEXP', cnf)
+    glibc_cfg(libc_posix_regexp_glibc, 'OPTION_POSIX_REGEXP_GLIBC', cnf)
+    glibc_cfg(libc_posix_wchar_io, 'OPTION_POSIX_WIDE_CHAR_DEVICE_IO', cnf)
+
+    return "\n".join(cnf)
diff --git a/recipes-core/glibc/glibc-package.inc b/recipes-core/glibc/glibc-package.inc
new file mode 100644
index 0000000..a2a70f4
--- /dev/null
+++ b/recipes-core/glibc/glibc-package.inc
@@ -0,0 +1,227 @@
+INHIBIT_SYSROOT_STRIP = "1"
+
+PACKAGES = "${PN}-dbg catchsegv sln nscd ldd tzcode glibc-thread-db ${PN}-pic libcidn libmemusage libsegfault ${PN}-pcprofile libsotruss ${PN} ${PN}-utils glibc-extra-nss ${PN}-dev ${PN}-staticdev ${PN}-doc"
+
+# The ld.so in this glibc supports the GNU_HASH
+RPROVIDES_${PN} = "eglibc rtld(GNU_HASH)"
+RPROVIDES_${PN}-utils = "eglibc-utils"
+RPROVIDES_${PN}-mtrace = "eglibc-mtrace libc-mtrace"
+RPROVIDES_${PN}-pic = "eglibc-pic"
+RPROVIDES_${PN}-dev = "eglibc-dev libc6-dev virtual-libc-dev"
+RPROVIDES_${PN}-staticdev = "eglibc-staticdev"
+RPROVIDES_${PN}-doc = "eglibc-doc"
+RPROVIDES_glibc-extra-nss = "eglibc-extra-nss"
+RPROVIDES_glibc-thread-db = "eglibc-thread-db"
+RPROVIDES_${PN}-pcprofile = "eglibc-pcprofile"
+RPROVIDES_${PN}-dbg = "eglibc-dbg"
+libc_baselibs = "${base_libdir}/libcrypt*.so.* ${base_libdir}/libcrypt-*.so ${base_libdir}/libc.so.* ${base_libdir}/libc-*.so ${base_libdir}/libm*.so.* ${base_libdir}/libm-*.so ${base_libdir}/libmvec-*.so ${base_libdir}/ld*.so.* ${base_libdir}/ld-*.so ${base_libdir}/libpthread*.so.* ${base_libdir}/libpthread-*.so ${base_libdir}/libresolv*.so.* ${base_libdir}/libresolv-*.so ${base_libdir}/librt*.so.* ${base_libdir}/librt-*.so ${base_libdir}/libutil*.so.* ${base_libdir}/libutil-*.so ${base_libdir}/libnsl*.so.* ${base_libdir}/libnsl-*.so ${base_libdir}/libnss_files*.so.* ${base_libdir}/libnss_files-*.so ${base_libdir}/libnss_compat*.so.* ${base_libdir}/libnss_compat-*.so ${base_libdir}/libnss_dns*.so.* ${base_libdir}/libnss_dns-*.so ${base_libdir}/libdl*.so.* ${base_libdir}/libdl-*.so ${base_libdir}/libanl*.so.* ${base_libdir}/libanl-*.so ${base_libdir}/libBrokenLocale*.so.* ${base_libdir}/libBrokenLocale-*.so"
+libc_baselibs_append_aarch64 = " /lib/ld-linux-aarch64*.so.1"
+INSANE_SKIP_${PN}_append_aarch64 = " libdir"
+
+FILES_${PN} = "${libc_baselibs} ${libexecdir}/* ${base_sbindir}/ldconfig ${sysconfdir}/ld.so.conf"
+FILES_ldd = "${bindir}/ldd"
+FILES_libsegfault = "${base_libdir}/libSegFault*"
+FILES_libcidn = "${base_libdir}/libcidn-*.so ${base_libdir}/libcidn.so.*"
+FILES_libmemusage = "${base_libdir}/libmemusage.so"
+FILES_glibc-extra-nss = "${base_libdir}/libnss_*-*.so ${base_libdir}/libnss_*.so.*"
+FILES_sln = "${base_sbindir}/sln"
+FILES_${PN}-pic = "${libdir}/*_pic.a ${libdir}/*_pic.map ${libdir}/libc_pic/*.o"
+FILES_libsotruss = "${libdir}/audit/sotruss-lib.so"
+FILES_SOLIBSDEV = "${libdir}/lib*${SOLIBSDEV}"
+FILES_${PN}-dev += "${bindir}/rpcgen ${libdir}/*_nonshared.a ${base_libdir}/*_nonshared.a ${base_libdir}/*.o ${datadir}/aclocal"
+FILES_${PN}-staticdev += "${libdir}/*.a ${base_libdir}/*.a"
+FILES_nscd = "${sbindir}/nscd* ${sysconfdir}/init.d/nscd ${systemd_unitdir}/system/nscd* ${sysconfdir}/tmpfiles.d/nscd.conf \
+              ${sysconfdir}/nscd.conf ${sysconfdir}/default/volatiles/98_nscd ${localstatedir}/db/nscd"
+FILES_${PN}-mtrace = "${bindir}/mtrace"
+FILES_tzcode = "${bindir}/tzselect ${sbindir}/zic ${sbindir}/zdump"
+FILES_${PN}-utils = "${bindir}/* ${sbindir}/*"
+FILES_catchsegv = "${bindir}/catchsegv"
+RDEPENDS_catchsegv = "libsegfault"
+FILES_${PN}-pcprofile = "${base_libdir}/libpcprofile.so"
+FILES_glibc-thread-db = "${base_libdir}/libthread_db.so.* ${base_libdir}/libthread_db-*.so"
+RPROVIDES_${PN}-dev += "libc-dev"
+RPROVIDES_${PN}-staticdev += "libc-staticdev"
+
+SUMMARY_sln = "The static ln"
+DESCRIPTION_sln = "Similar to the 'ln' utility, but statically linked.  sln is useful to make symbolic links to dynamic libraries if the dynamic linking system, for some reason, is not functional."
+SUMMARY_nscd = "Name service cache daemon"
+DESCRIPTION_nscd = "nscd, name service cache daemon, caches name service lookups for the passwd, group and hosts information.  It can damatically improvide performance with remote, such as NIS or NIS+, name services."
+SUMMARY_glibc-extra-nss = "hesiod, NIS and NIS+ nss libraries"
+DESCRIPTION_glibc-extra-nss = "glibc: nis, nisplus and hesiod search services."
+SUMMARY_ldd = "print shared library dependencies"
+DESCRIPTION_ldd = "${bindir}/ldd prints shared library dependencies for each program or shared library specified on the command line."
+SUMMARY_${PN}-utils = "Miscellaneous utilities provided by glibc"
+DESCRIPTION_${PN}-utils = "Miscellaneous utilities including getconf, iconv, locale, gencat, rpcgen, ..."
+DESCRIPTION_libsotruss = "Library to support sotruss which traces calls through PLTs"
+DESCRIPTION_tzcode = "tzcode, timezone zoneinfo utils -- zic, zdump, tzselect"
+
+inherit libc-common multilib_header
+
+do_install_append () {
+	rm -f ${D}${sysconfdir}/localtime
+	rm -rf ${D}${localstatedir}
+
+	# remove empty glibc dir
+	if [ -d ${D}${libexecdir} ]; then
+		rmdir --ignore-fail-on-non-empty ${D}${libexecdir}
+	fi
+
+	oe_multilib_header bits/syscall.h
+
+	if [ -f ${D}${bindir}/mtrace ]; then
+		sed -i -e '1s,#!.*perl,#! ${USRBINPATH}/env perl,' -e '2s,exec.*perl,exec ${USRBINPATH}/env perl,' ${D}${bindir}/mtrace
+	fi
+	rm -rf ${D}${includedir}/rpcsvc/rquota*
+	# Info dir listing isn't interesting at this point so remove it if it exists.
+	if [ -e "${D}${infodir}/dir" ]; then
+		rm -f ${D}${infodir}/dir
+	fi
+
+	if ! ${@bb.utils.contains('DISTRO_FEATURES', 'ldconfig', 'true', 'false', d)}; then
+		# The distro doesn't want these files so let's not install them
+		rm -f ${D}${sysconfdir}/ld.so.conf
+		rm -f ${D}${base_sbindir}/ldconfig
+		# This directory will be empty now so remove it too.
+		# But check whether it exists first, since it won't for glibc-initial.
+		if [ -d ${D}${sysconfdir} ]; then
+			rmdir ${D}${sysconfdir}
+		fi
+	fi
+
+	if echo ${PN}|grep -q "glibc-initial"; then
+		return
+	fi
+
+	install -d ${D}${sysconfdir}/init.d
+	install -d ${D}${localstatedir}/db/nscd
+	install -m 0755 ${S}/nscd/nscd.init ${D}${sysconfdir}/init.d/nscd
+	install -m 0755 ${S}/nscd/nscd.conf ${D}${sysconfdir}/nscd.conf
+	sed -i "s%daemon%start-stop-daemon --start --exec%g" ${D}${sysconfdir}/init.d/nscd
+
+	install -d ${D}${systemd_unitdir}/system
+	install -m 0644 ${S}/nscd/nscd.service ${D}${systemd_unitdir}/system/
+
+	if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
+		install -d ${D}${sysconfdir}/tmpfiles.d
+		echo "d /run/nscd 755 root root -" \
+			> ${D}${sysconfdir}/tmpfiles.d/nscd.conf
+	else
+		install -d ${D}${sysconfdir}/default/volatiles
+		echo "d root root 0755 /var/run/nscd none" \
+			> ${D}${sysconfdir}/default/volatiles/98_nscd
+	fi
+}
+
+do_install_append_aarch64 () {
+	if [ "${base_libdir}" != "/lib" ] ; then
+		# The aarch64 ABI says the dynamic linker -must- be /lib/ld-linux-aarch64[_be].so.1
+		install -d ${D}/lib
+		if [ -e ${D}${base_libdir}/ld-linux-aarch64.so.1 ]; then
+			ln -s ${@base_path_relative('/lib', '${base_libdir}')}/ld-linux-aarch64.so.1 \
+				${D}/lib/ld-linux-aarch64.so.1
+		elif [ -e ${D}${base_libdir}/ld-linux-aarch64_be.so.1 ]; then
+			ln -s ${@base_path_relative('/lib', '${base_libdir}')}/ld-linux-aarch64_be.so.1 \
+				${D}/lib/ld-linux-aarch64_be.so.1
+		fi
+	fi
+	do_install_armmultilib
+}
+
+do_install_append_arm () {
+	do_install_armmultilib
+}
+
+do_install_append_armeb () {
+	do_install_armmultilib
+}
+
+do_install_armmultilib () {
+
+	oe_multilib_header bits/endian.h bits/fcntl.h bits/fenv.h bits/fp-fast.h bits/hwcap.h bits/ipc.h bits/link.h bits/wordsize.h
+	oe_multilib_header bits/local_lim.h bits/mman.h bits/msq.h bits/pthreadtypes.h bits/pthreadtypes-arch.h  bits/sem.h  bits/semaphore.h bits/setjmp.h
+	oe_multilib_header bits/shm.h bits/sigstack.h bits/stat.h bits/statfs.h bits/typesizes.h
+
+	oe_multilib_header fpu_control.h gnu/lib-names.h gnu/stubs.h ieee754.h
+
+	oe_multilib_header sys/elf.h sys/procfs.h sys/ptrace.h sys/ucontext.h sys/user.h
+}
+
+
+LOCALESTASH = "${WORKDIR}/stashed-locale"
+bashscripts = "mtrace sotruss xtrace"
+
+do_stash_locale () {
+	dest=${LOCALESTASH}
+	install -d ${dest}${base_libdir} ${dest}${bindir} ${dest}${libdir} ${dest}${datadir}
+	if [ "${base_libdir}" != "${libdir}" ]; then
+		cp -fpPR ${D}${base_libdir}/* ${dest}${base_libdir}
+	fi
+	if [ -e ${D}${bindir}/localedef ]; then
+		mv -f ${D}${bindir}/localedef ${dest}${bindir}
+	fi
+	if [ -e ${D}${libdir}/gconv ]; then
+		mv -f ${D}${libdir}/gconv ${dest}${libdir}
+	fi
+	if [ -e ${D}${exec_prefix}/lib ]; then
+		cp -fpPR ${D}${exec_prefix}/lib ${dest}${exec_prefix}
+	fi
+	if [ -e ${D}${datadir}/i18n ]; then
+		mv ${D}${datadir}/i18n ${dest}${datadir}
+	fi
+	cp -fpPR ${D}${datadir}/* ${dest}${datadir}
+	rm -rf ${D}${datadir}/locale/
+	cp -fpPR ${WORKDIR}/SUPPORTED ${dest}
+
+	target=${dest}/scripts
+	mkdir -p $target
+	for i in ${bashscripts}; do
+		if [ -f ${D}${bindir}/$i ]; then
+			cp ${D}${bindir}/$i $target/
+		fi
+	done
+}
+
+addtask do_stash_locale after do_install before do_populate_sysroot do_package
+do_stash_locale[dirs] = "${B}"
+do_stash_locale[cleandirs] = "${LOCALESTASH}"
+SSTATETASKS += "do_stash_locale"
+do_stash_locale[sstate-inputdirs] = "${LOCALESTASH}"
+do_stash_locale[sstate-outputdirs] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/glibc-stash-locale"
+do_stash_locale[sstate-fixmedir] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/glibc-stash-locale"
+
+python do_stash_locale_setscene () {
+    sstate_setscene(d)
+}
+addtask do_stash_locale_setscene
+
+do_poststash_install_cleanup () {
+	# Remove all files which do_stash_locale would remove (mv)
+	# since that task could have come from sstate and not get run.
+	for i in ${bashscripts}; do
+	    rm -f ${D}${bindir}/$i
+	done
+	rm -f ${D}${bindir}/localedef
+	rm -rf ${D}${datadir}/i18n
+	rm -rf ${D}${libdir}/gconv
+	rm -rf ${D}/${localedir}
+	rm -rf ${D}${datadir}/locale
+	if [ "${libdir}" != "${exec_prefix}/lib" ]; then
+		# This dir only exists to hold locales
+		rm -rf ${D}${exec_prefix}/lib
+	fi
+}
+addtask do_poststash_install_cleanup after do_stash_locale do_install before do_populate_sysroot do_package
+
+pkg_postinst_nscd () {
+	if [ -z "$D" ]; then
+		if command -v systemd-tmpfiles >/dev/null; then
+			systemd-tmpfiles --create ${sysconfdir}/tmpfiles.d/nscd.conf
+		elif [ -e ${sysconfdir}/init.d/populate-volatile.sh ]; then
+			${sysconfdir}/init.d/populate-volatile.sh update
+		fi
+	fi
+}
+CONFFILES_nscd="${sysconfdir}/nscd.conf"
+
+SYSTEMD_PACKAGES = "nscd"
+SYSTEMD_SERVICE_nscd = "nscd.service"
diff --git a/recipes-core/glibc/glibc-scripts_2.20.bb b/recipes-core/glibc/glibc-scripts_2.20.bb
new file mode 100644
index 0000000..674cd80
--- /dev/null
+++ b/recipes-core/glibc/glibc-scripts_2.20.bb
@@ -0,0 +1 @@
+require recipes-core/glibc/glibc-scripts.inc
diff --git a/recipes-core/glibc/glibc-testing.inc b/recipes-core/glibc/glibc-testing.inc
new file mode 100644
index 0000000..ec16fe1
--- /dev/null
+++ b/recipes-core/glibc/glibc-testing.inc
@@ -0,0 +1,79 @@
+do_compile_append () {
+	# now generate script to drive testing
+	echo "#!/usr/bin/env sh" >${B}/${HOST_PREFIX}testglibc
+	set >> ${B}/${HOST_PREFIX}testglibc
+	# prune out the unneeded vars
+	sed -i -e "/^BASH/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^USER/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^OPT/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^DIRSTACK/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^EUID/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^FUNCNAME/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^GROUPS/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^HOST/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^HOME/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^IFS/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^LC_ALL/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^LOGNAME/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^MACHTYPE/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^OSTYPE/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^PIPE/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^SHELL/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^'/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^UID/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^TERM/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^PATCH_GET/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^PKG_/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^POSIXLY_/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^PPID/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^PS4/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^Q/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^SHLVL/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^STAGING/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^LD_LIBRARY_PATH/d" ${B}/${HOST_PREFIX}testglibc
+	sed -i -e "/^PSEUDO/d" ${B}/${HOST_PREFIX}testglibc
+
+	# point to real sysroot not the toolchain bootstrap sysroot
+	sed -i -e "s/\-tcbootstrap//g" ${B}/${HOST_PREFIX}testglibc
+
+	# use the final cross-gcc to test since some tests need libstdc++
+	sed -i -e "s/^PATH=.*\.gcc-cross-initial\:/PATH=/g" ${B}/${HOST_PREFIX}testglibc
+
+	# append execution part script
+cat >> ${B}/${HOST_PREFIX}testglibc << STOP
+target="\$1"
+if [ "x\$target" = "x" ]
+then
+	echo "Please specify the target machine and remote user in form of user@target"
+	exit 1;
+fi
+ssh \$target ls \$PWD\  2>&1 > /dev/null
+if [ "x\$?" != "x0" ]
+then
+	echo "Failed connecting to \$target it could be because of:"
+	echo "1. You dont have passwordless ssh setup to access \$target"
+	echo "2. NFS share on \$target is not mounted or if mounted then not matching the build tree layout."
+	echo "   The tree should be accessible at same location on build host and target"
+	echo "   You can add nfs-server to IMAGE_FEATURES to get the nfs client on target"
+	echo "3. nfs server on build host is not running."
+	echo "   Please make sure that you have 'no_root_squash' added in /etc/exports if you want"
+	echo "   to test as root user on target (usually its recommended to create a non"
+	echo "   root user."
+	echo "   As a sanity check make sure that target can read/write to the glibc build tree"
+	echo "   Please refer to ${S}/EGLIBC.cross-testing for further instructions on setup"
+	exit 1
+fi
+	echo "# we test using cross compiler from real sysroot therefore override the" > ${B}/configparms
+	echo "# definitions that come from ${B}/config.make" >> ${B}/configparms
+
+	fgrep tcbootstrap ${B}/config.make > ${B}/configparms
+	sed -i -e "s/\-tcbootstrap//g" ${B}/configparms
+wrapper="${S}/scripts/cross-test-ssh.sh \$target"
+localedef="${STAGING_BINDIR_NATIVE}/cross-localedef --little-endian --uint32-align=4"
+make tests-clean
+make cross-localedef="\$localedef" cross-test-wrapper="\$wrapper" -k check
+rm -rf ${B}/configparms
+STOP
+
+	chmod +x ${B}/${HOST_PREFIX}testglibc
+}
diff --git a/recipes-core/glibc/glibc/0001-R_ARM_TLS_DTPOFF32.patch b/recipes-core/glibc/glibc/0001-R_ARM_TLS_DTPOFF32.patch
new file mode 100644
index 0000000..3922cb8
--- /dev/null
+++ b/recipes-core/glibc/glibc/0001-R_ARM_TLS_DTPOFF32.patch
@@ -0,0 +1,56 @@
+
+Quote from bug 1443 which explains what the patch does : 
+
+  We build some random program and link it with -lust.  When we run it,
+  it dies with a SIGSEGV before reaching main().
+  
+  Libust.so depends on liburcu-bp.so from the usermode-rcu package.
+  Although libust.so is not prelinked, liburcu-bp.so IS prelinked; this
+  is critical.
+  
+  Libust.so uses a TLS / __thread variable that is defined in liburcu-
+  bp.so.  There are special ARM-specific relocation types that allow two
+  shared libraries to share thread-specific data.  This is critical too.
+  
+  One more critical issue: although liburcu-bp.so is prelinked, we can't
+  load it at its prelinked address, because we also link against
+  librt.so, and librt.so uses that address.
+  
+  The dynamic linker is forced to relink liburcu-bp.so at a different
+  address.  In the course of relinking, it processes the special ARM
+  relocation record mentioned above.  The prelinker has already filled
+  in the information, which is a short offset into a table of thread-
+  specific data that is allocated per-thread for each library that uses
+  TLS.  Because the normal behavior of a relocation is to add the symbol
+  value to an addend stored at the address being relocated, we end up
+  adding the short offset to itself, doubling it.
+  
+  Now we have an awkward situation.  The libust.so library doesn't know
+  about the addend, so its TLS data for this element is correct.  The
+  liburcu-bp.so library has a different offset for the element.  When we
+  go to initialize the element for the first time in liburcu-bp.so, we
+  write the address of the result at the doubled (broken) offset.
+  Later, when we refer to the address from libust.so, we check the value
+  at the correct offset, but it's NULL, so we eat hot SIGSEGV.
+
+Upstream-Status: Pending
+
+Signed-off-by: Andrei Dinu <andrei.adrianx.dinu@intel.com>
+---
+ .../libc/ports/sysdeps/arm/dl-machine.h            |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+ndex 8d905e8..dcfa71e 100644
+Index: git/sysdeps/arm/dl-machine.h
+===================================================================
+--- git.orig/sysdeps/arm/dl-machine.h	2014-08-27 05:30:47.748070587 +0000
++++ git/sysdeps/arm/dl-machine.h	2014-08-27 05:30:47.740070587 +0000
+@@ -495,7 +495,7 @@
+ 
+ 	case R_ARM_TLS_DTPOFF32:
+ 	  if (sym != NULL)
+-	    *reloc_addr += sym->st_value;
++	    *reloc_addr = sym->st_value;
+ 	  break;
+ 
+ 	case R_ARM_TLS_TPOFF32:
diff --git a/recipes-core/glibc/glibc/0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch b/recipes-core/glibc/glibc/0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
new file mode 100644
index 0000000..f341282
--- /dev/null
+++ b/recipes-core/glibc/glibc/0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch
@@ -0,0 +1,33 @@
+From 713d822908d1b2ae8403af7f9375c7054ed3dd49 Mon Sep 17 00:00:00 2001
+From: Ting Liu <b28495@freescale.com>
+Date: Wed, 19 Dec 2012 04:39:57 -0600
+Subject: [PATCH] eglibc: run libm-err-tab.pl with specific dirs in ${S}
+
+libm-err-tab.pl will parse all the files named "libm-test-ulps"
+in the given dir recursively. To avoid parsing the one in
+${S}/.pc/ (it does exist after eglibc adds aarch64 support,
+${S}/.pc/aarch64-0001-glibc-fsf-v1-eaf6f205.patch/ports/sysdeps/
+aarch64/libm-test-ulps), run libm-err-tab.pl with specific dirs
+in ${S}.
+
+Upstream-Status: inappropriate [OE specific]
+
+Signed-off-by: Ting Liu <b28495@freescale.com>
+---
+ manual/Makefile |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: git/manual/Makefile
+===================================================================
+--- git.orig/manual/Makefile	2014-08-29 10:35:18.728070587 -0700
++++ git/manual/Makefile	2014-08-29 10:35:18.720070587 -0700
+@@ -105,7 +105,8 @@
+ $(objpfx)stamp-libm-err: libm-err-tab.pl $(wildcard $(foreach dir,$(sysdirs),\
+ 						     $(dir)/libm-test-ulps))
+ 	pwd=`pwd`; \
+-	$(PERL) $< $$pwd/.. > $(objpfx)libm-err-tmp
++	$(PERL) $< $$pwd/../ports > $(objpfx)libm-err-tmp
++	$(PERL) $< $$pwd/../sysdeps >> $(objpfx)libm-err-tmp
+ 	$(move-if-change) $(objpfx)libm-err-tmp $(objpfx)libm-err.texi
+ 	touch $@
+ 
diff --git a/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch b/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch
new file mode 100644
index 0000000..0ce8230
--- /dev/null
+++ b/recipes-core/glibc/glibc/0017-timezone-re-written-tzselect-as-posix-sh.patch
@@ -0,0 +1,45 @@
+From c90306107fbbe2979012917e87747ce78c82ab88 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:33:03 +0000
+Subject: [PATCH 17/27] timezone: re-written tzselect as posix sh
+
+To avoid the bash dependency.
+
+Upstream-Status: Pending
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ timezone/Makefile     | 2 +-
+ timezone/tzselect.ksh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/timezone/Makefile b/timezone/Makefile
+index 24c93c6..886b06e 100644
+--- a/timezone/Makefile
++++ b/timezone/Makefile
+@@ -126,7 +126,7 @@ $(testdata)/XT%: testdata/XT%
+ 	cp $< $@
+ 
+ $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
+-	sed -e 's|/bin/bash|$(BASH)|' \
++	sed -e 's|/bin/bash|/bin/sh|' \
+ 	    -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
+ 	    -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
+ 	    -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
+diff --git a/timezone/tzselect.ksh b/timezone/tzselect.ksh
+index 9d70691..25f45a8 100755
+--- a/timezone/tzselect.ksh
++++ b/timezone/tzselect.ksh
+@@ -35,7 +35,7 @@ REPORT_BUGS_TO=tz@iana.org
+ 
+ # Specify default values for environment variables if they are unset.
+ : ${AWK=awk}
+-: ${TZDIR=`pwd`}
++: ${TZDIR=$(pwd)}
+ 
+ # Check for awk Posix compliance.
+ ($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch b/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
new file mode 100644
index 0000000..8eacbc0
--- /dev/null
+++ b/recipes-core/glibc/glibc/0018-eglibc-Cross-building-and-testing-instructions.patch
@@ -0,0 +1,619 @@
+From eff048074ac7b5258bb615e5a5b221daa19b18ae Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:42:58 +0000
+Subject: [PATCH 18/27] eglibc: Cross building and testing instructions
+
+Ported from eglibc
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ GLIBC.cross-building | 383 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ GLIBC.cross-testing  | 205 +++++++++++++++++++++++++++
+ 2 files changed, 588 insertions(+)
+ create mode 100644 GLIBC.cross-building
+ create mode 100644 GLIBC.cross-testing
+
+diff --git a/GLIBC.cross-building b/GLIBC.cross-building
+new file mode 100644
+index 0000000..e6e0da1
+--- /dev/null
++++ b/GLIBC.cross-building
+@@ -0,0 +1,383 @@
++                                                        -*- mode: text -*-
++
++                        Cross-Compiling GLIBC
++                  Jim Blandy <jimb@codesourcery.com>
++
++
++Introduction
++
++Most GNU tools have a simple build procedure: you run their
++'configure' script, and then you run 'make'.  Unfortunately, the
++process of cross-compiling the GNU C library is quite a bit more
++involved:
++
++1) Build a cross-compiler, with certain facilities disabled.
++
++2) Configure the C library using the compiler you built in step 1).
++   Build a few of the C run-time object files, but not the rest of the
++   library.  Install the library's header files and the run-time
++   object files, and create a dummy libc.so.
++
++3) Build a second cross-compiler, using the header files and object
++   files you installed in step 2.
++
++4) Configure, build, and install a fresh C library, using the compiler
++   built in step 3.
++
++5) Build a third cross-compiler, based on the C library built in step 4.
++
++The reason for this complexity is that, although GCC and the GNU C
++library are distributed separately, they are not actually independent
++of each other: GCC requires the C library's headers and some object
++files to compile its own libraries, while the C library depends on
++GCC's libraries.  GLIBC includes features and bug fixes to the stock
++GNU C library that simplify this process, but the fundamental
++interdependency stands.
++
++In this document, we explain how to cross-compile an GLIBC/GCC pair
++from source.  Our intended audience is developers who are already
++familiar with the GNU toolchain and comfortable working with
++cross-development tools.  While we do present a worked example to
++accompany the explanation, for clarity's sake we do not cover many of
++the options available to cross-toolchain users.
++
++
++Preparation
++
++GLIBC requires recent versions of the GNU binutils, GCC, and the
++Linux kernel.  The web page <http://www.eglibc.org/prerequisites>
++documents the current requirements, and lists patches needed for
++certain target architectures.  As of this writing, these build
++instructions have been tested with binutils 2.22.51, GCC 4.6.2,
++and Linux 3.1.
++
++First, let's set some variables, to simplify later commands.  We'll
++build GLIBC and GCC for an ARM target, known to the Linux kernel
++as 'arm', and we'll do the build on an Intel x86_64 Linux box:
++
++    $ build=x86_64-pc-linux-gnu
++    $ host=$build
++    $ target=arm-none-linux-gnueabi
++    $ linux_arch=arm
++
++We're using the aforementioned versions of Binutils, GCC, and Linux:
++
++    $ binutilsv=binutils-2.22.51
++    $ gccv=gcc-4.6.2
++    $ linuxv=linux-3.1
++
++We're carrying out the entire process under '~/cross-build', which
++contains unpacked source trees for binutils, gcc, and linux kernel,
++along with GLIBC svn trunk (which can be checked-out with
++'svn co http://www.eglibc.org/svn/trunk eglibc'):
++
++    $ top=$HOME/cross-build/$target
++    $ src=$HOME/cross-build/src
++    $ ls $src
++    binutils-2.22.51  glibc  gcc-4.6.2  linux-3.1
++
++We're going to place our build directories in a subdirectory 'obj',
++we'll install the cross-development toolchain in 'tools', and we'll
++place our sysroot (containing files to be installed on the target
++system) in 'sysroot':
++
++    $ obj=$top/obj
++    $ tools=$top/tools
++    $ sysroot=$top/sysroot
++
++
++Binutils
++
++Configuring and building binutils for the target is straightforward:
++
++    $ mkdir -p $obj/binutils
++    $ cd $obj/binutils
++    $ $src/$binutilsv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --with-sysroot=$sysroot
++    $ make
++    $ make install
++
++
++The First GCC
++
++For our work, we need a cross-compiler targeting an ARM Linux
++system.  However, that configuration includes the shared library
++'libgcc_s.so', which is compiled against the GLIBC headers (which we
++haven't installed yet) and linked against 'libc.so' (which we haven't
++built yet).
++
++Fortunately, there are configuration options for GCC which tell it not
++to build 'libgcc_s.so'.  The '--without-headers' option is supposed to
++take care of this, but its implementation is incomplete, so you must
++also configure with the '--with-newlib' option.  While '--with-newlib'
++appears to mean "Use the Newlib C library", its effect is to tell the
++GCC build machinery, "Don't assume there is a C library available."
++
++We also need to disable some of the libraries that would normally be
++built along with GCC, and specify that only the compiler for the C
++language is needed.
++
++So, we create a build directory, configure, make, and install.
++
++    $ mkdir -p $obj/gcc1
++    $ cd $obj/gcc1
++    $ $src/$gccv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --without-headers --with-newlib \
++    >     --disable-shared --disable-threads --disable-libssp \
++    >     --disable-libgomp --disable-libmudflap --disable-libquadmath \
++    >     --disable-decimal-float --disable-libffi \
++    >     --enable-languages=c
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install
++
++
++Linux Kernel Headers
++
++To configure GLIBC, we also need Linux kernel headers in place.
++Fortunately, the Linux makefiles have a target that installs them for
++us.  Since the process does modify the source tree a bit, we make a
++copy first:
++
++    $ cp -r $src/$linuxv $obj/linux
++    $ cd $obj/linux
++
++Now we're ready to install the headers into the sysroot:
++
++    $ PATH=$tools/bin:$PATH \
++    > make headers_install \
++    >      ARCH=$linux_arch CROSS_COMPILE=$target- \
++    >      INSTALL_HDR_PATH=$sysroot/usr
++
++
++GLIBC Headers and Preliminary Objects
++
++Using the cross-compiler we've just built, we can now configure GLIBC
++well enough to install the headers and build the object files that the
++full cross-compiler will need:
++
++    $ mkdir -p $obj/glibc-headers
++    $ cd $obj/glibc-headers
++    $ BUILD_CC=gcc \
++    > CC=$tools/bin/$target-gcc \
++    > CXX=$tools/bin/$target-g++ \
++    > AR=$tools/bin/$target-ar \
++    > RANLIB=$tools/bin/$target-ranlib \
++    > $src/glibc/libc/configure \
++    >     --prefix=/usr \
++    >     --with-headers=$sysroot/usr/include \
++    >     --build=$build \
++    >     --host=$target \
++    >     --disable-profile --without-gd --without-cvs \
++    >     --enable-add-ons=nptl,libidn,../ports
++
++The option '--prefix=/usr' may look strange, but you should never
++configure GLIBC with a prefix other than '/usr': in various places,
++GLIBC's build system checks whether the prefix is '/usr', and does
++special handling only if that is the case.  Unless you use this
++prefix, you will get a sysroot that does not use the standard Linux
++directory layouts and cannot be used as a basis for the root
++filesystem on your target system compatibly with normal GLIBC
++installations.
++
++The '--with-headers' option tells GLIBC where the Linux headers have
++been installed.
++
++The '--enable-add-ons=nptl,libidn,../ports' option tells GLIBC to look
++for the listed glibc add-ons. Most notably the ports add-on (located
++just above the libc sources in the GLIBC svn tree) is required to
++support ARM targets.
++
++We can now use the 'install-headers' makefile target to install the
++headers:
++
++    $ make install-headers install_root=$sysroot \
++    >                      install-bootstrap-headers=yes
++
++The 'install_root' variable indicates where the files should actually
++be installed; its value is treated as the parent of the '--prefix'
++directory we passed to the configure script, so the headers will go in
++'$sysroot/usr/include'.  The 'install-bootstrap-headers' variable
++requests special handling for certain tricky header files.
++
++Next, there are a few object files needed to link shared libraries,
++which we build and install by hand:
++
++    $ mkdir -p $sysroot/usr/lib
++    $ make csu/subdir_lib
++    $ cp csu/crt1.o csu/crti.o csu/crtn.o $sysroot/usr/lib
++
++Finally, 'libgcc_s.so' requires a 'libc.so' to link against.  However,
++since we will never actually execute its code, it doesn't matter what
++it contains.  So, treating '/dev/null' as a C source file, we produce
++a dummy 'libc.so' in one step:
++
++    $ $tools/bin/$target-gcc -nostdlib -nostartfiles -shared -x c /dev/null \
++    >                        -o $sysroot/usr/lib/libc.so
++
++
++The Second GCC
++
++With the GLIBC headers and selected object files installed, we can
++now build a GCC that is capable of compiling GLIBC.  We configure,
++build, and install the second GCC, again building only the C compiler,
++and avoiding libraries we won't use:
++
++    $ mkdir -p $obj/gcc2
++    $ cd $obj/gcc2
++    $ $src/$gccv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --with-sysroot=$sysroot \
++    >     --disable-libssp --disable-libgomp --disable-libmudflap \
++    >     --disable-libffi --disable-libquadmath \
++    >     --enable-languages=c
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install
++
++
++GLIBC, Complete
++
++With the second compiler built and installed, we're now ready for the
++full GLIBC build:
++
++    $ mkdir -p $obj/glibc
++    $ cd $obj/glibc
++    $ BUILD_CC=gcc \
++    > CC=$tools/bin/$target-gcc \
++    > CXX=$tools/bin/$target-g++ \
++    > AR=$tools/bin/$target-ar \
++    > RANLIB=$tools/bin/$target-ranlib \
++    > $src/glibc/libc/configure \
++    >     --prefix=/usr \
++    >     --with-headers=$sysroot/usr/include \
++    >     --with-kconfig=$obj/linux/scripts/kconfig \
++    >     --build=$build \
++    >     --host=$target \
++    >     --disable-profile --without-gd --without-cvs \
++    >     --enable-add-ons=nptl,libidn,../ports
++
++Note the additional '--with-kconfig' option. This tells GLIBC where to
++find the host config tools used by the kernel 'make config' and 'make
++menuconfig'.  These tools can be re-used by GLIBC for its own 'make
++*config' support, which will create 'option-groups.config' for you.
++But first make sure those tools have been built by running some
++dummy 'make *config' calls in the kernel directory:
++
++    $ cd $obj/linux
++    $ PATH=$tools/bin:$PATH make config \
++    >      ARCH=$linux_arch CROSS_COMPILE=$target- \
++    $ PATH=$tools/bin:$PATH make menuconfig \
++    >      ARCH=$linux_arch CROSS_COMPILE=$target- \
++
++Now we can configure and build the full GLIBC:
++
++    $ cd $obj/glibc
++    $ PATH=$tools/bin:$PATH make defconfig
++    $ PATH=$tools/bin:$PATH make menuconfig
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install install_root=$sysroot
++
++At this point, we have a complete GLIBC installation in '$sysroot',
++with header files, library files, and most of the C runtime startup
++files in place.
++
++
++The Third GCC
++
++Finally, we recompile GCC against this full installation, enabling
++whatever languages and libraries we would like to use:
++
++    $ mkdir -p $obj/gcc3
++    $ cd $obj/gcc3
++    $ $src/$gccv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --with-sysroot=$sysroot \
++    >     --enable-__cxa_atexit \
++    >     --disable-libssp --disable-libgomp --disable-libmudflap \
++    >     --enable-languages=c,c++
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install
++
++The '--enable-__cxa_atexit' option tells GCC what sort of C++
++destructor support to expect from the C library; it's required with
++GLIBC.
++
++And since GCC's installation process isn't designed to help construct
++sysroot trees, we must manually copy certain libraries into place in
++the sysroot.
++
++    $ cp -d $tools/$target/lib/libgcc_s.so* $sysroot/lib
++    $ cp -d $tools/$target/lib/libstdc++.so* $sysroot/usr/lib
++
++
++Trying Things Out
++
++At this point, '$tools' contains a cross toolchain ready to use
++the GLIBC installation in '$sysroot':
++
++    $ cat > hello.c <<EOF
++    > #include <stdio.h>
++    > int
++    > main (int argc, char **argv)
++    > {
++    >   puts ("Hello, world!");
++    >   return 0;
++    > }
++    > EOF
++    $ $tools/bin/$target-gcc -Wall hello.c -o hello
++    $ cat > c++-hello.cc <<EOF
++    > #include <iostream>
++    > int
++    > main (int argc, char **argv)
++    > {
++    >   std::cout << "Hello, C++ world!" << std::endl;
++    >   return 0;
++    > }
++    > EOF
++    $ $tools/bin/$target-g++ -Wall c++-hello.cc -o c++-hello
++
++
++We can use 'readelf' to verify that these are indeed executables for
++our target, using our dynamic linker:
++
++    $ $tools/bin/$target-readelf -hl hello
++    ELF Header:
++    ...
++      Type:                              EXEC (Executable file)
++      Machine:                           ARM
++
++    ...
++    Program Headers:
++      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
++      PHDR           0x000034 0x10000034 0x10000034 0x00100 0x00100 R E 0x4
++      INTERP         0x000134 0x00008134 0x00008134 0x00013 0x00013 R   0x1
++          [Requesting program interpreter: /lib/ld-linux.so.3]
++      LOAD           0x000000 0x00008000 0x00008000 0x0042c 0x0042c R E 0x8000
++    ...
++
++Looking at the dynamic section of the installed 'libgcc_s.so', we see
++that the 'NEEDED' entry for the C library does include the '.6'
++suffix, indicating that was linked against our fully build GLIBC, and
++not our dummy 'libc.so':
++
++    $ $tools/bin/$target-readelf -d $sysroot/lib/libgcc_s.so.1
++    Dynamic section at offset 0x1083c contains 24 entries:
++      Tag        Type                         Name/Value
++     0x00000001 (NEEDED)                     Shared library: [libc.so.6]
++     0x0000000e (SONAME)                     Library soname: [libgcc_s.so.1]
++    ...
++
++
++And on the target machine, we can run our programs:
++
++    $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \
++    > ./hello
++    Hello, world!
++    $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \
++    > ./c++-hello
++    Hello, C++ world!
+diff --git a/GLIBC.cross-testing b/GLIBC.cross-testing
+new file mode 100644
+index 0000000..b67b468
+--- /dev/null
++++ b/GLIBC.cross-testing
+@@ -0,0 +1,205 @@
++                                                        -*- mode: text -*-
++
++                      Cross-Testing With GLIBC
++                  Jim Blandy <jimb@codesourcery.com>
++
++
++Introduction
++
++Developers writing software for embedded systems often use a desktop
++or other similarly capable computer for development, but need to run
++tests on the embedded system, or perhaps on a simulator.  When
++configured for cross-compilation, the stock GNU C library simply
++disables running tests altogether: the command 'make tests' builds
++test programs, but does not run them.  GLIBC, however, provides
++facilities for compiling tests and generating data files on the build
++system, but running the test programs themselves on a remote system or
++simulator.
++
++
++Test environment requirements
++
++The test environment must meet certain conditions for GLIBC's
++cross-testing facilities to work:
++
++- Shared filesystems.  The 'build' system, on which you configure and
++  compile GLIBC, and the 'host' system, on which you intend to run
++  GLIBC, must share a filesystem containing the GLIBC build and
++  source trees.  Files must appear at the same paths on both systems.
++
++- Remote-shell like invocation.  There must be a way to run a program
++  on the host system from the build system, passing it properly quoted
++  command-line arguments, setting environment variables, and
++  inheriting the caller's standard input and output.
++
++
++Usage
++
++To use GLIBC's cross-testing support, provide values for the
++following Make variables when you invoke 'make':
++
++- cross-test-wrapper
++
++  This should be the name of the cross-testing wrapper command, along
++  with any arguments.
++
++- cross-localedef
++
++  This should be the name of a cross-capable localedef program, like
++  that included in the GLIBC 'localedef' module, along with any
++  arguments needed.
++
++These are each explained in detail below.
++
++
++The Cross-Testing Wrapper
++
++To run test programs reliably, the stock GNU C library takes care to
++ensure that test programs use the newly compiled dynamic linker and
++shared libraries, and never the host system's installed libraries.  To
++accomplish this, it runs the tests by explicitly invoking the dynamic
++linker from the build tree, passing it a list of build tree
++directories to search for shared libraries, followed by the name of
++the executable to run and its arguments.
++
++For example, where one might normally run a test program like this:
++
++    $ ./tst-foo arg1 arg2
++
++the GNU C library might run that program like this:
++
++    $ $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++(where $objdir is the path to the top of the build tree, and the
++trailing backslash indicates a continuation of the command).  In other
++words, each test program invocation is 'wrapped up' inside an explicit
++invocation of the dynamic linker, which must itself execute the test
++program, having loaded shared libraries from the appropriate
++directories.
++
++To support cross-testing, GLIBC allows the developer to optionally
++set the 'cross-test-wrapper' Make variable to another wrapper command,
++to which it passes the entire dynamic linker invocation shown above as
++arguments.  For example, if the developer supplies a wrapper of
++'my-wrapper hostname', then GLIBC would run the test above as
++follows:
++
++    $ my-wrapper hostname \
++      $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++The 'my-wrapper' command is responsible for executing the command
++given on the host system.
++
++Since tests are run in varying directories, the wrapper should either
++be in your command search path, or 'cross-test-wrapper' should give an
++absolute path for the wrapper.
++
++The wrapper must meet several requirements:
++
++- It must preserve the current directory.  As explained above, the
++  build directory tree must be visible on both the build and host
++  systems, at the same path.  The test wrapper must ensure that the
++  current directory it inherits is also inherited by the dynamic
++  linker (and thus the test program itself).
++
++- It must preserve environment variables' values.  Many GLIBC tests
++  set environment variables for test runs; in native testing, it
++  invokes programs like this:
++
++    $ GCONV_PATH=$objdir/iconvdata \
++      $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++  With the cross-testing wrapper, that invocation becomes:
++
++    $ GCONV_PATH=$objdir/iconvdata \
++      my-wrapper hostname \
++      $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++  Here, 'my-wrapper' must ensure that the value it sees for
++  'GCONV_PATH' will be seen by the dynamic linker, and thus 'tst-foo'
++  itself.  (The wrapper supplied with GLIBC simply preserves the
++  values of *all* enviroment variables, with a fixed set of
++  exceptions.)
++
++  If your wrapper is a shell script, take care to correctly propagate
++  environment variables whose values contain spaces and shell
++  metacharacters.
++
++- It must pass the command's arguments, unmodified.  The arguments
++  seen by the test program should be exactly those seen by the wrapper
++  (after whatever arguments are given to the wrapper itself).  The
++  GLIBC test framework performs all needed shell word splitting and
++  expansion (wildcard expansion, parameter substitution, and so on)
++  before invoking the wrapper; further expansion may break the tests.
++
++
++The 'cross-test-ssh.sh' script
++
++If you want to use 'ssh' (or something sufficiently similar) to run
++test programs on your host system, GLIBC includes a shell script,
++'scripts/cross-test-ssh.sh', which you can use as your wrapper
++command.  This script takes care of setting the test command's current
++directory, propagating environment variable values, and carrying
++command-line arguments, all across an 'ssh' connection.  You may even
++supply an alternative to 'ssh' on the command line, if needed.
++
++For more details, pass 'cross-test-ssh.sh' the '--help' option.
++
++
++The Cross-Compiling Locale Definition Command
++
++Some GLIBC tests rely on locales generated especially for the test
++process.  In a native configuration, these tests simply run the
++'localedef' command built by the normal GLIBC build process,
++'locale/localedef', to process and install their locales.  However, in
++a cross-compiling configuration, this 'localedef' is built for the
++host system, not the build system, and since it requires quite a bit
++of memory to run (we have seen it fail on systems with 64MiB of
++memory), it may not be practical to run it on the host system.
++
++If set, GLIBC uses the 'cross-localedef' Make variable as the command
++to run on the build system to process and install locales.  The
++localedef program built from the GLIBC 'localedef' module is
++suitable.
++
++The value of 'cross-localedef' may also include command-line arguments
++to be passed to the program; if you are using GLIBC's 'localedef',
++you may include endianness and 'uint32_t' alignment arguments here.
++
++
++Example
++
++In developing GLIBC's cross-testing facility, we invoked 'make' with
++the following script:
++
++    #!/bin/sh
++
++    srcdir=...
++    test_hostname=...
++    localedefdir=...
++    cross_gxx=...-g++
++
++    wrapper="$srcdir/scripts/cross-test-ssh.sh $test_hostname"
++    localedef="$localedefdir/localedef --little-endian --uint32-align=4"
++
++    make cross-test-wrapper="$wrapper" \
++         cross-localedef="$localedef" \
++         CXX="$cross_gxx" \
++         "$@"
++
++
++Other Cross-Testing Concerns
++
++Here are notes on some other issues which you may encounter in running
++the GLIBC tests in a cross-compiling environment:
++
++- Some tests require a C++ cross-compiler; you should set the 'CXX'
++  Make variable to the name of an appropriate cross-compiler.
++
++- Some tests require access to libstdc++.so.6 and libgcc_s.so.1; we
++  simply place copies of these libraries in the top GLIBC build
++  directory.
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch b/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch
new file mode 100644
index 0000000..dcb80f9
--- /dev/null
+++ b/recipes-core/glibc/glibc/0019-eglibc-Bring-Eglibc-option-group-infrastructure-to-g.patch
@@ -0,0 +1,1436 @@
+From aa7c5fe86d04584a9aed4dc40ba856c65a1ef9c4 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:45:18 +0000
+Subject: [PATCH 19/27] eglibc: Bring Eglibc option group infrastructure to
+ glibc
+
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ EGLIBC.option-groups              | 122 ++++++
+ Makefile                          |   1 +
+ config.make.in                    |   2 +
+ configure                         |  13 +
+ configure.ac                      |  10 +
+ option-groups.def                 | 868 ++++++++++++++++++++++++++++++++++++++
+ option-groups.defaults            |  47 +++
+ option-groups.mak                 |  41 ++
+ options-config/Makefile           |  55 +++
+ options-config/config-postproc.pl |  58 +++
+ options-config/config-preproc.pl  |   8 +
+ scripts/option-groups.awk         |  63 +++
+ 12 files changed, 1288 insertions(+)
+ create mode 100644 EGLIBC.option-groups
+ create mode 100644 option-groups.def
+ create mode 100644 option-groups.defaults
+ create mode 100644 option-groups.mak
+ create mode 100644 options-config/Makefile
+ create mode 100644 options-config/config-postproc.pl
+ create mode 100644 options-config/config-preproc.pl
+ create mode 100644 scripts/option-groups.awk
+
+diff --git a/EGLIBC.option-groups b/EGLIBC.option-groups
+new file mode 100644
+index 0000000..6a50b8d
+--- /dev/null
++++ b/EGLIBC.option-groups
+@@ -0,0 +1,122 @@
++                                                        -*- mode: text -*-
++
++              The EGLIBC Component Configuration System
++                  Jim Blandy <jimb@codesourcery.com>
++
++Introduction
++
++The GNU C library (GLIBC) provides a broad range of functionality,
++ranging from internationalization support to transcendental
++mathematical functions.  Its website boasts that "nearly all known and
++useful functions from any other C library are available."  This
++exhaustive approach has been one of GLIBC's strengths on desktop and
++server systems, but it has also given GLIBC a large footprint, both in
++memory and on disk, making it a challenge to use in embedded systems
++with limited resources.
++
++The Embedded GNU C library (EGLIBC) is a variant of the GNU C library
++designed to work well on embedded systems.  In particular, EGLIBC's
++component configuration system allows embedded developers to build
++customized versions of the library that include only the features
++their application uses, reducing its space requirements.
++
++EGLIBC's component configuration system categorizes the library's
++functions into "option groups", and allows you to include or exclude
++option groups individually.  Some option groups depend on others;
++EGLIBC tracks these relationships, and ensures that the selected
++configuration yields a functioning library.
++
++
++Consistent and Predictable Behavior
++
++A flexible configuration system is a mixed blessing: if the options
++offered are poorly designed, it can be hard to see which choices will
++have the desired effects, and choices with obscure consequences can
++make debugging difficult.  EGLIBC's configuration follows some general
++principles to reduce these risks:
++
++- EGLIBC has a single default configuration for each target
++  architecture.
++
++- In the default configuration, all option groups are enabled, and
++  EGLIBC is upwardly API- and ABI-compatible with GLIBC.
++
++- As much as possible, configurations only affect what functions are
++  present, not how they behave.  If the system works with an option
++  group disabled, it will still work with it enabled.
++
++- As much as possible, configurations only select option groups ---
++  they do not describe characteristics of the target architecture.
++
++These rules mean that you have a simple debugging strategy available
++if you suspect that your EGLIBC configuration might be the source of a
++problem: fall back to the default configuration, re-test, and then
++disable option groups one by one, until the problem reappears.
++
++
++The Option Groups
++
++To see the current full list of implemented option groups, refer to the
++file 'option-groups.def' at the top of the source tree, or run
++'make menuconfig' from the top-level build directory.
++
++The POSIX.1-2001 specification includes a suggested partition of all
++the functions in the POSIX C API into option groups: math functions
++like 'sin' and 'cos'; networking functions like 'socket' and
++'connect'; and so on.  EGLIBC could use this partitioning as the basis
++for future option groups.
++
++
++Implementation
++
++The EGLIBC component configuration system resembles the approach used
++by the Linux kernel to select device drivers, network protocols, and
++other features.  A file named 'option-groups.config' in the top-level
++build directory contains assignments to Make variables, each of which
++enables or disables a particular option group.  If the variable's
++value is set to 'y', then the option group is enabled; if it set to
++anything else, the option group is omitted.  The file
++'option-groups.defaults', at the top of the source tree, establishes
++default values for all variables; all option groups are enabled by
++default.
++
++For example, the following 'option-groups.config' would omit locale
++data, but include mathematical functions, and everything else:
++
++   OPTION_EGLIBC_LOCALES = n
++   OPTION_EGLIBC_LIBM = y
++
++Like the Linux kernel, EGLIBC supports a similar set of '*config' make
++targets to make it easier to create 'option-groups.config', with all
++dependencies between option groups automatically satisfied.  Run
++'make help' to see the list of supported make config targets.  For
++example, 'make menuconfig' will update the current config utilising a
++menu based program.
++
++The option group names and their type (boolean, int, hex, string), help
++description, and dependencies with other option groups, are described by
++'option-groups.def' at the top of the source tree, analogous to the
++'Kconfig' files in the Linux kernel.
++
++In general, each option group variable controls whether a given set of
++object files in EGLIBC is compiled and included in the final
++libraries, or omitted from the build.
++
++Each subdirectory's Makefile categorizes its routines, libraries, and
++executables by option group.  For example, EGLIBC's 'math/Makefile'
++places the 'libm' library in the OPTION_EGLIBC_LIBM group as follows:
++
++   extra-libs-$(OPTION_EGLIBC_LIBM) := libm
++
++Finally, common code in 'Makerules' cites the value of the variable
++'extra-libs-y', selecting only those libraries that belong to enabled
++option groups to be built.
++
++
++Current Status and Future Directions
++
++The EGLIBC component configuration system described here is still
++under development.
++
++We have used the system to subset some portions of EGLIBC's
++Index: libc/configure.ac
+diff --git a/Makefile b/Makefile
+index 658ccfa..f906391 100644
+--- a/Makefile
++++ b/Makefile
+@@ -24,6 +24,7 @@ endif
+ 
+ include Makeconfig
+ 
++include options-config/Makefile
+ 
+ # This is the default target; it makes everything except the tests.
+ .PHONY: all
+diff --git a/config.make.in b/config.make.in
+index a9f5696..294f8d1 100644
+--- a/config.make.in
++++ b/config.make.in
+@@ -47,6 +47,8 @@ c++-sysincludes = @CXX_SYSINCLUDES@
+ all-warnings = @all_warnings@
+ enable-werror = @enable_werror@
+ 
++kconfig_tools = @KCONFIG_TOOLS@
++
+ have-z-combreloc = @libc_cv_z_combreloc@
+ have-z-execstack = @libc_cv_z_execstack@
+ have-Bgroup = @libc_cv_Bgroup@
+diff --git a/configure b/configure
+index 7d7299a..4116404 100755
+--- a/configure
++++ b/configure
+@@ -641,6 +641,7 @@ INSTALL_INFO
+ PERL
+ BASH_SHELL
+ libc_cv_gcc_static_libgcc
++KCONFIG_TOOLS
+ CXX_SYSINCLUDES
+ SYSINCLUDES
+ AUTOCONF
+@@ -755,6 +756,7 @@ with_fp
+ with_binutils
+ with_selinux
+ with_headers
++with_kconfig
+ with_default_link
+ enable_sanity_checks
+ enable_shared
+@@ -1459,6 +1461,9 @@ Optional Packages:
+   --with-selinux          if building with SELinux support
+   --with-headers=PATH     location of system headers to use (for example
+                           /usr/src/linux/include) [default=compiler default]
++  --with-kconfig=PATH     location of kconfig tools to use (from Linux kernel
++                          builds) to re-use for configuring EGLIBC option
++                          groups
+   --with-default-link     do not use explicit linker scripts
+   --with-cpu=CPU          select code for CPU variant
+ 
+@@ -3517,6 +3522,14 @@ fi
+ 
+ 
+ 
++# Check whether --with-kconfig was given.
++if test "${with_kconfig+set}" = set; then
++  withval=$with_kconfig; KCONFIG_TOOLS=$withval
++else
++  KCONFIG_TOOLS=''
++fi
++
++
+ 
+ # Check whether --with-default-link was given.
+ if test "${with_default_link+set}" = set; then :
+diff --git a/configure.ac b/configure.ac
+index a467a69..fc0ed4d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -136,6 +136,16 @@ AC_ARG_WITH([headers],
+ 	    [sysheaders=''])
+ AC_SUBST(sysheaders)
+ 
++AC_ARG_WITH([kconfig],
++	    AC_HELP_STRING([--with-kconfig=PATH],
++			   [location of kconfig tools to use (from Linux
++			    kernel builds) to re-use for configuring EGLIBC
++			    option groups]),
++	    [KCONFIG_TOOLS=$withval],
++	    [KCONFIG_TOOLS=''])
++AC_SUBST(KCONFIG_TOOLS)
++
++
+ AC_SUBST(use_default_link)
+ AC_ARG_WITH([default-link],
+ 	    AC_HELP_STRING([--with-default-link],
+diff --git a/option-groups.def b/option-groups.def
+new file mode 100644
+index 0000000..6aebd94
+--- /dev/null
++++ b/option-groups.def
+@@ -0,0 +1,868 @@
++# This file documents the option groups EGLIBC currently supports, in
++# a format akin to the Linux Kconfig system's.  The syntax may change
++# over time.
++#
++# An entry of the form:
++#
++#   config GROUP_NAME
++#       bool "one-line explanation of what this option group controls"
++#       help
++#           Multi-line help explaining the option group's meaning in
++#           some detail, terminated by indentation level.
++#
++# defines an option group whose variable is GROUP_NAME, with
++# meaningful values 'y' (enabled) and 'n' (disabled).  The
++# documentation is formatted to be consumed by some sort of
++# interactive configuration interface, but EGLIBC doesn't have such an
++# interface yet.
++#
++# An option may have a 'depends on' line, indicating which other options
++# must also be enabled if this option is.  At present, EGLIBC doesn't
++# check that these dependencies are satisfied.
++#
++# Option group variables get their default values from the file
++# 'option-groups.defaults', in the top directory of the EGLIBC source
++# tree.  By default, all EGLIBC option groups are enabled --- their
++# variables are set to 'y'.
++#
++# After including 'option-groups.defaults', the EGLIBC make machinery
++# includes the file 'option-groups.config' from the top of the build
++# tree, if it is present.  Developers can place assignments to option
++# group variables in that file to override the defaults.  For example,
++# to disable an option group, place a line of the form:
++#
++#    OPTION_GROUP_NAME = n
++#
++# in 'option-groups.config' at the top of your build tree.  To
++# explicitly enable an option group, you may also write:
++#
++#    OPTION_GROUP_NAME = y
++#
++# although this simply reestablishes the value already set by
++# 'option-groups.defaults'.
++
++config EGLIBC_ADVANCED_INET6
++   bool "IPv6 Advanced Sockets API support (RFC3542)"
++   depends on EGLIBC_INET
++   help
++       This option group includes the functions specified by RFC 3542,
++       "Advanced Sockets Application Program Interface (API) for
++       IPv6".
++
++       This option group includes the following functions:
++
++         inet6_opt_append
++         inet6_opt_find
++         inet6_opt_finish
++         inet6_opt_get_val
++         inet6_opt_init
++         inet6_option_alloc
++         inet6_option_append
++         inet6_option_find
++         inet6_option_init
++         inet6_option_next
++         inet6_option_space
++         inet6_opt_next
++         inet6_opt_set_val
++         inet6_rth_add
++         inet6_rth_getaddr
++         inet6_rth_init
++         inet6_rth_reverse
++         inet6_rth_segments
++         inet6_rth_space
++
++config EGLIBC_BACKTRACE
++   bool "Functions for producing backtraces"
++   help
++       This option group includes functions for producing a list of
++       the function calls that are currently active in a thread, from
++       within the thread itself.  These functions are often used
++       within signal handlers, to produce diagnostic output.
++
++       This option group includes the following functions:
++
++         backtrace
++         backtrace_symbols
++         backtrace_symbols_fd
++
++config EGLIBC_BIG_MACROS
++   bool "Use extensive inline code"
++   help
++       This option group specifies whether certain pieces of code
++       should be inlined to achieve maximum speed.  If this option
++       group is not selected, function calls will be used instead,
++       hence reducing the library footprint.
++
++config EGLIBC_BSD
++   bool "BSD-specific functions, and their compatibility stubs"
++   help
++       This option group includes functions specific to BSD kernels.
++       A number of these functions have stub versions that are also
++       included in libraries built for non-BSD systems for
++       compatibility.
++
++       This option group includes the following functions:
++
++         chflags
++         fchflags
++         lchmod
++         revoke
++         setlogin
++
++config EGLIBC_CXX_TESTS
++   bool "Tests that link against the standard C++ library."
++   depends on POSIX_WIDE_CHAR_DEVICE_IO && EGLIBC_LIBM
++   help
++       This option group does not include any C library functions;
++       instead, it controls which EGLIBC tests an ordinary 'make
++       tests' runs.  With this group disabled, tests that would
++       normally link against the standard C++ library are not
++       run.
++
++       The standard C++ library depends on the math library 'libm' and
++       the wide character I/O functions included in EGLIBC.  So those
++       option groups must be enabled if this test is enabled.
++
++config EGLIBC_CATGETS
++   bool "Functions for accessing message catalogs"
++   depends on EGLIBC_LOCALE_CODE
++   help
++       This option group includes functions for accessing message
++       catalogs: catopen, catclose, and catgets.
++
++       This option group depends on the EGLIBC_LOCALE_CODE
++       option group.
++
++config EGLIBC_CHARSETS
++   bool "iconv/gconv character set conversion libraries"
++   help
++       This option group includes support for character sets other
++       than ASCII (ANSI_X3.4-1968) and Unicode and ISO-10646 in their
++       various encodings.  This affects both the character sets
++       supported by the wide and multibyte character functions, and
++       those supported by the 'iconv' functions.
++
++       With this option group disabled, EGLIBC supports only the
++       following character sets:
++
++          ANSI_X3.4         - ASCII
++          ANSI_X3.4-1968
++          ANSI_X3.4-1986
++          ASCII
++          CP367
++          CSASCII
++          IBM367
++          ISO-IR-6
++          ISO646-US
++          ISO_646.IRV:1991
++          OSF00010020
++          US
++          US-ASCII
++
++          10646-1:1993      - ISO 10646, in big-endian UCS4 form
++          10646-1:1993/UCS4
++          CSUCS4
++          ISO-10646
++          ISO-10646/UCS4
++          OSF00010104
++          OSF00010105
++          OSF00010106
++          UCS-4
++          UCS-4BE
++          UCS4
++
++          UCS-4LE           - ISO 10646, in little-endian UCS4 form
++
++          ISO-10646/UTF-8   - ISO 10646, in UTF-8 form
++          ISO-10646/UTF8
++          ISO-IR-193
++          OSF05010001
++          UTF-8
++          UTF8
++
++          ISO-10646/UCS2    - ISO 10646, in target-endian UCS2 form
++          OSF00010100
++          OSF00010101
++          OSF00010102
++          UCS-2
++          UCS2
++
++          UCS-2BE           - ISO 10646, in big-endian UCS2 form
++          UNICODEBIG
++
++          UCS-2LE           - ISO 10646, in little-endian UCS2 form
++          UNICODELITTLE
++
++          WCHAR_T           - EGLIBC's internal form (target-endian,
++                              32-bit ISO 10646)
++
++config EGLIBC_CRYPT
++   bool "Encryption library"
++   help
++       This option group includes the `libcrypt' library which
++       provides functions for one-way encryption.  Supported
++       encryption algorithms include MD5, SHA-256, SHA-512 and DES.
++
++config EGLIBC_CRYPT_UFC
++   bool "Ultra fast `crypt' implementation"
++   depends on EGLIBC_CRYPT
++   help
++       This option group provides ultra fast DES-based implementation of
++       the `crypt' function.  When this option group is disabled,
++       (a) the library will not provide the setkey[_r] and encrypt[_r]
++       functions and (b) the crypt[_r] function will return NULL and set the
++       errno to ENOSYS if /salt/ passed does not correspond to either MD5,
++       SHA-256 or SHA-512 algorithm.
++
++config EGLIBC_DB_ALIASES
++   bool "Functions for accessing the mail aliases database"
++   help
++       This option group includues functions for looking up mail
++       aliases in '/etc/aliases' or using nsswitch.  It includes the
++       following functions:
++
++         endaliasent
++         getaliasbyname
++         getaliasbyname_r
++         getaliasent
++         getaliasent_r
++         setaliasent
++
++       When this option group is disabled, the NSS service libraries
++       also lack support for querying their mail alias tables.
++
++config EGLIBC_ENVZ
++   bool "Functions for handling envz-style environment vectors."
++   help
++       This option group contains functions for creating and operating
++       on envz vectors.  An "envz vector" is a vector of strings in a
++       contiguous block of memory, where each element is a name-value
++       pair, and elements are separated from their neighbors by null
++       characters.
++
++       This option group includes the following functions:
++
++        envz_add        envz_merge
++        envz_entry      envz_remove
++        envz_get        envz_strip
++
++config EGLIBC_FCVT
++   bool "Functions for converting floating-point numbers to strings"
++   help
++       This option group includes functions for converting
++       floating-point numbers to strings.
++
++       This option group includes the following functions:
++
++         ecvt           qecvt
++	 ecvt_r		qecvt_r
++         fcvt		qfcvt
++	 fcvt_r		qfcvt_r
++         gcvt		qgcvt
++
++config EGLIBC_FMTMSG
++   bool "Functions for formatting messages"
++   help
++       This option group includes the following functions:
++
++         addseverity    fmtmsg
++
++config EGLIBC_FSTAB
++   bool "Access functions for 'fstab'"
++   help
++       This option group includes functions for reading the mount
++       point specification table, '/etc/fstab'.  These functions are
++       not included in the POSIX standard, which provides the
++       'getmntent' family of functions instead.
++
++       This option group includes the following functions:
++
++         endfsent       getfsspec
++         getfsent       setfsent
++         getfsfile
++
++config EGLIBC_FTRAVERSE
++   bool "Functions for traversing file hierarchies"
++   help
++       This option group includes functions for traversing file
++       UNIX file hierachies.
++
++       This option group includes the following functions:
++
++         fts_open       ftw
++	 fts_read	nftw
++         fts_children	ftw64
++	 fts_set	nftw64
++         fts_close
++
++config EGLIBC_GETLOGIN
++   bool "The getlogin function"
++   depends on EGLIBC_UTMP
++   help
++       This function group includes the 'getlogin' and 'getlogin_r'
++       functions, which return the user name associated by the login
++       activity with the current process's controlling terminal.
++
++       With this option group disabled, the 'glob' function will not
++       fall back on 'getlogin' to find the user's login name for tilde
++       expansion when the 'HOME' environment variable is not set.
++
++config EGLIBC_IDN
++   bool "International domain names support"
++   help
++       This option group includes the `libcidn' library which
++       provides support for international domain names.
++
++config EGLIBC_INET
++   bool "Networking support"
++   help
++       This option group includes networking-specific functions and
++       data.  With EGLIBC_INET disabled, the EGLIBC
++       installation and API changes as follows:
++
++       - The following libraries are not installed:
++
++         libnsl
++         libnss_compat
++         libnss_dns
++         libnss_hesiod
++         libnss_nis
++         libnss_nisplus
++         libresolv
++
++       - The following functions and variables are omitted from libc:
++
++         authdes_create           hstrerror              svc_fdset
++         authdes_getucred         htonl                  svc_getreq
++         authdes_pk_create        htons                  svc_getreq_common
++         authnone_create          if_freenameindex       svc_getreq_poll
++         authunix_create          if_indextoname         svc_getreqset
++         authunix_create_default  if_nameindex           svc_max_pollfd
++         bindresvport             if_nametoindex         svc_pollfd
++         callrpc                  in6addr_any            svcraw_create
++         cbc_crypt                in6addr_loopback       svc_register
++         clnt_broadcast           inet6_opt_append       svc_run
++         clnt_create              inet6_opt_find         svc_sendreply
++         clnt_pcreateerror        inet6_opt_finish       svctcp_create
++         clnt_perrno              inet6_opt_get_val      svcudp_bufcreate
++         clnt_perror              inet6_opt_init         svcudp_create
++         clntraw_create           inet6_option_alloc     svcudp_enablecache
++         clnt_spcreateerror       inet6_option_append    svcunix_create
++         clnt_sperrno             inet6_option_find      svcunixfd_create
++         clnt_sperror             inet6_option_init      svc_unregister
++         clnttcp_create           inet6_option_next      user2netname
++         clntudp_bufcreate        inet6_option_space     xdecrypt
++         clntudp_create           inet6_opt_next         xdr_accepted_reply
++         clntunix_create          inet6_opt_set_val      xdr_array
++         des_setparity            inet6_rth_add          xdr_authdes_cred
++         ecb_crypt                inet6_rth_getaddr      xdr_authdes_verf
++         endaliasent              inet6_rth_init         xdr_authunix_parms
++         endhostent               inet6_rth_reverse      xdr_bool
++         endnetent                inet6_rth_segments     xdr_bytes
++         endnetgrent              inet6_rth_space        xdr_callhdr
++         endprotoent              inet_addr              xdr_callmsg
++         endrpcent                inet_aton              xdr_char
++         endservent               inet_lnaof             xdr_cryptkeyarg
++         ether_aton               inet_makeaddr          xdr_cryptkeyarg2
++         ether_aton_r             inet_netof             xdr_cryptkeyres
++         ether_hostton            inet_network           xdr_des_block
++         ether_line               inet_nsap_addr         xdr_double
++         ether_ntoa               inet_nsap_ntoa         xdr_enum
++         ether_ntoa_r             inet_ntoa              xdr_float
++         ether_ntohost            inet_ntop              xdr_free
++         freeaddrinfo             inet_pton              xdr_getcredres
++         freeifaddrs              innetgr                xdr_hyper
++         gai_strerror             iruserok               xdr_int
++         getaddrinfo              iruserok_af            xdr_int16_t
++         getaliasbyname           key_decryptsession     xdr_int32_t
++         getaliasbyname_r         key_decryptsession_pk  xdr_int64_t
++         getaliasent              key_encryptsession     xdr_int8_t
++         getaliasent_r            key_encryptsession_pk  xdr_keybuf
++         gethostbyaddr            key_gendes             xdr_key_netstarg
++         gethostbyaddr_r          key_get_conv           xdr_key_netstres
++         gethostbyname            key_secretkey_is_set   xdr_keystatus
++         gethostbyname2           key_setnet             xdr_long
++         gethostbyname2_r         key_setsecret          xdr_longlong_t
++         gethostbyname_r          netname2host           xdrmem_create
++         gethostent               netname2user           xdr_netnamestr
++         gethostent_r             ntohl                  xdr_netobj
++         getifaddrs               ntohs                  xdr_opaque
++         getipv4sourcefilter      passwd2des             xdr_opaque_auth
++         get_myaddress            pmap_getmaps           xdr_pmap
++         getnameinfo              pmap_getport           xdr_pmaplist
++         getnetbyaddr             pmap_rmtcall           xdr_pointer
++         getnetbyaddr_r           pmap_set               xdr_quad_t
++         getnetbyname             pmap_unset             xdrrec_create
++         getnetbyname_r           rcmd                   xdrrec_endofrecord
++         getnetent                rcmd_af                xdrrec_eof
++         getnetent_r              registerrpc            xdrrec_skiprecord
++         getnetgrent              res_init               xdr_reference
++         getnetgrent_r            rexec                  xdr_rejected_reply
++         getnetname               rexec_af               xdr_replymsg
++         getprotobyname           rexecoptions           xdr_rmtcall_args
++         getprotobyname_r         rpc_createerr          xdr_rmtcallres
++         getprotobynumber         rresvport              xdr_short
++         getprotobynumber_r       rresvport_af           xdr_sizeof
++         getprotoent              rtime                  xdrstdio_create
++         getprotoent_r            ruserok                xdr_string
++         getpublickey             ruserok_af             xdr_u_char
++         getrpcbyname             ruserpass              xdr_u_hyper
++         getrpcbyname_r           setaliasent            xdr_u_int
++         getrpcbynumber           sethostent             xdr_uint16_t
++         getrpcbynumber_r         setipv4sourcefilter    xdr_uint32_t
++         getrpcent                setnetent              xdr_uint64_t
++         getrpcent_r              setnetgrent            xdr_uint8_t
++         getrpcport               setprotoent            xdr_u_long
++         getsecretkey             setrpcent              xdr_u_longlong_t
++         getservbyname            setservent             xdr_union
++         getservbyname_r          setsourcefilter        xdr_unixcred
++         getservbyport            svcauthdes_stats       xdr_u_quad_t
++         getservbyport_r          svcerr_auth            xdr_u_short
++         getservent               svcerr_decode          xdr_vector
++         getservent_r             svcerr_noproc          xdr_void
++         getsourcefilter          svcerr_noprog          xdr_wrapstring
++         h_errlist                svcerr_progvers        xencrypt
++         h_errno                  svcerr_systemerr       xprt_register
++         herror                   svcerr_weakauth        xprt_unregister
++         h_nerr                   svc_exit
++         host2netname             svcfd_create
++
++       - The rpcgen, nscd, and rpcinfo commands are not installed.
++
++       - The 'rpc' file (a text file listing RPC services) is not installed.
++
++       Socket-related system calls do not fall in this option group,
++       because many are also used for other inter-process
++       communication mechanisms.  For example, the 'syslog' routines
++       use Unix-domain sockets to communicate with the syslog daemon;
++       syslog is valuable in non-networked contexts.
++
++config EGLIBC_INET_ANL
++   bool "Asynchronous name lookup"
++   depends on EGLIBC_INET
++   help
++       This option group includes the `libanl' library which
++       provides support for asynchronous name lookup.
++
++config EGLIBC_LIBM
++   bool "libm (math library)"
++   help
++       This option group includes the 'libm' library, containing
++       mathematical functions.  If this option group is omitted, then
++       an EGLIBC installation does not include shared or unshared versions
++       of the math library.
++
++       Note that this does not remove all floating-point related
++       functionality from EGLIBC; for example, 'printf' and 'scanf'
++       can still print and read floating-point values with this option
++       group disabled.
++
++       Note that the ISO Standard C++ library 'libstdc++' depends on
++       EGLIBC's math library 'libm'.  If you disable this option
++       group, you will not be able to build 'libstdc++' against the
++       resulting EGLIBC installation.
++
++config EGLIBC_LOCALES
++   bool "Locale definitions"
++   help
++       This option group includes all locale definitions other than
++       that for the "C" locale.  If this option group is omitted, then
++       only the "C" locale is supported.
++
++
++config EGLIBC_LOCALE_CODE
++   bool "Locale functions"
++   depends on POSIX_C_LANG_WIDE_CHAR
++   help
++       This option group includes locale support functions, programs,
++       and libraries.  With EGLIBC_LOCALE_CODE disabled,
++       EGLIBC supports only the 'C' locale (also known as 'POSIX'),
++       and ignores the settings of the 'LANG' and 'LC_*' environment
++       variables.
++
++       With EGLIBC_LOCALE_CODE disabled, the following
++       functions are omitted from libc:
++
++         duplocale   localeconv  nl_langinfo    rpmatch  strfmon_l
++         freelocale  newlocale   nl_langinfo_l  strfmon  uselocale
++
++       Furthermore, only the LC_CTYPE and LC_TIME categories of the
++       standard "C" locale are available.
++
++       The EGLIBC_CATGETS option group depends on this option group.
++
++
++config EGLIBC_MEMUSAGE
++   bool "Memory profiling library"
++   help
++       This option group includes the `libmemusage' library and
++       the `memusage' and `memusagestat' utilities.
++       These components provide memory profiling functions.
++
++config EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++   int "Memory profiling library buffer size"
++   depends on EGLIBC_MEMUSAGE
++   default "32768"
++   help
++       Libmemusage library buffers the profiling data in memory
++       before writing it out to disk.  By default, the library
++       allocates 1.5M buffer, which can be substantial for some
++       systems.  EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE option
++       allows to change the default buffer size.  It specifies
++       the number of entries the buffer should have.
++       On most architectures one buffer entry amounts to 48 bytes,
++       so setting this option to the value of 512 will reduce the size of
++       the memory buffer to 24K.
++
++config EGLIBC_NIS
++   bool "Support for NIS, NIS+, and the special 'compat' services."
++   depends on EGLIBC_INET && EGLIBC_SUNRPC
++   help
++       This option group includes the NIS, NIS+, and 'compat' Name
++       Service Switch service libraries.  When it is disabled, those
++       services libraries are not installed; you should remove any
++       references to them from your 'nsswitch.conf' file.
++
++       This option group depends on the EGLIBC_INET option
++       group; you must enable that to enable this option group.
++
++config EGLIBC_NSSWITCH
++   bool "Name service switch (nsswitch) support"
++   help
++       This option group includes support for the 'nsswitch' facility.
++       With this option group enabled, all EGLIBC functions for
++       accessing various system databases (passwords and groups;
++       networking; aliases; public keys; and so on) consult the
++       '/etc/nsswitch.conf' configuration file to decide how to handle
++       queries.
++
++       With this option group disabled, EGLIBC uses a fixed list of
++       services to satisfy queries on each database, as requested by
++       configuration files specified when EGLIBC is built.  Your
++       'option-groups.config' file must set the following two
++       variables:
++
++config EGLIBC_NSSWITCH_FIXED_CONFIG
++   string "Nsswitch fixed config filename"
++   depends on !EGLIBC_NSSWITCH
++   default ""
++   help
++          Set this to the name of a file whose contents observe the
++          same syntax as an ordinary '/etc/nsswitch.conf' file.  The
++          EGLIBC build process parses this file just as EGLIBC would
++          at run time if EGLIBC_NSSWITCH were enabled, and
++          produces a C library that uses the nsswitch service
++          libraries to search for database entries as this file
++          specifies, instead of consulting '/etc/nsswitch.conf' at run
++          time.
++
++          This should be an absolute filename.  The EGLIBC build
++          process may use it from several different working
++          directories.  It may include references to Makefile
++          variables like 'common-objpfx' (the top of the build tree,
++          with a trailing slash), or '..' (the top of the source tree,
++          with a trailing slash).
++
++          The EGLIBC source tree includes a sample configuration file
++          named 'nss/fixed-nsswitch.conf'; for simple configurations,
++          you will probably want to delete references to databases not
++          needed on your system.
++
++config EGLIBC_NSSWITCH_FIXED_FUNCTIONS
++   string "Nsswitch fixed functions filename"
++   depends on !EGLIBC_NSSWITCH
++   default ""
++   help
++          The EGLIBC build process uses this file to decide which
++          functions to make available from which service libraries.
++          The file 'nss/fixed-nsswitch.functions' serves as a sample
++          configuration file for this setting, and explains its syntax
++          and meaning in more detail.
++
++          This should be an absolute file name.  The EGLIBC build
++          process may use it from several different working
++          directories.  It may include references to Makefile
++          variables like 'common-objpfx' (the top of the build tree,
++          with a trailing slash), or '..' (the top of the source tree,
++          with a trailing slash).
++
++          Be sure to mention each function in each service you wish to
++          use.  If you do not mention a service's function here, the
++          EGLIBC database access functions will not find it, even if
++          it is listed in the EGLIBC_NSSWITCH_FIXED_CONFIG
++          file.
++
++          In this arrangement, EGLIBC will not use the 'dlopen' and
++          'dlsym' functions to find database access functions.  Instead,
++          libc hard-codes references to the service libraries' database
++          access functions.  You must explicitly link your program
++          against the name service libraries (those whose names start
++          with 'libnss_', in the sysroot's '/lib' directory) whose
++          functions you intend to use.  This arrangement helps
++          system-wide static analysis tools decide which functions a
++          system actually uses.
++
++          Note that some nsswitch service libraries require other option
++          groups to be enabled; for example, the EGLIBC_INET
++          option group must be enabled to use the 'libnss_dns.so.2'
++          service library, which uses the Domain Name System network
++          protocol to answer queries.
++
++config EGLIBC_RCMD
++   bool "Support for 'rcmd' and related library functions"
++   depends on EGLIBC_INET
++   help
++      This option group includes functions for running commands on
++      remote machines via the 'rsh' protocol, and doing authentication
++      related to those functions.  This also includes functions that
++      use the 'rexec' protocol.
++
++      This option group includes the following functions:
++
++        rcmd            ruserok
++        rcmd_af         ruserok_af
++        rexec           iruserok
++        rexec_af        iruserok_af
++        rresvport       ruserpass
++        rresvport_af
++
++config EGLIBC_RTLD_DEBUG
++   bool "Runtime linker debug print outs"
++   help
++      This option group enables debug output of the runtime linker
++      which is activated via LD_DEBUG and LD_TRACE_PRELINKING
++      environment variables.  Disabling this option group yields
++      a smaller runtime linker binary.
++      BEWARE: Disabling this option group is likely to break
++      the `ldd' utility which may also be used by the prelinker.
++      In particular, the `--unused' ldd option will not work correctly.
++
++config EGLIBC_SPAWN
++   bool "Support for POSIX posix_spawn functions"
++   help
++      This option group includes the POSIX functions for executing
++      programs in child processes without using 'fork' or 'vfork'.
++
++      This option group includes the following functions:
++
++        posix_spawn
++        posix_spawnattr_destroy
++        posix_spawnattr_getflags
++        posix_spawnattr_getpgroup
++        posix_spawnattr_getschedparam
++        posix_spawnattr_getschedpolicy
++        posix_spawnattr_getsigdefault
++        posix_spawnattr_getsigmask
++        posix_spawnattr_init
++        posix_spawnattr_setflags
++        posix_spawnattr_setpgroup
++        posix_spawnattr_setschedparam
++        posix_spawnattr_setschedpolicy
++        posix_spawnattr_setsigdefault
++        posix_spawnattr_setsigmask
++        posix_spawn_file_actions_addclose
++        posix_spawn_file_actions_adddup2
++        posix_spawn_file_actions_addopen
++        posix_spawn_file_actions_destroy
++        posix_spawn_file_actions_init
++        posix_spawnp
++
++      This option group also provides the ability for the iconv,
++      localedef, and locale programs to operate transparently on
++      compressed charset definitions.  When this option group is
++      disabled, those programs will only operate on uncompressed
++      charmap files.
++
++config EGLIBC_STREAMS
++   bool "Support for accessing STREAMS."
++   help
++      This option group includes functions for reading and writing
++      messages to and from STREAMS.  The STREAMS interface provides a
++      uniform mechanism for implementing networking services and other
++      character-based I/O.  (STREAMS are not to be confused with
++      <stdio.h> FILE objects, also called 'streams'.)
++
++      This option group includes the following functions:
++
++        getmsg          putpmsg
++        getpmsg         fattach
++        isastream       fdetach
++        putmsg
++
++config EGLIBC_SUNRPC
++   bool "Support for the Sun 'RPC' protocol."
++   depends on EGLIBC_INET
++   help
++      This option group includes support for the Sun RPC protocols,
++      including the 'rpcgen' and 'rpcinfo' programs.
++
++config EGLIBC_UTMP
++    bool "Older access functions for 'utmp' login records"
++    help
++       This option group includes the older 'utent' family of
++       functions for accessing user login records in the 'utmp' file.
++       POSIX omits these functions in favor of the 'utxent' family,
++       and they are obsolete on systems other than Linux.
++
++       This option group includes the following functions:
++
++         endutent
++         getutent
++         getutent_r
++         getutid
++         getutid_r
++         getutline
++         getutline_r
++         logwtmp
++         pututline
++         setutent
++         updwtmp
++         utmpname
++
++       This option group includes the following libraries:
++
++         libutil.so (and libutil.a)
++
++config EGLIBC_UTMPX
++    bool "POSIX access functions for 'utmp' login records"
++    depends on EGLIBC_UTMP
++    help
++       This option group includes the POSIX functions for reading and
++       writing user login records in the 'utmp' file (usually
++       '/var/run/utmp').  The POSIX functions operate on 'struct
++       utmpx' structures, as opposed to the family of older 'utent'
++       functions, which operate on 'struct utmp' structures.
++
++       This option group includes the following functions:
++
++         endutxent
++         getutmp
++         getutmpx
++         getutxent
++         getutxid
++         getutxline
++         pututxline
++         setutxent
++         updwtmpx
++         utmpxname
++
++config EGLIBC_WORDEXP
++    bool "Shell-style word expansion"
++    help
++        This option group includes the 'wordexp' function for
++        performing word expansion in the manner of the shell, and the
++        accompanying 'wordfree' function.
++
++config POSIX_C_LANG_WIDE_CHAR
++    bool "ISO C library wide character functions, excluding I/O"
++    help
++        This option group includes the functions defined by the ISO C
++        standard for working with wide and multibyte characters in
++        memory.  Functions for reading and writing wide and multibyte
++        characters from and to files call in the
++        POSIX_WIDE_CHAR_DEVICE_IO option group.
++
++        This option group includes the following functions:
++
++          btowc         mbsinit       wcscspn       wcstoll
++          iswalnum      mbsrtowcs     wcsftime      wcstombs
++          iswalpha      mbstowcs      wcslen        wcstoul
++          iswblank      mbtowc        wcsncat       wcstoull
++          iswcntrl      swprintf      wcsncmp       wcstoumax
++          iswctype      swscanf       wcsncpy       wcsxfrm
++          iswdigit      towctrans     wcspbrk       wctob
++          iswgraph      towlower      wcsrchr       wctomb
++          iswlower      towupper      wcsrtombs     wctrans
++          iswprint      vswprintf     wcsspn        wctype
++          iswpunct      vswscanf      wcsstr        wmemchr
++          iswspace      wcrtomb       wcstod        wmemcmp
++          iswupper      wcscat        wcstof        wmemcpy
++          iswxdigit     wcschr        wcstoimax     wmemmove
++          mblen         wcscmp        wcstok        wmemset
++          mbrlen        wcscoll       wcstol
++          mbrtowc       wcscpy        wcstold
++
++config POSIX_REGEXP
++    bool "Regular expressions"
++    help
++        This option group includes the POSIX regular expression
++        functions, and the associated non-POSIX extensions and
++        compatibility functions.
++
++        With POSIX_REGEXP disabled, the following functions are
++        omitted from libc:
++
++          re_comp                 re_max_failures         regcomp
++          re_compile_fastmap      re_search               regerror
++          re_compile_pattern      re_search_2             regexec
++          re_exec                 re_set_registers        regfree
++          re_match                re_set_syntax           rpmatch
++          re_match_2              re_syntax_options
++
++        Furthermore, the compatibility regexp interface defined in the
++        <regexp.h> header file, 'compile', 'step', and 'advance', is
++        omitted.
++
++config POSIX_REGEXP_GLIBC
++    bool "Regular expressions from GLIBC"
++    depends on POSIX_REGEXP
++    help
++	This option group specifies which regular expression
++        library to use.  The choice is between regex
++        implementation from GLIBC and regex implementation from
++        libiberty.  The GLIBC variant is fully POSIX conformant and
++        optimized for speed; regex from libiberty is more than twice
++        as small while still is enough for most practical purposes.
++
++config POSIX_WIDE_CHAR_DEVICE_IO
++    bool "Input and output functions for wide characters"
++    depends on POSIX_C_LANG_WIDE_CHAR
++    help
++        This option group includes functions for reading and writing
++        wide characters to and from <stdio.h> streams.
++
++        This option group includes the following functions:
++
++          fgetwc        fwprintf      putwchar      vwscanf
++          fgetws        fwscanf       ungetwc       wprintf
++          fputwc        getwc         vfwprintf     wscanf
++          fputws        getwchar      vfwscanf
++          fwide         putwc         vwprintf
++
++        This option group further includes the following unlocked
++        variants of the above functions:
++
++          fgetwc_unlocked           getwc_unlocked
++          fgetws_unlocked           getwchar_unlocked
++          fputwc_unlocked           putwc_unlocked
++          fputws_unlocked           putwchar_unlocked
++
++        Note that the GNU standard C++ library, 'libstdc++.so', uses
++        some of these functions; you will not be able to link or run
++        C++ programs if you disable this option group.
++
++        This option group also affects the behavior of the following
++        functions:
++
++          fdopen
++          fopen
++          fopen64
++          freopen
++          freopen64
++
++        These functions all take an OPENTYPE parameter which may
++        contain a string of the form ",ccs=CHARSET", indicating that
++        the underlying file uses the character set named CHARSET.
++        This produces a wide-oriented stream, which is only useful
++        when the functions included in this option group are present.
++        If the user attempts to open a file specifying a character set
++        in the OPENTYPE parameter, and EGLIBC was built with this
++        option group disabled, the function returns NULL, and sets
++        errno to EINVAL.
++
++\f
++# This helps Emacs users browse this file using the page motion commands
++# and commands like 'pages-directory'.
++# Local Variables:
++# page-delimiter: "^config\\s-"
++# End:
+diff --git a/option-groups.defaults b/option-groups.defaults
+new file mode 100644
+index 0000000..8141201
+--- /dev/null
++++ b/option-groups.defaults
+@@ -0,0 +1,47 @@
++# This file sets default values for all option group variables
++# mentioned in option-groups.def; see that file for a description of
++# each option group.
++#
++# Subdirectory makefiles include this file before including the user's
++# settings from option-groups.config at the top of the build tree;
++# that file need only refer to those options whose default settings
++# are to be changed.
++#
++# By default, all option groups are enabled.
++OPTION_EGLIBC_ADVANCED_INET6 = y
++OPTION_EGLIBC_BACKTRACE = y
++OPTION_EGLIBC_BIG_MACROS = y
++OPTION_EGLIBC_BSD = y
++OPTION_EGLIBC_CXX_TESTS = y
++OPTION_EGLIBC_CATGETS = y
++OPTION_EGLIBC_CHARSETS = y
++OPTION_EGLIBC_CRYPT = y
++OPTION_EGLIBC_CRYPT_UFC = y
++OPTION_EGLIBC_DB_ALIASES = y
++OPTION_EGLIBC_ENVZ = y
++OPTION_EGLIBC_FCVT = y
++OPTION_EGLIBC_FMTMSG = y
++OPTION_EGLIBC_FSTAB = y
++OPTION_EGLIBC_FTRAVERSE = y
++OPTION_EGLIBC_GETLOGIN = y
++OPTION_EGLIBC_IDN = y
++OPTION_EGLIBC_INET = y
++OPTION_EGLIBC_INET_ANL = y
++OPTION_EGLIBC_LIBM = y
++OPTION_EGLIBC_LOCALES = y
++OPTION_EGLIBC_LOCALE_CODE = y
++OPTION_EGLIBC_MEMUSAGE = y
++OPTION_EGLIBC_NIS = y
++OPTION_EGLIBC_NSSWITCH = y
++OPTION_EGLIBC_RCMD = y
++OPTION_EGLIBC_RTLD_DEBUG = y
++OPTION_EGLIBC_SPAWN = y
++OPTION_EGLIBC_STREAMS = y
++OPTION_EGLIBC_SUNRPC = y
++OPTION_EGLIBC_UTMP = y
++OPTION_EGLIBC_UTMPX = y
++OPTION_EGLIBC_WORDEXP = y
++OPTION_POSIX_C_LANG_WIDE_CHAR = y
++OPTION_POSIX_REGEXP = y
++OPTION_POSIX_REGEXP_GLIBC = y
++OPTION_POSIX_WIDE_CHAR_DEVICE_IO = y
+diff --git a/option-groups.mak b/option-groups.mak
+new file mode 100644
+index 0000000..f83e0c1
+--- /dev/null
++++ b/option-groups.mak
+@@ -0,0 +1,41 @@
++# Setup file for subdirectory Makefiles that define EGLIBC option groups.
++
++# EGLIBC shouldn't need to override this.  However, the
++# cross-build-friendly localedef includes this makefile to get option
++# group variable definitions; it uses a single build tree for all the
++# multilibs, and needs to be able to specify a different option group
++# configuration file for each multilib.
++option_group_config_file ?= $(objdir)/option-groups.config
++
++# Read the default settings for all options.
++# We're included before ../Rules, so we can't assume $(..) is set.
++include $(firstword $(..) ../)option-groups.defaults
++
++# Read the developer's option group selections, overriding the
++# defaults from option-groups.defaults.
++-include $(option_group_config_file)
++
++# $(call option-disabled, VAR) is 'y' if VAR is not 'y', or 'n' otherwise.
++# VAR should be a variable name, not a variable reference; this is
++# less general, but more terse for the intended use.
++# You can use it to add a file to a list if an option group is
++# disabled, like this:
++#   routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += ...
++define option-disabled
++$(firstword $(subst y,n,$(filter y,$($(strip $(1))))) y)
++endef
++
++# Establish 'routines-y', etc. as simply-expanded variables.
++aux-y	       	    :=
++extra-libs-others-y :=
++extra-libs-y   	    :=
++extra-objs-y   	    :=
++install-bin-y  	    :=
++install-others-y    :=
++install-sbin-y 	    :=
++others-y       	    :=
++others-pie-y   	    :=
++routines-y     	    :=
++test-srcs-y    	    :=
++tests-y        	    :=
++xtests-y       	    :=
+diff --git a/options-config/Makefile b/options-config/Makefile
+new file mode 100644
+index 0000000..db00708
+--- /dev/null
++++ b/options-config/Makefile
+@@ -0,0 +1,55 @@
++# ===========================================================================
++# EGLIBC option-groups configuration targets
++# These targets are included from top-level makefile
++
++ifneq ($(kconfig_tools),)
++ifneq (no,$(PERL))
++
++ocdir := options-config
++
++OconfigDefaults     := option-groups.defaults
++OconfigDefaults_tmp := $(common-objpfx).tmp.defconfig
++OconfigDef          := option-groups.def
++Oconfig             := $(common-objpfx)option-groups.config
++Oconfig_tmp         := $(common-objpfx).tmp.config
++
++conf  := $(kconfig_tools)/conf
++mconf := $(kconfig_tools)/mconf
++
++preproc  := $(PERL) $(ocdir)/config-preproc.pl
++postproc := $(PERL) $(ocdir)/config-postproc.pl
++
++PHONY += defconfig config menuconfig
++
++defconfig: $(conf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(OconfigDefaults_tmp)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(OconfigDefaults) > $(OconfigDefaults_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< --defconfig=$(OconfigDefaults_tmp) \
++				$(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++	rm $(OconfigDefaults_tmp)
++
++config: $(conf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< --oldaskconfig $(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++
++menuconfig: $(mconf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< $(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++
++# Help text used by make help
++help:
++	@echo  '  defconfig	  - New config with default from default config'
++	@echo  '  config	  - Update current config utilising a line-oriented program'
++	@echo  '  menuconfig	  - Update current config utilising a menu based program'
++
++endif
++endif
+diff --git a/options-config/config-postproc.pl b/options-config/config-postproc.pl
+new file mode 100644
+index 0000000..4dd1c63
+--- /dev/null
++++ b/options-config/config-postproc.pl
+@@ -0,0 +1,58 @@
++#!/usr/bin/perl
++
++$usage = "usage: $0 <default config file> <config file>\n";
++
++die "$usage" unless @ARGV;
++$defaults = shift @ARGV;
++die "$usage" unless @ARGV;
++die "Could not open $ARGV[0]" unless -T $ARGV[0];
++
++sub yank {
++    @option = grep(!($_ =~ /$_[0]\s*=/), @option);
++}
++
++open(DEFAULTS, $defaults) || die "Could not open $defaults\n";
++
++# get the full list of available options using the default config file
++$i = 0;
++while (<DEFAULTS>) {
++    if (/^\s*OPTION_(\w+\s*=.*$)/) {
++	$option[$i++] = $1;
++    }
++}
++
++# now go through the config file, making the necessary changes
++while (<>) {
++    if (/Linux Kernel Configuration/) {
++	# change title
++	s/Linux Kernel/Option Groups/;
++	print;
++    } elsif (/^\s*CONFIG_(\w+)\s*=/) {
++	# this is an explicit option set line, change CONFIG_ to OPTION_
++	# before printing and remove this option from option list
++	$opt = $1;
++	yank($opt);
++	s/CONFIG_/OPTION_/g;
++	print;
++    } elsif (/^\s*#\s+CONFIG_(\w+) is not set/) {
++	# this is a comment line for an unset boolean option, change CONFIG_
++	# to OPTION_, remove this option from option list, and convert to
++	# explicit OPTION_FOO=n
++	$opt = $1;
++	yank($opt);
++	s/CONFIG_/OPTION_/g;
++	print "OPTION_$opt=n\n";
++    } else {
++	print;
++    }
++}
++
++# any boolean options left in @options, are options that were not mentioned in
++# the config file, and implicitly that means the option must be set =n,
++# so do that here.
++foreach $opt (@option) {
++    if ($opt =~ /=\s*[yn]/) {
++	$opt =~ s/=\s*[yn]/=n/;
++	print "OPTION_$opt\n";
++    }
++}
+diff --git a/options-config/config-preproc.pl b/options-config/config-preproc.pl
+new file mode 100644
+index 0000000..b83bb85
+--- /dev/null
++++ b/options-config/config-preproc.pl
+@@ -0,0 +1,8 @@
++#!/usr/bin/perl
++
++if (@ARGV) {
++    while (<>) {
++	s/OPTION_/CONFIG_/g;
++	print;
++    }
++}
+diff --git a/scripts/option-groups.awk b/scripts/option-groups.awk
+new file mode 100644
+index 0000000..533af0c
+--- /dev/null
++++ b/scripts/option-groups.awk
+@@ -0,0 +1,63 @@
++# option-groups.awk --- generate option group header file
++# Given input files containing makefile-style assignments to variables,
++# print out a header file that #defines an appropriate preprocessor
++# symbol for each variable left set to 'y'.
++
++BEGIN { FS="=" }
++
++# Trim spaces.
++{ gsub (/[[:blank:]]/, "") }
++
++# Skip comments.
++/^#/ { next }
++
++# Process assignments.
++NF == 2 {
++    vars[$1] = $2
++}
++
++# Print final values.
++END {
++    print "/* This file is automatically generated by scripts/option-groups.awk"
++    print "   in the EGLIBC source tree."
++    print ""
++    print "   It defines macros that indicate which EGLIBC option groups were"
++    print "   configured in 'option-groups.config' when this C library was"
++    print "   built.  For each option group named OPTION_foo, it #defines"
++    print "   __OPTION_foo to be 1 if the group is enabled, or #defines that"
++    print "   symbol to be 0 if the group is disabled.  */"
++    print ""
++    print "#ifndef __GNU_OPTION_GROUPS_H"
++    print "#define __GNU_OPTION_GROUPS_H"
++    print ""
++
++    # Produce a sorted list of variable names.
++    i=0
++    for (var in vars)
++        names[i++] = var
++    n = asort (names)
++
++    for (i = 1; i <= n; i++)
++    {
++        var = names[i]
++        if (var ~ /^OPTION_/)
++        {
++            if (vars[var] == "y")
++                print "#define __" var " 1"
++            else if (vars[var] == "n")
++                print "#define __" var " 0"
++	    else if (vars[var] ~ /^[0-9]+/ ||
++		     vars[var] ~ /^0x[0-9aAbBcCdDeEfF]+/ ||
++		     vars[var] ~ /^\"/)
++		 print "#define __" var " " vars[var]
++	    else
++		print "/* #undef __" var " */"
++            # Ignore variables that don't have boolean, int, hex, or
++	    # string values. Ideally, this would be driven by the types
++	    # given in option-groups.def.
++        }
++    }
++
++    print ""
++    print "#endif /* __GNU_OPTION_GROUPS_H */"
++}
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch b/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch
new file mode 100644
index 0000000..df93094
--- /dev/null
+++ b/recipes-core/glibc/glibc/0020-eglibc-Help-bootstrap-cross-toolchain.patch
@@ -0,0 +1,100 @@
+From 8fe0d29488b376011cdaaa462d557ffc0b31fb63 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:49:28 +0000
+Subject: [PATCH 20/27] eglibc: Help bootstrap cross toolchain
+
+Taken from EGLIBC, r1484 + r1525
+
+        2007-02-20  Jim Blandy  <jimb@codesourcery.com>
+
+                * Makefile (install-headers): Preserve old behavior: depend on
+                $(inst_includedir)/gnu/stubs.h only if install-bootstrap-headers
+                is set; otherwise, place gnu/stubs.h on the 'install-others' list.
+
+        2007-02-16  Jim Blandy  <jimb@codesourcery.com>
+
+                * Makefile: Amend make install-headers to install everything
+                necessary for building a cross-compiler.  Install gnu/stubs.h as
+                part of 'install-headers', not 'install-others'.
+                If install-bootstrap-headers is 'yes', install a dummy copy of
+                gnu/stubs.h, instead of computing the real thing.
+                * include/stubs-bootstrap.h: New file.
+
+Upstream-Status: Pending
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ Makefile                  | 22 +++++++++++++++++++++-
+ include/stubs-bootstrap.h | 12 ++++++++++++
+ 2 files changed, 33 insertions(+), 1 deletion(-)
+ create mode 100644 include/stubs-bootstrap.h
+
+diff --git a/Makefile b/Makefile
+index f906391..e4e149e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -69,9 +69,18 @@ subdir-dirs = include
+ vpath %.h $(subdir-dirs)
+ 
+ # What to install.
+-install-others = $(inst_includedir)/gnu/stubs.h
+ install-bin-script =
+ 
++# If we're bootstrapping, install a dummy gnu/stubs.h along with the
++# other headers, so 'make install-headers' produces a useable include
++# tree.  Otherwise, install gnu/stubs.h later, after the rest of the
++# build is done.
++ifeq ($(install-bootstrap-headers),yes)
++install-headers: $(inst_includedir)/gnu/stubs.h
++else
++install-others = $(inst_includedir)/gnu/stubs.h
++endif
++
+ ifeq (yes,$(build-shared))
+ headers += gnu/lib-names.h
+ endif
+@@ -151,6 +160,16 @@ others: $(common-objpfx)testrun.sh
+ 
+ subdir-stubs := $(foreach dir,$(subdirs),$(common-objpfx)$(dir)/stubs)
+ 
++# gnu/stubs.h depends (via the subdir 'stubs' targets) on all the .o
++# files in EGLIBC.  For bootstrapping a GCC/EGLIBC pair, an empty
++# gnu/stubs.h is good enough.
++ifeq ($(install-bootstrap-headers),yes)
++$(inst_includedir)/gnu/stubs.h: include/stubs-bootstrap.h $(+force)
++	$(make-target-directory)
++	$(INSTALL_DATA) $< $@
++
++installed-stubs =
++else
+ ifndef abi-variants
+ installed-stubs = $(inst_includedir)/gnu/stubs.h
+ else
+@@ -177,6 +196,7 @@ $(inst_includedir)/gnu/stubs.h: $(+force)
+ 
+ install-others-nosubdir: $(installed-stubs)
+ endif
++endif
+ 
+ 
+ # Since stubs.h is never needed when building the library, we simplify the
+diff --git a/include/stubs-bootstrap.h b/include/stubs-bootstrap.h
+new file mode 100644
+index 0000000..1d2b669
+--- /dev/null
++++ b/include/stubs-bootstrap.h
+@@ -0,0 +1,12 @@
++/* Placeholder stubs.h file for bootstrapping.
++
++   When bootstrapping a GCC/EGLIBC pair, GCC requires that the EGLIBC
++   headers be installed, but we can't fully build EGLIBC without that
++   GCC.  So we run the command:
++
++      make install-headers install-bootstrap-headers=yes
++
++   to install the headers GCC needs, but avoid building certain
++   difficult headers.  The <gnu/stubs.h> header depends, via the
++   EGLIBC subdir 'stubs' make targets, on every .o file in EGLIBC, but
++   an empty stubs.h like this will do fine for GCC.  */
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch b/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch
new file mode 100644
index 0000000..38bb8a1
--- /dev/null
+++ b/recipes-core/glibc/glibc/0021-eglibc-cherry-picked-from-http-www.eglibc.org-archiv.patch
@@ -0,0 +1,64 @@
+From fe2ae4f877928dd6bff5bac3f15bce4b50d2bd12 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:51:16 +0000
+Subject: [PATCH 21/27] eglibc: cherry-picked from
+ http://www.eglibc.org/archives/patches/msg00772.html
+
+It hasn't yet been merged into glibc
+
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ resolv/res_libc.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/resolv/res_libc.c b/resolv/res_libc.c
+index ee3fa21..29e2340 100644
+--- a/resolv/res_libc.c
++++ b/resolv/res_libc.c
+@@ -22,12 +22,13 @@
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ #include <bits/libc-lock.h>
+-
++#include <sys/stat.h>
+ 
+ /* The following bit is copied from res_data.c (where it is #ifdef'ed
+    out) since res_init() should go into libc.so but the rest of that
+    file should not.  */
+ 
++__libc_lock_define_initialized (static, lock);
+ extern unsigned long long int __res_initstamp attribute_hidden;
+ /* We have atomic increment operations on 64-bit platforms.  */
+ #if __WORDSIZE == 64
+@@ -35,7 +36,6 @@ extern unsigned long long int __res_initstamp attribute_hidden;
+ # define atomicincunlock(lock) (void) 0
+ # define atomicinc(var) catomic_increment (&(var))
+ #else
+-__libc_lock_define_initialized (static, lock);
+ # define atomicinclock(lock) __libc_lock_lock (lock)
+ # define atomicincunlock(lock) __libc_lock_unlock (lock)
+ # define atomicinc(var) ++var
+@@ -94,7 +94,18 @@ res_init(void) {
+ int
+ __res_maybe_init (res_state resp, int preinit)
+ {
++	static time_t last_mtime;
++	struct stat statbuf;
++	int ret;
++
+ 	if (resp->options & RES_INIT) {
++		ret = stat (_PATH_RESCONF, &statbuf);
++		__libc_lock_lock (lock);
++		if ((ret == 0) && (last_mtime != statbuf.st_mtime)) {
++			last_mtime = statbuf.st_mtime;
++			atomicinc (__res_initstamp);
++		}
++		__libc_lock_unlock (lock);
+ 		if (__res_initstamp != resp->_u._ext.initstamp) {
+ 			if (resp->nscount > 0)
+ 				__res_iclose (resp, true);
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch b/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch
new file mode 100644
index 0000000..8a4c9c3
--- /dev/null
+++ b/recipes-core/glibc/glibc/0022-eglibc-Clear-cache-lines-on-ppc8xx.patch
@@ -0,0 +1,81 @@
+From be7273225698074347a71de58006977bb304d7f7 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:53:47 +0000
+Subject: [PATCH 22/27] eglibc: Clear cache lines on ppc8xx
+
+2007-06-13  Nathan Sidwell  <nathan@codesourcery.com>
+            Mark Shinwell  <shinwell@codesourcery.com>
+
+        * sysdeps/unix/sysv/linux/powerpc/libc-start.c
+        (__libc_start_main): Detect 8xx parts and clear
+        __cache_line_size if detected.
+        * sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
+        (DL_PLATFORM_AUXV): Likewise.
+
+Upstream-Status: Pending
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c  | 14 +++++++++++++-
+ sysdeps/unix/sysv/linux/powerpc/libc-start.c | 15 ++++++++++++++-
+ 2 files changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
+index c2504ff..d50f1cb 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
++++ b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
+@@ -24,9 +24,21 @@ int __cache_line_size attribute_hidden;
+ /* Scan the Aux Vector for the "Data Cache Block Size" entry.  If found
+    verify that the static extern __cache_line_size is defined by checking
+    for not NULL.  If it is defined then assign the cache block size
+-   value to __cache_line_size.  */
++   value to __cache_line_size.  This is used by memset to
++   optimize setting to zero.  We have to detect 8xx processors, which
++   have buggy dcbz implementations that cannot report page faults
++   correctly.  That requires reading SPR, which is a privileged
++   operation.  Fortunately 2.2.18 and later emulates PowerPC mfspr
++   reads from the PVR register.   */
+ #define DL_PLATFORM_AUXV						      \
+       case AT_DCACHEBSIZE:						      \
++	if (__LINUX_KERNEL_VERSION >= 0x020218)				      \
++	  {								      \
++	    unsigned pvr = 0;						      \
++	    asm ("mfspr %0, 287" : "=r" (pvr));				      \
++	    if ((pvr & 0xffff0000) == 0x00500000)			      \
++	      break;							      \
++	  }								      \
+ 	__cache_line_size = av->a_un.a_val;				      \
+ 	break;
+ 
+diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+index a9364c7..a3ed1d4 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
++++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+@@ -68,11 +68,24 @@ __libc_start_main (int argc, char **argv,
+       rtld_fini = NULL;
+     }
+ 
+-  /* Initialize the __cache_line_size variable from the aux vector.  */
++  /* Initialize the __cache_line_size variable from the aux vector.
++     This is used by memset to optimize setting to zero.  We have to
++     detect 8xx processors, which have buggy dcbz implementations that
++     cannot report page faults correctly.  That requires reading SPR,
++     which is a privileged operation.  Fortunately 2.2.18 and later
++     emulates PowerPC mfspr reads from the PVR register.  */
+   for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
+     switch (av->a_type)
+       {
+       case AT_DCACHEBSIZE:
++	if (__LINUX_KERNEL_VERSION >= 0x020218)
++	  {
++	    unsigned pvr = 0;
++
++	    asm ("mfspr %0, 287" : "=r" (pvr) :);
++	    if ((pvr & 0xffff0000) == 0x00500000)
++	      break;
++	  }
+ 	__cache_line_size = av->a_un.a_val;
+ 	break;
+       }
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch b/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch
new file mode 100644
index 0000000..9f3d753
--- /dev/null
+++ b/recipes-core/glibc/glibc/0023-eglibc-Resolve-__fpscr_values-on-SH4.patch
@@ -0,0 +1,56 @@
+From 718e7e5db1c8b073adb9a79ec6f167238c2d8bda Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:55:53 +0000
+Subject: [PATCH 23/27] eglibc: Resolve __fpscr_values on SH4
+
+2010-09-29  Nobuhiro Iwamatsu  <iwamatsu@nigauri.org>
+            Andrew Stubbs  <ams@codesourcery.com>
+
+        Resolve SH's __fpscr_values to symbol in libc.so.
+
+        * sysdeps/sh/sh4/fpu/fpu_control.h: Add C++ __set_fpscr prototype.
+        * sysdeps/unix/sysv/linux/sh/Versions (GLIBC_2.2): Add __fpscr_values.
+        * sysdeps/unix/sysv/linux/sh/sysdep.S (___fpscr_values): New constant.
+
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ sysdeps/unix/sysv/linux/sh/Versions |  1 +
+ sysdeps/unix/sysv/linux/sh/sysdep.S | 11 +++++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/sysdeps/unix/sysv/linux/sh/Versions b/sysdeps/unix/sysv/linux/sh/Versions
+index e0938c4..ca1d7da 100644
+--- a/sysdeps/unix/sysv/linux/sh/Versions
++++ b/sysdeps/unix/sysv/linux/sh/Versions
+@@ -2,6 +2,7 @@ libc {
+   GLIBC_2.2 {
+     # functions used in other libraries
+     __xstat64; __fxstat64; __lxstat64;
++    __fpscr_values;
+ 
+     # a*
+     alphasort64;
+diff --git a/sysdeps/unix/sysv/linux/sh/sysdep.S b/sysdeps/unix/sysv/linux/sh/sysdep.S
+index a02b7e2..b9be326 100644
+--- a/sysdeps/unix/sysv/linux/sh/sysdep.S
++++ b/sysdeps/unix/sysv/linux/sh/sysdep.S
+@@ -30,3 +30,14 @@ ENTRY (__syscall_error)
+ 
+ #define __syscall_error __syscall_error_1
+ #include <sysdeps/unix/sh/sysdep.S>
++
++       .data
++       .align 3
++       .globl ___fpscr_values
++       .type ___fpscr_values, @object
++       .size ___fpscr_values, 8
++___fpscr_values:
++       .long 0
++       .long 0x80000
++weak_alias (___fpscr_values, __fpscr_values)
++
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch b/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch
new file mode 100644
index 0000000..0514e28
--- /dev/null
+++ b/recipes-core/glibc/glibc/0024-eglibc-Forward-port-eglibc-options-groups-support.patch
@@ -0,0 +1,16842 @@
+From 2a5d7bcf0ff791c95ee1388772408a1bf4454694 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 01:33:49 +0000
+Subject: [PATCH 24/27] eglibc: Forward port eglibc options groups support
+
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ Makeconfig                              |   20 +-
+ Makerules                               |   19 +
+ argp/Makefile                           |    2 +
+ argp/argp-fmtstream.c                   |   25 +-
+ argp/argp-help.c                        |   13 +-
+ argp/argp-namefrob.h                    |    2 +
+ catgets/Makefile                        |   17 +-
+ crypt/Makefile                          |   20 +-
+ crypt/crypt-entry.c                     |   13 +
+ crypt/crypt_common.c                    |   42 +
+ crypt/crypt_util.c                      |   18 -
+ csu/Makefile                            |    2 +
+ debug/Makefile                          |   41 +-
+ debug/segfault.c                        |   11 +-
+ debug/tst-chk1.c                        |    7 +
+ dlfcn/Makefile                          |    7 +-
+ elf/dl-support.c                        |    3 +
+ elf/rtld.c                              |   17 +-
+ extra-lib.mk                            |    6 +-
+ grp/Makefile                            |    5 +
+ hesiod/Makefile                         |    6 +-
+ iconv/Makefile                          |    7 +
+ iconv/gconv_db.c                        |    3 +
+ iconv/gconv_trans.c                     |    7 +
+ iconv/iconv_prog.c                      |    8 +
+ iconvdata/Makefile                      |   27 +-
+ include/netdb.h                         |    4 +
+ inet/Makefile                           |   22 +-
+ intl/Makefile                           |    3 +-
+ intl/dcigettext.c                       |   39 +-
+ io/Makefile                             |   18 +-
+ libidn/Makefile                         |    5 +-
+ libidn/toutf8.c                         |   11 +-
+ libio/Makefile                          |   66 +-
+ libio/__fpurge.c                        |    2 +-
+ libio/fileops.c                         |   10 +-
+ libio/iofwide.c                         |   26 +
+ libio/ioseekoff.c                       |    2 +-
+ libio/ioseekpos.c                       |    2 +-
+ libio/iosetbuffer.c                     |    4 +
+ libio/libioP.h                          |   18 +-
+ libio/wdummyfileops.c                   |  161 +
+ locale/C-ctype.c                        |   20 +
+ locale/Makefile                         |   41 +-
+ locale/catnames.c                       |   48 +
+ locale/dummy-setlocale.c                |   33 +
+ locale/localeinfo.h                     |    2 +-
+ locale/programs/charmap-dir.c           |    6 +
+ locale/programs/ld-collate.c            |   17 +-
+ locale/programs/ld-ctype.c              |   27 +-
+ locale/programs/ld-messages.c           |    5 +
+ locale/programs/ld-time.c               |   31 +-
+ locale/programs/linereader.c            |    2 +-
+ locale/programs/localedef.c             |    8 +
+ locale/programs/locfile.c               |    5 +-
+ locale/programs/locfile.h               |   59 +-
+ locale/setlocale.c                      |   30 -
+ locale/xlocale.c                        |   37 +
+ localedata/Makefile                     |   35 +-
+ login/Makefile                          |   17 +-
+ malloc/Makefile                         |   10 +-
+ malloc/memusage.c                       |    7 +-
+ malloc/memusage.sh                      |    2 +-
+ math/Makefile                           |    6 +-
+ misc/Makefile                           |   25 +-
+ misc/err.c                              |   11 +
+ misc/error.c                            |    5 +
+ misc/tst-efgcvt.c                       |    2 +-
+ nis/Makefile                            |   31 +-
+ nptl/Makefile                           |   28 +-
+ nptl/pthread_create.c                   |    5 +
+ nscd/Makefile                           |   33 +-
+ nscd/nis_hash.c                         |    3 +
+ nss/Makefile                            |   67 +-
+ nss/fixed-nsswitch.conf                 |   22 +
+ nss/fixed-nsswitch.functions            |  121 +
+ nss/gen-fixed-nsswitch.c                |  803 +++
+ nss/getent.c                            |   46 +-
+ nss/getnssent_r.c                       |    9 +-
+ nss/nsswitch.c                          |  109 +-
+ nss/nsswitch.h                          |   18 +-
+ posix/Makefile                          |   94 +-
+ posix/bug-regex1.c                      |    3 +
+ posix/bug-regex6.c                      |    8 +-
+ posix/fnmatch.c                         |    6 +-
+ posix/fnmatch_loop.c                    |   23 +-
+ posix/glob.c                            |   15 +-
+ posix/regcomp.c                         |   98 +-
+ posix/regex.h                           |   11 +
+ posix/regex_internal.c                  |   45 +-
+ posix/regex_internal.h                  |   23 +-
+ posix/regexec-compat.c                  |   39 +
+ posix/regexec.c                         |   71 +-
+ posix/xregex.c                          | 8215 +++++++++++++++++++++++++++++++
+ pwd/Makefile                            |    2 +
+ resolv/Makefile                         |   21 +-
+ stdio-common/Makefile                   |   35 +-
+ stdio-common/_i18n_number.h             |   13 +
+ stdio-common/fxprintf.c                 |    5 +
+ stdio-common/printf_fp.c                |   22 +
+ stdio-common/printf_fphex.c             |   13 +
+ stdio-common/printf_size.c              |    8 +
+ stdio-common/scanf14.c                  |    3 +
+ stdio-common/tst-popen.c                |    3 +
+ stdio-common/tst-sprintf.c              |    4 +-
+ stdio-common/tstdiomisc.c               |    5 +
+ stdio-common/vfprintf.c                 |   31 +-
+ stdio-common/vfscanf.c                  |   53 +-
+ stdlib/Makefile                         |   34 +-
+ stdlib/strtod_l.c                       |   13 +
+ stdlib/tst-strtod.c                     |    5 +
+ streams/Makefile                        |    5 +-
+ string/Makefile                         |   14 +-
+ string/strcoll_l.c                      |    5 +
+ string/strerror_l.c                     |    5 +
+ string/strxfrm_l.c                      |    5 +
+ string/test-strcmp.c                    |   28 -
+ string/tst-strxfrm.c                    |    3 +
+ string/tst-strxfrm2.c                   |    3 +
+ sunrpc/Makefile                         |   44 +-
+ sysdeps/arm/Makefile                    |    5 +-
+ sysdeps/generic/ldsodefs.h              |    8 +
+ sysdeps/gnu/Makefile                    |    3 +-
+ sysdeps/ieee754/ldbl-opt/Makefile       |   27 +-
+ sysdeps/ieee754/ldbl-opt/nldbl-compat.c |   40 +-
+ sysdeps/ieee754/ldbl-opt/nldbl-compat.h |   24 +-
+ sysdeps/nptl/Makefile                   |    3 +
+ sysdeps/nptl/bits/libc-lock.h           |   45 +
+ sysdeps/nptl/bits/libc-lockP.h          |   50 +-
+ sysdeps/nptl/small-macros-fns.c         |   72 +
+ sysdeps/unix/sysv/linux/gethostid.c     |    6 +
+ sysdeps/unix/sysv/linux/libc_fatal.c    |    3 +
+ time/Makefile                           |   18 +-
+ time/strftime_l.c                       |   12 +-
+ time/strptime_l.c                       |   14 +-
+ timezone/Makefile                       |    2 +-
+ wcsmbs/Makefile                         |   27 +-
+ wcsmbs/wcsmbsload.c                     |   13 +
+ wctype/Makefile                         |   14 +-
+ 139 files changed, 11363 insertions(+), 583 deletions(-)
+ create mode 100644 crypt/crypt_common.c
+ create mode 100644 libio/wdummyfileops.c
+ create mode 100644 locale/catnames.c
+ create mode 100644 locale/dummy-setlocale.c
+ create mode 100644 nscd/nis_hash.c
+ create mode 100644 nss/fixed-nsswitch.conf
+ create mode 100644 nss/fixed-nsswitch.functions
+ create mode 100644 nss/gen-fixed-nsswitch.c
+ create mode 100644 posix/regexec-compat.c
+ create mode 100644 posix/xregex.c
+ create mode 100644 sysdeps/nptl/small-macros-fns.c
+
+diff --git a/Makeconfig b/Makeconfig
+index f136b88..52dae8f 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -609,7 +609,7 @@ elf-objpfx = $(common-objpfx)elf/
+ # and run on the build system, causes that program with those
+ # arguments to be run on the host for which the library is built.
+ ifndef test-wrapper
+-test-wrapper =
++test-wrapper = $(cross-test-wrapper)
+ endif
+ # Likewise, but the name of the program is preceded by
+ # <variable>=<value> assignments for environment variables.
+@@ -1089,6 +1089,24 @@ libm = $(common-objpfx)math/libm.a
+ libmvec = $(common-objpfx)mathvec/libmvec.a
+ endif
+ 
++# Generate a header file that #defines preprocessor symbols indicating
++# which option groups are enabled.  Note that the option-groups.config file
++# may not exist at all.
++before-compile += $(common-objpfx)gnu/option-groups.h
++common-generated += gnu/option-groups.h gnu/option-groups.stmp
++headers += gnu/option-groups.h
++$(common-objpfx)gnu/option-groups.h: $(common-objpfx)gnu/option-groups.stmp; @:
++$(common-objpfx)gnu/option-groups.stmp:					\
++		$(..)scripts/option-groups.awk				\
++		$(..)option-groups.defaults				\
++		$(wildcard $(common-objpfx)option-groups.config)
++	$(make-target-directory)
++	@rm -f ${@:stmp=T} $@
++	LC_ALL=C $(AWK) -f $^ > ${@:stmp=T}
++	$(move-if-change) ${@:stmp=T} ${@:stmp=h}
++	touch $@
++
++
+ # These are the subdirectories containing the library source.  The order
+ # is more or less arbitrary.  The sorting step will take care of the
+ # dependencies.
+diff --git a/Makerules b/Makerules
+index f9ca3f5..1dd41aa 100644
+--- a/Makerules
++++ b/Makerules
+@@ -456,6 +456,25 @@ define sed-remove-objpfx
+ endef
+ endif
+ \f
++# Include targets in the selected option groups.
++aux                  += $(aux-y)
++extra-libs           += $(extra-libs-y)
++extra-libs-others    += $(extra-libs-others-y)
++extra-objs           += $(extra-objs-y)
++install-bin          += $(install-bin-y)
++install-others       += $(install-others-y)
++install-sbin         += $(install-sbin-y)
++modules              += $(modules-y)
++others               += $(others-y)
++others-pie           += $(others-pie-y)
++routines             += $(routines-y)
++static-only-routines += $(static-only-routines-y)
++sysdep_routines      += $(sysdep_routines-y)
++test-srcs            += $(test-srcs-y)
++tests                += $(tests-y)
++xtests               += $(xtests-y)
++
++\f
+ # Modify the list of routines we build for different targets
+ 
+ ifeq (yes,$(build-shared))
+diff --git a/argp/Makefile b/argp/Makefile
+index 1a87629..f7c1e40 100644
+--- a/argp/Makefile
++++ b/argp/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for argp.
+ #
++include ../option-groups.mak
++
+ subdir	:= argp
+ 
+ include ../Makeconfig
+diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c
+index 2b845e0..c344e7b 100644
+--- a/argp/argp-fmtstream.c
++++ b/argp/argp-fmtstream.c
+@@ -42,6 +42,7 @@
+ #ifdef _LIBC
+ # include <wchar.h>
+ # include <libio/libioP.h>
++# include <gnu/option-groups.h>
+ # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
+ #endif
+ 
+@@ -100,7 +101,11 @@ __argp_fmtstream_free (argp_fmtstream_t fs)
+   __argp_fmtstream_update (fs);
+   if (fs->p > fs->buf)
+     {
++#ifdef _LIBC
+       __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
++#else
++      fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
++#endif
+     }
+   free (fs->buf);
+   free (fs);
+@@ -145,9 +150,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
+ 	      size_t i;
+ 	      for (i = 0; i < pad; i++)
+ 		{
++#ifdef _LIBC
+ 		  if (_IO_fwide (fs->stream, 0) > 0)
+-		    putwc_unlocked (L' ', fs->stream);
++                    {
++#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++                      putwc_unlocked (L' ', fs->stream);
++#else
++                      abort ();
++#endif
++                    }
+ 		  else
++#endif
+ 		    putc_unlocked (' ', fs->stream);
+ 		}
+ 	    }
+@@ -308,9 +321,17 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
+ 	      *nl++ = ' ';
+ 	  else
+ 	    for (i = 0; i < fs->wmargin; ++i)
++#ifdef _LIBC
+ 	      if (_IO_fwide (fs->stream, 0) > 0)
+-		putwc_unlocked (L' ', fs->stream);
++                {
++#ifdef OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++                  putwc_unlocked (L' ', fs->stream);
++#else
++                  abort ();
++#endif
++                }
+ 	      else
++#endif
+ 		putc_unlocked (' ', fs->stream);
+ 
+ 	  /* Copy the tail of the original buffer into the current buffer
+diff --git a/argp/argp-help.c b/argp/argp-help.c
+index b055e45..6b3c4c1 100644
+--- a/argp/argp-help.c
++++ b/argp/argp-help.c
+@@ -51,6 +51,7 @@ char *alloca ();
+ #ifdef _LIBC
+ # include <../libio/libioP.h>
+ # include <wchar.h>
++# include <gnu/option-groups.h>
+ #endif
+ 
+ #ifndef _
+@@ -1702,7 +1703,7 @@ char *__argp_basename (char *name)
+ }
+ 
+ char *
+-__argp_short_program_name (void)
++(__argp_short_program_name) (void)
+ {
+ # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+   return program_invocation_short_name;
+@@ -1873,9 +1874,17 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
+ #endif
+ 	    }
+ 
++#ifdef _LIBC
+ 	  if (_IO_fwide (stream, 0) > 0)
+-	    putwc_unlocked (L'\n', stream);
++            {
++#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++              putwc_unlocked (L'\n', stream);
++#else
++              abort ();
++#endif
++            }
+ 	  else
++#endif
+ 	    putc_unlocked ('\n', stream);
+ 
+ #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+diff --git a/argp/argp-namefrob.h b/argp/argp-namefrob.h
+index f67c58f..e2002dc 100644
+--- a/argp/argp-namefrob.h
++++ b/argp/argp-namefrob.h
+@@ -76,10 +76,12 @@
+ #undef __argp_fmtstream_wmargin
+ #define __argp_fmtstream_wmargin argp_fmtstream_wmargin
+ 
++#if 0
+ #include "mempcpy.h"
+ #include "strcase.h"
+ #include "strchrnul.h"
+ #include "strndup.h"
++#endif
+ 
+ /* normal libc functions we call */
+ #undef __flockfile
+diff --git a/catgets/Makefile b/catgets/Makefile
+index 4624a88..05714fd 100644
+--- a/catgets/Makefile
++++ b/catgets/Makefile
+@@ -22,20 +22,23 @@ subdir	:= catgets
+ 
+ include ../Makeconfig
+ 
++include ../option-groups.mak
++
+ headers		= nl_types.h
+-routines	= catgets open_catalog
+-others		= gencat
+-install-bin	= gencat
+-extra-objs	= $(gencat-modules:=.o)
++routines-$(OPTION_EGLIBC_CATGETS)    := catgets open_catalog
++others-$(OPTION_EGLIBC_CATGETS)      := gencat
++install-bin-$(OPTION_EGLIBC_CATGETS) := gencat
++extra-objs-$(OPTION_EGLIBC_CATGETS)  := $(gencat-modules:=.o)
+ 
+-tests = tst-catgets
+-test-srcs = test-gencat
++tests-$(OPTION_EGLIBC_CATGETS)       := tst-catgets
++test-srcs-$(OPTION_EGLIBC_CATGETS)   := test-gencat
+ 
++ifeq (y,$(OPTION_EGLIBC_CATGETS))
+ ifeq ($(run-built-tests),yes)
+ tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
+ 		 $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out
+ endif
+-
++endif
+ gencat-modules	= xmalloc
+ 
+ # To find xmalloc.c
+diff --git a/crypt/Makefile b/crypt/Makefile
+index 34c4dd7..7c18c88 100644
+--- a/crypt/Makefile
++++ b/crypt/Makefile
+@@ -18,21 +18,25 @@
+ #
+ #	Sub-makefile for crypt() portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= crypt
+ 
+ include ../Makeconfig
+ 
+ headers := crypt.h
+ 
+-extra-libs := libcrypt
+-extra-libs-others := $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_CRYPT) := libcrypt
++extra-libs-others-y := $(extra-libs-y)
+ 
+-libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
+-		     crypt_util
++libcrypt-routines :=crypt-entry  md5-crypt sha256-crypt sha512-crypt crypt_common
++libcrypt-routines-$(OPTION_EGLIBC_CRYPT_UFC) := crypt crypt_util
++libcrypt-routines += $(libcrypt-routines-y)
+ 
+-tests := cert md5c-test sha256c-test sha512c-test badsalttest
++tests-$(OPTION_EGLIBC_CRYPT) := md5c-test sha256c-test sha512c-test badsalttest
++tests-$(OPTION_EGLIBC_CRYPT_UFC) += cert
+ 
+-ifeq ($(crypt-in-libc),yes)
++ifeq ($(crypt-in-libc)$(OPTION_EGLIBC_CRYPT),yesy)
+ routines += $(libcrypt-routines)
+ endif
+ 
+@@ -44,7 +48,7 @@ LDLIBS-crypt.so = -lfreebl3
+ else
+ libcrypt-routines += md5 sha256 sha512
+ 
+-tests += md5test sha256test sha512test
++tests-$(OPTION_EGLIBC_CRYPT) += md5test sha256test sha512test
+ 
+ # The test md5test-giant uses up to 400 MB of RSS and runs on a fast
+ # machine over a minute.
+@@ -64,8 +68,10 @@ $(objpfx)sha256test: $(patsubst %, $(objpfx)%.o,$(sha256-routines))
+ $(objpfx)sha512test: $(patsubst %, $(objpfx)%.o,$(sha512-routines))
+ endif
+ 
++ifeq ($(OPTION_EGLIBC_CRYPT),y)
+ ifeq (yes,$(build-shared))
+ $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so
+ else
+ $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a
+ endif
++endif # eglibc: OPTION_EGLIBC_CRYPT
+diff --git a/crypt/crypt-entry.c b/crypt/crypt-entry.c
+index 7e655ba..6ae5c2b 100644
+--- a/crypt/crypt-entry.c
++++ b/crypt/crypt-entry.c
+@@ -27,6 +27,7 @@
+ #include <stdio.h>
+ #endif
+ #include <string.h>
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <fips-private.h>
+ 
+@@ -76,9 +77,11 @@ __crypt_r (key, salt, data)
+      const char *salt;
+      struct crypt_data * __restrict data;
+ {
++#if __OPTION_EGLIBC_CRYPT_UFC
+   ufc_long res[4];
+   char ktab[9];
+   ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
++#endif /*__OPTION_EGLIBC_CRYPT_UFC*/
+ 
+ #ifdef _LIBC
+   /* Try to find out whether we have to use MD5 encryption replacement.  */
+@@ -105,6 +108,7 @@ __crypt_r (key, salt, data)
+ 			     sizeof (struct crypt_data));
+ #endif
+ 
++#if __OPTION_EGLIBC_CRYPT_UFC
+   /*
+    * Hack DES tables according to salt
+    */
+@@ -144,6 +148,10 @@ __crypt_r (key, salt, data)
+    */
+   _ufc_output_conversion_r (res[0], res[1], salt, data);
+   return data->crypt_3_buf;
++#else /* __OPTION_EGLIBC_CRYPT_UFC */
++  __set_errno (ENOSYS);
++  return NULL;
++#endif /* __OPTION_EGLIBC_CRYPT_UFC */
+ }
+ weak_alias (__crypt_r, crypt_r)
+ 
+@@ -168,7 +176,12 @@ crypt (key, salt)
+     return __sha512_crypt (key, salt);
+ #endif
+ 
++#if __OPTION_EGLIBC_CRYPT_UFC
+   return __crypt_r (key, salt, &_ufc_foobar);
++#else /* __OPTION_EGLIBC_CRYPT_UFC */
++  __set_errno (ENOSYS);
++  return NULL;
++#endif /* __OPTION_EGLIBC_CRYPT_UFC */
+ }
+ 
+ 
+diff --git a/crypt/crypt_common.c b/crypt/crypt_common.c
+new file mode 100644
+index 0000000..cce6a31
+--- /dev/null
++++ b/crypt/crypt_common.c
+@@ -0,0 +1,42 @@
++/*
++ * crypt: crypt(3) implementation
++ *
++ * Copyright (C) 1991-2014 Free Software Foundation, Inc.
++ *
++ * This 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.
++ *
++ * This 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 this library; see the file COPYING.LIB.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * General Support routines
++ *
++ */
++
++#include "crypt-private.h"
++
++/* Table with characters for base64 transformation.  */
++static const char b64t[64] =
++"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
++
++void
++__b64_from_24bit (char **cp, int *buflen,
++		  unsigned int b2, unsigned int b1, unsigned int b0,
++		  int n)
++{
++  unsigned int w = (b2 << 16) | (b1 << 8) | b0;
++  while (n-- > 0 && (*buflen) > 0)
++    {
++      *(*cp)++ = b64t[w & 0x3f];
++      --(*buflen);
++      w >>= 6;
++    }
++}
+diff --git a/crypt/crypt_util.c b/crypt/crypt_util.c
+index 1597885..9297974 100644
+--- a/crypt/crypt_util.c
++++ b/crypt/crypt_util.c
+@@ -242,10 +242,6 @@ static ufc_long eperm32tab[4][256][2];
+  */
+ static ufc_long efp[16][64][2];
+ 
+-/* Table with characters for base64 transformation.  */
+-static const char b64t[64] =
+-"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+-
+ /*
+  * For use by the old, non-reentrant routines
+  * (crypt/encrypt/setkey)
+@@ -949,17 +945,3 @@ setkey(__key)
+ {
+   __setkey_r(__key, &_ufc_foobar);
+ }
+-
+-void
+-__b64_from_24bit (char **cp, int *buflen,
+-		  unsigned int b2, unsigned int b1, unsigned int b0,
+-		  int n)
+-{
+-  unsigned int w = (b2 << 16) | (b1 << 8) | b0;
+-  while (n-- > 0 && (*buflen) > 0)
+-    {
+-      *(*cp)++ = b64t[w & 0x3f];
+-      --(*buflen);
+-      w >>= 6;
+-    }
+-}
+diff --git a/csu/Makefile b/csu/Makefile
+index 9f0855a..b1c3363 100644
+--- a/csu/Makefile
++++ b/csu/Makefile
+@@ -22,6 +22,8 @@
+ # crtn.o, special "initializer" and "finalizer" files used in the link
+ # to make the .init and .fini sections work right.
+ 
++include ../option-groups.mak
++
+ subdir := csu
+ 
+ include ../Makeconfig
+diff --git a/debug/Makefile b/debug/Makefile
+index 9ff357b..d23d97d 100644
+--- a/debug/Makefile
++++ b/debug/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for debug portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= debug
+ 
+ include ../Makeconfig
+@@ -27,7 +29,7 @@ headers	:= execinfo.h
+ # Note that ptsname_r_chk and getlogin_r are not here, but in
+ # login/Makefile instead.  If that subdir is omitted from the
+ # build, its _FORTIFY_SOURCE support will be too.
+-routines  = backtrace backtracesyms backtracesymsfd noophooks \
++routines  = noophooks \
+ 	    memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
+ 	    strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \
+ 	    sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
+@@ -36,20 +38,27 @@ routines  = backtrace backtracesyms backtracesymsfd noophooks \
+ 	    read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
+ 	    readlink_chk readlinkat_chk getwd_chk getcwd_chk \
+ 	    realpath_chk fread_chk fread_u_chk \
+-	    wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
+-	    wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
+-	    wcpncpy_chk \
+-	    swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \
+-	    vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \
+ 	    confstr_chk getgroups_chk ttyname_r_chk \
+-	    gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \
+-	    wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
+-	    wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \
++	    gethostname_chk getdomainname_chk \
++	    asprintf_chk vasprintf_chk dprintf_chk \
+ 	    vdprintf_chk obprintf_chk \
+ 	    longjmp_chk ____longjmp_chk \
+ 	    fdelt_chk poll_chk ppoll_chk \
+ 	    stack_chk_fail fortify_fail \
+ 	    $(static-only-routines)
++routines-$(OPTION_EGLIBC_BACKTRACE) += backtrace backtracesyms backtracesymsfd
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)			\
++	 += wprintf_chk fwprintf_chk				\
++	    vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR)				\
++	 += wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk	\
++	    wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk	\
++	    wcpncpy_chk							\
++	    swprintf_chk vswprintf_chk					\
++	    wcrtomb_chk mbsnrtowcs_chk					\
++	    wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk	\
++	    wcstombs_chk
++
+ static-only-routines := warning-nop stack_chk_fail_local
+ 
+ CFLAGS-backtrace.c = -fno-omit-frame-pointer
+@@ -131,11 +140,15 @@ LDFLAGS-tst-backtrace4 = -rdynamic
+ LDFLAGS-tst-backtrace5 = -rdynamic
+ LDFLAGS-tst-backtrace6 = -rdynamic
+ 
+-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
+-	tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
+-	tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
+-	tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
+-	tst-backtrace5 tst-backtrace6
++tests = tst-longjmp_chk test-strcpy_chk test-stpcpy_chk tst-longjmp_chk2
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++      += tst-chk1 tst-chk2 tst-chk3 tst-lfschk1 tst-lfschk2 tst-lfschk3
++tests-$(OPTION_EGLIBC_BACKTRACE) \
++      += backtrace-tst tst-backtrace2 tst-backtrace3 tst-backtrace4 \
++         tst-backtrace5 tst-backtrace6
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_EGLIBC_CXX_TESTS))
++tests += tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6
++endif
+ 
+ ifeq (,$(CXX))
+ tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \
+diff --git a/debug/segfault.c b/debug/segfault.c
+index 3459a2a..ee9a146 100644
+--- a/debug/segfault.c
++++ b/debug/segfault.c
+@@ -30,6 +30,7 @@
+ #include <unistd.h>
+ #include <_itoa.h>
+ #include <ldsodefs.h>
++#include <gnu/option-groups.h>
+ 
+ /* This file defines macros to access the content of the sigcontext element
+    passed up by the signal handler.  */
+@@ -68,11 +69,13 @@ write_strsignal (int fd, int signal)
+ static void
+ catch_segfault (int signal, SIGCONTEXT ctx)
+ {
+-  int fd, cnt, i;
+-  void **arr;
++  int fd;
+   struct sigaction sa;
++#if __OPTION_EGLIBC_BACKTRACE
++  int cnt, i;
++  void **arr;
+   uintptr_t pc;
+-
++#endif
+   /* This is the name of the file we are writing to.  If none is given
+      or we cannot write to this file write to stderr.  */
+   fd = 2;
+@@ -91,6 +94,7 @@ catch_segfault (int signal, SIGCONTEXT ctx)
+   REGISTER_DUMP;
+ #endif
+ 
++#if __OPTION_EGLIBC_BACKTRACE
+   WRITE_STRING ("\nBacktrace:\n");
+ 
+   /* Get the backtrace.  */
+@@ -113,6 +117,7 @@ catch_segfault (int signal, SIGCONTEXT ctx)
+ 
+   /* Now generate nicely formatted output.  */
+   __backtrace_symbols_fd (arr + i, cnt - i, fd);
++#endif
+ 
+ #ifdef HAVE_PROC_SELF
+   /* Now the link map.  */
+diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
+index 53559e6..362d92a 100644
+--- a/debug/tst-chk1.c
++++ b/debug/tst-chk1.c
+@@ -31,6 +31,7 @@
+ #include <sys/select.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ #define obstack_chunk_alloc malloc
+@@ -307,6 +308,7 @@ do_test (void)
+   snprintf (buf + 8, l0 + 3, "%d", num2);
+   CHK_FAIL_END
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   CHK_FAIL_START
+   swprintf (wbuf + 8, 3, L"%d", num1);
+   CHK_FAIL_END
+@@ -314,6 +316,7 @@ do_test (void)
+   CHK_FAIL_START
+   swprintf (wbuf + 8, l0 + 3, L"%d", num1);
+   CHK_FAIL_END
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ # endif
+ 
+   memcpy (buf, str1 + 2, l0 + 9);
+@@ -381,6 +384,7 @@ do_test (void)
+   CHK_FAIL_END
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+ 
+   /* These ops can be done without runtime checking of object size.  */
+   wmemcpy (wbuf, L"abcdefghij", 10);
+@@ -605,6 +609,7 @@ do_test (void)
+   CHK_FAIL_END
+ #endif
+ 
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   /* Now checks for %n protection.  */
+ 
+@@ -1192,6 +1197,7 @@ do_test (void)
+ # endif
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
+     {
+       assert (MB_CUR_MAX <= 10);
+@@ -1348,6 +1354,7 @@ do_test (void)
+       puts ("cannot set locale");
+       ret = 1;
+     }
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   int fd = posix_openpt (O_RDWR);
+   if (fd != -1)
+diff --git a/dlfcn/Makefile b/dlfcn/Makefile
+index 759780d..3827607 100644
+--- a/dlfcn/Makefile
++++ b/dlfcn/Makefile
+@@ -15,6 +15,8 @@
+ # License along with the GNU C Library; if not, see
+ # <http://www.gnu.org/licenses/>.
+ 
++include ../option-groups.mak
++
+ subdir		:= dlfcn
+ 
+ include ../Makeconfig
+@@ -36,8 +38,11 @@ endif
+ ifeq (yes,$(build-shared))
+ tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
+ 	bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
+-	bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen
++	tstatexit bug-dl-leaf tst-rec-dlopen
+ endif
++
++tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3
++
+ modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
+ 		defaultmod2 errmsg1mod modatexit modcxaatexit \
+ 		bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
+diff --git a/elf/dl-support.c b/elf/dl-support.c
+index 4d036f1..c15f405 100644
+--- a/elf/dl-support.c
++++ b/elf/dl-support.c
+@@ -19,6 +19,7 @@
+ /* This file defines some things that for the dynamic linker are defined in
+    rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */
+ 
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <libintl.h>
+ #include <stdlib.h>
+@@ -42,7 +43,9 @@ char **_dl_argv = &__progname;	/* This is checked for some error messages.  */
+ const char *_dl_platform;
+ size_t _dl_platformlen;
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ int _dl_debug_mask;
++#endif
+ int _dl_lazy;
+ ElfW(Addr) _dl_use_load_bias = -2;
+ int _dl_dynamic_weak;
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 6d3add7..fc3a2db 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -16,6 +16,7 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <dlfcn.h>
+ #include <fcntl.h>
+@@ -2201,6 +2202,7 @@ print_missing_version (int errcode __attribute__ ((unused)),
+ 		    objname, errstring);
+ }
+ \f
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ /* Nonzero if any of the debugging options is enabled.  */
+ static int any_debug attribute_relro;
+ 
+@@ -2310,6 +2312,7 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
+       _exit (0);
+     }
+ }
++#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
+ \f
+ static void
+ process_dl_audit (char *str)
+@@ -2349,8 +2352,9 @@ process_envvars (enum mode *modep)
+   char **runp = _environ;
+   char *envline;
+   enum mode mode = normal;
++#if __OPTION_EGLIBC_RTLD_DEBUG
+   char *debug_output = NULL;
+-
++#endif
+   /* This is the default place for profiling data file.  */
+   GLRO(dl_profile_output)
+     = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
+@@ -2377,12 +2381,14 @@ process_envvars (enum mode *modep)
+ 	  break;
+ 
+ 	case 5:
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	  /* Debugging of the dynamic linker?  */
+ 	  if (memcmp (envline, "DEBUG", 5) == 0)
+ 	    {
+ 	      process_dl_debug (&envline[6]);
+ 	      break;
+ 	    }
++#endif
+ 	  if (memcmp (envline, "AUDIT", 5) == 0)
+ 	    process_dl_audit (&envline[6]);
+ 	  break;
+@@ -2448,13 +2454,14 @@ process_envvars (enum mode *modep)
+ 	      break;
+ 	    }
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	  /* Where to place the profiling data file.  */
+ 	  if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
+ 	    {
+ 	      debug_output = &envline[13];
+ 	      break;
+ 	    }
+-
++#endif
+ 	  if (!__libc_enable_secure
+ 	      && memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
+ 	    GLRO(dl_dynamic_weak) = 1;
+@@ -2491,7 +2498,9 @@ process_envvars (enum mode *modep)
+ 	    {
+ 	      mode = trace;
+ 	      GLRO(dl_verbose) = 1;
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	      GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
++#endif
+ 	      GLRO(dl_trace_prelink) = &envline[17];
+ 	    }
+ 	  break;
+@@ -2538,12 +2547,15 @@ process_envvars (enum mode *modep)
+       if (__access ("/etc/suid-debug", F_OK) != 0)
+ 	{
+ 	  unsetenv ("MALLOC_CHECK_");
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	  GLRO(dl_debug_mask) = 0;
++#endif
+ 	}
+ 
+       if (mode != normal)
+ 	_exit (5);
+     }
++#if __OPTION_EGLIBC_RTLD_DEBUG
+   /* If we have to run the dynamic linker in debugging mode and the
+      LD_DEBUG_OUTPUT environment variable is given, we write the debug
+      messages to this file.  */
+@@ -2568,6 +2580,7 @@ process_envvars (enum mode *modep)
+ 	/* We use standard output if opening the file failed.  */
+ 	GLRO(dl_debug_fd) = STDOUT_FILENO;
+     }
++#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
+ }
+ 
+ 
+diff --git a/extra-lib.mk b/extra-lib.mk
+index b10748d..d71a06f 100644
+--- a/extra-lib.mk
++++ b/extra-lib.mk
+@@ -25,7 +25,9 @@ install-lib := $(install-lib)
+ extra-objs := $(extra-objs)
+ 
+ # The modules that go in $(lib).
+-all-$(lib)-routines := $($(lib)-routines) $($(lib)-sysdep_routines)
++all-$(lib)-routines := $($(lib)-routines)		\
++	               $($(lib)-routines-y)		\
++		       $($(lib)-sysdep_routines)
+ 
+ # Add each flavor of library to the lists of things to build and install.
+ install-lib += $(foreach o,$(object-suffixes-$(lib)),$(lib:lib%=$(libtype$o)))
+@@ -101,7 +103,7 @@ endif
+ endif
+ 
+ # This will define `libof-ROUTINE := LIB' for each of the routines.
+-cpp-srcs-left := $($(lib)-routines) $($(lib)-sysdep_routines)
++cpp-srcs-left := $(all-$(lib)-routines)
+ ifneq (,$(cpp-srcs-left))
+ include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
+ endif
+diff --git a/grp/Makefile b/grp/Makefile
+index c63b552..7486f32 100644
+--- a/grp/Makefile
++++ b/grp/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for grp portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= grp
+ 
+ include ../Makeconfig
+@@ -29,6 +31,9 @@ routines := fgetgrent initgroups setgroups \
+ 	    getgrent_r getgrgid_r getgrnam_r fgetgrent_r
+ 
+ tests := testgrp
++ifneq (y,$(OPTION_EGLIBC_NSSWITCH))
++LDLIBS-testgrp += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
++endif
+ 
+ ifeq (yes,$(build-shared))
+ test-srcs :=  tst_fgetgrent
+diff --git a/hesiod/Makefile b/hesiod/Makefile
+index ac0bc01..38263b4 100644
+--- a/hesiod/Makefile
++++ b/hesiod/Makefile
+@@ -18,12 +18,14 @@
+ #
+ #	Sub-makefile for hesiod portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= hesiod
+ 
+ include ../Makeconfig
+ 
+-extra-libs := libnss_hesiod
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_INET) += libnss_hesiod
++extra-libs-others-y += $(extra-libs-y)
+ 
+ subdir-dirs = nss_hesiod
+ vpath %.c nss_hesiod
+diff --git a/iconv/Makefile b/iconv/Makefile
+index 0d55eda..a1847c6 100644
+--- a/iconv/Makefile
++++ b/iconv/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for iconv.
+ #
++include ../option-groups.mak
++
+ subdir	:= iconv
+ 
+ include ../Makeconfig
+@@ -39,6 +41,11 @@ CFLAGS-iconv_charmap.c = -I../locale/programs
+ CFLAGS-dummy-repertoire.c = -I../locale/programs
+ CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
+ 		   -DDEFAULT_CHARMAP=null_pointer -DNEED_NULL_POINTER
++
++ifneq (y,$(OPTION_EGLIBC_SPAWN))
++CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
++endif
++
+ CFLAGS-linereader.c = -DNO_TRANSLITERATION
+ CFLAGS-simple-hash.c = -I../locale
+ 
+diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
+index ce46216..ea18964 100644
+--- a/iconv/gconv_db.c
++++ b/iconv/gconv_db.c
+@@ -25,6 +25,7 @@
+ #include <sys/param.h>
+ #include <bits/libc-lock.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ 
+ #include <dlfcn.h>
+ #include <gconv_int.h>
+@@ -828,9 +829,11 @@ free_modules_db (struct gconv_module *node)
+ /* Free all resources if necessary.  */
+ libc_freeres_fn (free_mem)
+ {
++#if __OPTION_EGLIBC_LOCALE_CODE
+   /* First free locale memory.  This needs to be done before freeing derivations,
+      as ctype cleanup functions dereference steps arrays which we free below.  */
+   _nl_locale_subfreeres ();
++#endif
+ 
+   /* finddomain.c has similar problem.  */
+   extern void _nl_finddomain_subfreeres (void) attribute_hidden;
+diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
+index 5d5d4d7..a7d3072 100644
+--- a/iconv/gconv_trans.c
++++ b/iconv/gconv_trans.c
+@@ -23,6 +23,7 @@
+ #include <stdint.h>
+ #include <string.h>
+ #include <stdlib.h>
++#include <gnu/option-groups.h>
+ 
+ #include <bits/libc-lock.h>
+ #include "gconv_int.h"
+@@ -38,15 +39,19 @@ __gconv_transliterate (struct __gconv_step *step,
+ 		       unsigned char **outbufstart, size_t *irreversible)
+ {
+   /* Find out about the locale's transliteration.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+   uint_fast32_t size;
+   const uint32_t *from_idx;
+   const uint32_t *from_tbl;
+   const uint32_t *to_idx;
+   const uint32_t *to_tbl;
++#endif
+   const uint32_t *winbuf;
+   const uint32_t *winbufend;
++#if __OPTION_EGLIBC_LOCALE_CODE
+   uint_fast32_t low;
+   uint_fast32_t high;
++#endif
+ 
+   /* The input buffer.  There are actually 4-byte values.  */
+   winbuf = (const uint32_t *) *inbufp;
+@@ -58,6 +63,7 @@ __gconv_transliterate (struct __gconv_step *step,
+     PTR_DEMANGLE (fct);
+ #endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   /* If there is no transliteration information in the locale don't do
+      anything and return the error.  */
+   size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_TAB_SIZE);
+@@ -193,6 +199,7 @@ __gconv_transliterate (struct __gconv_step *step,
+              sorted.  */
+ 	  break;
+     }
++#endif
+ 
+   /* One last chance: use the default replacement.  */
+   if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN) != 0)
+diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
+index e249bce..403ece5 100644
+--- a/iconv/iconv_prog.c
++++ b/iconv/iconv_prog.c
+@@ -35,6 +35,7 @@
+ #ifdef _POSIX_MAPPED_FILES
+ # include <sys/mman.h>
+ #endif
++#include <gnu/option-groups.h>
+ #include <charmap.h>
+ #include <gconv_int.h>
+ #include "iconv_prog.h"
+@@ -221,10 +222,17 @@ main (int argc, char *argv[])
+ 	      bool to_wrong =
+ 		(iconv_open (to_code, "UTF-8") == (iconv_t) -1
+ 		 && errno == EINVAL);
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	      const char *from_pretty =
+ 		(from_code[0] ? from_code : nl_langinfo (CODESET));
+ 	      const char *to_pretty =
+ 		(orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET));
++#else
++	      const char *from_pretty =
++		(from_code[0] ? from_code : "ANSI_X3.4-1968");
++	      const char *to_pretty =
++                 (orig_to_code[0] ? orig_to_code : "ANSI_X3.4-1968");
++#endif
+ 
+ 	      if (from_wrong)
+ 		{
+diff --git a/iconvdata/Makefile b/iconvdata/Makefile
+index a3d1d09..0832708 100644
+--- a/iconvdata/Makefile
++++ b/iconvdata/Makefile
+@@ -18,12 +18,15 @@
+ #
+ #	Makefile for iconv data and code.
+ #
++include ../option-groups.mak
++
+ subdir	:= iconvdata
+ 
+ include ../Makeconfig
+ 
+ # Names of all the shared objects which implement the transformations.
+-modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
++modules-$(OPTION_EGLIBC_CHARSETS)					 \
++	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
+ 	   ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10		 \
+ 	   ISO8859-11 ISO8859-13 ISO8859-14 ISO8859-15 ISO8859-16	 \
+ 	   T.61 ISO_6937 SJIS KOI-8 HP-ROMAN8 HP-ROMAN9 EBCDIC-AT-DE	 \
+@@ -63,11 +66,13 @@ modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
+ 	   MAC-CENTRALEUROPE KOI8-RU ISO8859-9E				 \
+ 	   CP770 CP771 CP772 CP773 CP774
+ 
+-modules.so := $(addsuffix .so, $(modules))
++modules.so := $(addsuffix .so, $(modules-y))
+ 
+ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+-	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9
++	tst-iconv6 bug-iconv5 bug-iconv8 bug-iconv9
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += bug-iconv6 tst-iconv7
++
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -127,13 +132,13 @@ ifeq (yes,$(build-shared))
+ # Rule to generate the shared objects.
+ charmaps = ../localedata/charmaps
+ -include $(objpfx)iconv-rules
+-extra-modules-left := $(modules)
++extra-modules-left := $(modules-y)
+ include extra-module.mk
+ 
+ 
+ extra-objs	+= $(modules.so)
+-install-others	= $(addprefix $(inst_gconvdir)/, $(modules.so))	\
+-		  $(inst_gconvdir)/gconv-modules
++install-others-y += $(addprefix $(inst_gconvdir)/, $(modules.so))
++install-others-$(OPTION_EGLIBC_CHARSETS) += $(inst_gconvdir)/gconv-modules
+ 
+ # We can build the conversion tables for numerous charsets automatically.
+ 
+@@ -201,7 +206,7 @@ before-compile += $(addprefix $(objpfx),$(generated-modules:=.h))
+ ifndef avoid-generated
+ $(objpfx)iconv-rules: Makefile
+ 	$(make-target-directory)
+-	{ echo $(filter-out lib%, $(modules)); \
++	{ echo $(filter-out lib%, $(modules-y)); \
+ 	  echo 8bit $(gen-8bit-modules); \
+ 	  echo 8bit-gap $(gen-8bit-gap-modules); } | \
+ 	LC_ALL=C \
+@@ -245,7 +250,7 @@ $(addprefix $(inst_gconvdir)/, $(modules.so)): \
+ 	$(do-install-program)
+ $(inst_gconvdir)/gconv-modules: gconv-modules $(+force)
+ 	$(do-install)
+-ifeq (no,$(cross-compiling))
++# eglibc: ifeq (no,$(cross-compiling))
+ # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
+ # if this libc has more gconv modules than the previously installed one.
+ 	if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \
+@@ -254,9 +259,9 @@ ifeq (no,$(cross-compiling))
+ 	   $(common-objpfx)iconv/iconvconfig \
+ 	     $(addprefix --prefix=,$(install_root)); \
+ 	fi
+-else
+-	@echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
+-endif
++# eglibc: else
++# eglibc:	@echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
++# eglibc: endif
+ 
+ endif # build-shared = yes
+ 
+diff --git a/include/netdb.h b/include/netdb.h
+index e1f051d..f6d15aa 100644
+--- a/include/netdb.h
++++ b/include/netdb.h
+@@ -232,6 +232,10 @@ extern enum nss_status _nss_ ## service ## _gethostbyname2_r		      \
+ 		       (const char *name, int af, struct hostent *host,	      \
+ 			char *buffer, size_t buflen, int *errnop,	      \
+ 			int *h_errnop);					      \
++extern enum nss_status _nss_ ## service ## _gethostbyname3_r		      \
++		       (const char *name, int af, struct hostent *result,     \
++			char *buffer, size_t buflen, int *errnop,	      \
++			int *h_errnop, int32_t *ttlp, char **canonp);         \
+ extern enum nss_status _nss_ ## service ## _gethostbyname_r		      \
+ 		       (const char *name, struct hostent *host, char *buffer, \
+ 			size_t buflen, int *errnop, int *h_errnop);	      \
+diff --git a/inet/Makefile b/inet/Makefile
+index f1d871f..7cb1709 100644
+--- a/inet/Makefile
++++ b/inet/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for inet portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= inet
+ 
+ include ../Makeconfig
+@@ -27,7 +29,8 @@ headers	:= netinet/ether.h netinet/in.h netinet/in_systm.h \
+ 	   netinet/tcp.h netinet/ip.h $(wildcard arpa/*.h protocols/*.h) \
+ 	   aliases.h ifaddrs.h netinet/ip6.h netinet/icmp6.h bits/in.h
+ 
+-routines := htonl htons		\
++routines-$(OPTION_EGLIBC_INET) \
++	 += htonl htons \
+ 	    inet_lnaof inet_mkadr	\
+ 	    inet_netof inet_ntoa inet_net herrno herrno-loc \
+ 	    gethstbyad gethstbyad_r gethstbynm gethstbynm2 gethstbynm2_r \
+@@ -39,18 +42,23 @@ routines := htonl htons		\
+ 	    getservent_r	\
+ 	    ether_aton ether_aton_r ether_hton ether_line \
+ 	    ether_ntoa ether_ntoa_r ether_ntoh \
+-	    rcmd rexec ruserpass \
+ 	    getnetgrent_r getnetgrent \
+-	    getaliasent_r getaliasent getaliasname getaliasname_r \
+-	    in6_addr getnameinfo if_index ifaddrs inet6_option \
++	    in6_addr getnameinfo if_index ifaddrs \
+ 	    getipv4sourcefilter setipv4sourcefilter \
+-	    getsourcefilter setsourcefilter inet6_opt inet6_rth
++	    getsourcefilter setsourcefilter
++routines-$(OPTION_EGLIBC_RCMD) \
++	 += rcmd rexec ruserpass
++routines-$(OPTION_EGLIBC_DB_ALIASES) \
++	 += getaliasent_r getaliasent getaliasname getaliasname_r
++routines-$(OPTION_EGLIBC_ADVANCED_INET6) \
++	 += inet6_option inet6_opt inet6_rth
+ 
+-aux := check_pf check_native ifreq
++aux-$(OPTION_EGLIBC_INET) += check_pf check_native ifreq
+ 
+ tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
+-	 tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
++	 tst-gethnm test-ifaddrs bug-if1 tst-ether_line \
+ 	 tst-getni1 tst-getni2 tst-inet6_rth tst-checks
++tests-$(OPTION_EGLIBC_ADVANCED_INET6) += test-inet6_opt
+ 
+ include ../Rules
+ 
+diff --git a/intl/Makefile b/intl/Makefile
+index 9ecf8fe..587bc0d 100644
+--- a/intl/Makefile
++++ b/intl/Makefile
+@@ -16,6 +16,7 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ # Makefile for intl subdirectory: message handling code from GNU gettext.
++include ../option-groups.mak
+ 
+ subdir = intl
+ 
+@@ -48,7 +49,7 @@ endif
+ $(objpfx)plural.o: plural.c
+ 
+ ifeq ($(run-built-tests),yes)
+-ifeq (yes,$(build-shared))
++ifeq (yyyes,$(OPTION_EGLIBC_LOCALES)$(OPTION_EGLIBC_LOCALE_CODE)$(build-shared))
+ ifneq ($(strip $(MSGFMT)),:)
+ tests-special += $(objpfx)tst-translit.out $(objpfx)tst-gettext.out \
+ 		 $(objpfx)tst-gettext2.out $(objpfx)tst-codeset.out \
+diff --git a/intl/dcigettext.c b/intl/dcigettext.c
+index 8a3f091..e271648 100644
+--- a/intl/dcigettext.c
++++ b/intl/dcigettext.c
+@@ -100,11 +100,15 @@ extern int errno;
+ # include "libgnuintl.h"
+ #endif
+ #include "hash-string.h"
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
+ 
+ /* Handle multi-threaded applications.  */
+ #ifdef _LIBC
+ # include <bits/libc-lock.h>
+ # define gl_rwlock_define_initialized __libc_rwlock_define_initialized
++# define gl_rwlock_define __libc_rwlock_define
+ # define gl_rwlock_rdlock __libc_rwlock_rdlock
+ # define gl_rwlock_wrlock __libc_rwlock_wrlock
+ # define gl_rwlock_unlock __libc_rwlock_unlock
+@@ -523,8 +527,10 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
+   saved_errno = errno;
+ 
+ #ifdef _LIBC
+-  __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
+-  __libc_rwlock_rdlock (__libc_setlocale_lock);
++# if __OPTION_EGLIBC_LOCALE_CODE
++  gl_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
++  gl_rwlock_rdlock (__libc_setlocale_lock);
++# endif
+ #endif
+ 
+   gl_rwlock_rdlock (_nl_state_lock);
+@@ -550,7 +556,11 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
+ #ifdef HAVE_PER_THREAD_LOCALE
+ # ifndef IN_LIBGLOCALE
+ #  ifdef _LIBC
+-  localename = strdupa (__current_locale_name (category));
++#   if __OPTION_EGLIBC_LOCALE_CODE
++      localename = strdupa (__current_locale_name (category));
++#   else
++      localename = "C";
++#   endif
+ #  else
+   categoryname = category_to_name (category);
+ #   define CATEGORYNAME_INITIALIZED
+@@ -581,10 +591,12 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
+       else
+ 	retval = (char *) (*foundp)->translation;
+ 
+-      gl_rwlock_unlock (_nl_state_lock);
+ # ifdef _LIBC
+-      __libc_rwlock_unlock (__libc_setlocale_lock);
++#  if __OPTION_EGLIBC_LOCALE_CODE
++      gl_rwlock_unlock (__libc_setlocale_lock);
++#  endif
+ # endif
++      gl_rwlock_unlock (_nl_state_lock);
+       __set_errno (saved_errno);
+       return retval;
+     }
+@@ -838,10 +850,13 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
+ 	      if (plural)
+ 		retval = plural_lookup (domain, n, retval, retlen);
+ 
+-	      gl_rwlock_unlock (_nl_state_lock);
+ #ifdef _LIBC
+-	      __libc_rwlock_unlock (__libc_setlocale_lock);
++# if __OPTION_EGLIBC_LOCALE_CODE
++
++	      gl_rwlock_unlock (__libc_setlocale_lock);
++# endif
+ #endif
++	      gl_rwlock_unlock (_nl_state_lock);
+ 	      return retval;
+ 	    }
+ 	}
+@@ -850,10 +865,12 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
+  return_untranslated:
+   /* Return the untranslated MSGID.  */
+   FREE_BLOCKS (block_list);
+-  gl_rwlock_unlock (_nl_state_lock);
+ #ifdef _LIBC
+-  __libc_rwlock_unlock (__libc_setlocale_lock);
++# if __OPTION_EGLIBC_LOCALE_CODE
++   gl_rwlock_unlock (__libc_setlocale_lock);
++# endif
+ #endif
++  gl_rwlock_unlock (_nl_state_lock);
+ #ifndef _LIBC
+   if (!ENABLE_SECURE)
+     {
+@@ -1550,7 +1567,11 @@ guess_category_value (int category, const char *categoryname)
+      `LC_xxx', and `LANG'.  On some systems this can be done by the
+      `setlocale' function itself.  */
+ # ifdef _LIBC
++#  if __OPTION_EGLIBC_LOCALE_CODE
+   locale = __current_locale_name (category);
++#  else
++  locale = "C";
++#  endif
+ # else
+   locale_defaulted = 0;
+ #  if HAVE_USELOCALE
+diff --git a/io/Makefile b/io/Makefile
+index 613dce0..697439e 100644
+--- a/io/Makefile
++++ b/io/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for I/O portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= io
+ 
+ include ../Makeconfig
+@@ -36,7 +38,7 @@ routines :=								\
+ 	fxstatat fxstatat64						\
+ 	statfs fstatfs statfs64 fstatfs64				\
+ 	statvfs fstatvfs statvfs64 fstatvfs64				\
+-	umask chmod fchmod lchmod fchmodat				\
++	umask chmod fchmod fchmodat					\
+ 	mkdir mkdirat							\
+ 	open open_2 open64 open64_2 openat openat_2 openat64 openat64_2	\
+ 	read write lseek lseek64 access euidaccess faccessat		\
+@@ -49,11 +51,13 @@ routines :=								\
+ 	ttyname ttyname_r isatty					\
+ 	link linkat symlink symlinkat readlink readlinkat		\
+ 	unlink unlinkat rmdir						\
+-	ftw ftw64 fts poll ppoll					\
++	poll ppoll							\
+ 	posix_fadvise posix_fadvise64					\
+ 	posix_fallocate posix_fallocate64				\
+ 	sendfile sendfile64 \
+ 	utimensat futimens
++routines-$(OPTION_EGLIBC_BSD) += lchmod
++routines-$(OPTION_EGLIBC_FTRAVERSE) += ftw ftw64 fts
+ 
+ aux := have_o_cloexec
+ 
+@@ -64,18 +68,22 @@ static-only-routines = stat fstat lstat stat64 fstat64 lstat64	\
+ 		       fstatat fstatat64 mknod mknodat
+ 
+ others		:= pwd
+-test-srcs	:= ftwtest
++test-srcs-$(OPTION_EGLIBC_FTRAVERSE) := ftwtest
+ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
+-		   tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \
++		   tst-fcntl tst-statvfs \
+ 		   tst-openat tst-unlinkat tst-fstatat tst-futimesat \
+ 		   tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
+ 		   tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
+-		   tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
++		   tst-mknodat tst-mkfifoat tst-ttyname_r \
+ 		   tst-posix_fallocate
++tests-$(OPTION_EGLIBC_FTRAVERSE) += bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 \
++				    bug-ftw5
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_EGLIBC_FTRAVERSE))
+ tests-special += $(objpfx)ftwtest.out
+ endif
++endif
+ 
+ include ../Rules
+ 
+diff --git a/libidn/Makefile b/libidn/Makefile
+index 940fa52..43aad0c 100644
+--- a/libidn/Makefile
++++ b/libidn/Makefile
+@@ -16,6 +16,7 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ # Makefile for libidn subdirectory of GNU C Library.
++include ../option-groups.mak
+ 
+ subdir	:= libidn
+ 
+@@ -23,8 +24,8 @@ include ../Makeconfig
+ 
+ routines = idn-stub
+ 
+-extra-libs		= libcidn
+-extra-libs-others	= $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_IDN) = libcidn
++extra-libs-others-y = $(extra-libs-y)
+ 
+ libcidn-routines := punycode toutf8 nfkc stringprep rfc3454 profiles idna \
+ 		    iconvme
+diff --git a/libidn/toutf8.c b/libidn/toutf8.c
+index c7e67ca..62df478 100644
+--- a/libidn/toutf8.c
++++ b/libidn/toutf8.c
+@@ -33,6 +33,11 @@
+ /* Get strlen. */
+ #include <string.h>
+ 
++/* Get __OPTION_EGLIBC_LOCALE_CODE.  */
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ /* Get iconv_string. */
+ #include "iconvme.h"
+ 
+@@ -47,7 +52,11 @@
+ #endif
+ 
+ #ifdef _LIBC
+-# define stringprep_locale_charset() nl_langinfo (CODESET)
++# if __OPTION_EGLIBC_LOCALE_CODE
++#  define stringprep_locale_charset() nl_langinfo (CODESET)
++# else
++#  define stringprep_locale_charset() "ANSI_X3.4-1968"
++# endif
+ #else
+ /**
+  * stringprep_locale_charset - return charset used in current locale
+diff --git a/libio/Makefile b/libio/Makefile
+index 7b3bcf9..27c9186 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Specific makefile for libio.
+ #
++include ../option-groups.mak
++
+ subdir	:= libio
+ 
+ include ../Makeconfig
+@@ -27,16 +29,13 @@ headers	:= stdio.h libio.h _G_config.h bits/stdio.h bits/stdio-lock.h \
+ 
+ routines	:=							      \
+ 	filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
+-	iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc	      \
++	iofopncook iofputs iofread iofsetpos ioftell			      \
+ 	iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs	      \
+ 	ioseekoff ioseekpos iosetbuffer iosetvbuf ioungetc		      \
+ 	iovsprintf iovsscanf						      \
+ 	iofgetpos64 iofopen64 iofsetpos64				      \
+-	fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
+-	iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u	      \
+-	putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf      \
+-	wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops   \
+-	wstrops wfileops iofwide fwide wmemstream			      \
++	putchar putchar_u						      \
++	iofwide								      \
+ 									      \
+ 	clearerr feof ferror fileno fputc freopen fseek getc getchar	      \
+ 	memstream pclose putc putchar rewind setbuf setlinebuf vasprintf      \
+@@ -48,24 +47,49 @@ routines	:=							      \
+ 									      \
+ 	libc_fatal fmemopen oldfmemopen
+ 
+-tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
+-	tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \
+-	tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf	      \
+-	tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof          \
+-	tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	wfiledoalloc                                                          \
++	iowpadn                                                               \
++	swprintf                                                              \
++	vswprintf iovswscanf swscanf wgenops                                  \
++	wstrops wfileops wmemstream
++routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) +=	      \
++	wdummyfileops
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) +=				      \
++	fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
++	iofputws iofputws_u iogetwline ioungetwc putwc putwc_u                \
++	putwchar putwchar_u fwprintf vwprintf                                 \
++	wprintf wscanf fwscanf vwscanf                                        \
++	fwide
++
++tests = test-fmemopen tst-ext tst-ext2 \
++	tst-mmap-setvbuf tst-atime tst-eof \
++	tst-freopen bug-ungetc bug-fseek \
+ 	tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \
+-	tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \
+-	bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \
++	tst-mmap2-eofsync tst-mmap-offend bug-fopena+ \
++	bug-ungetc2 bug-ungetc3 bug-ungetc4 \
+ 	tst-memstream1 tst-memstream2 \
+-	tst-wmemstream1 tst-wmemstream2 \
+-	bug-memstream1 bug-wmemstream1 \
+-	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
+-	tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
+-	tst-ftell-append tst-fputws
++	bug-memstream1 tst-popen1 tst-fwrite-error \
++	tst-ftell-active-handler tst-ftell-append
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++	+= tst-swscanf tst-fgetws tst-setvbuf1 \
++	tst-ungetwc1 tst-ungetwc2 bug-ftell bug-ungetwc2 \
++	tst-widetext tst-fputws
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
++	+= bug-rewind bug-rewind2 bug-ungetwc1 \
++	bug-wfflush bug-wmemstream1 tst-fopenloc2 \
++	tst_getwc \
++	tst_putwc tst_wprintf tst_wprintf2 tst_wscanf \
++	tst-fgetwc bug-wsetpos tst-fseek tst-ftell-partial-wide
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++	+= tst_swprintf tst_swscanf \
++	tst-sscanf \
++	tst-wmemstream1 tst-wmemstream2
++
+ ifeq (yes,$(build-shared))
+ # Add test-fopenloc only if shared library is enabled since it depends on
+ # shared localedata objects.
+-tests += tst-fopenloc
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-fopenloc
+ endif
+ test-srcs = test-freopen
+ 
+@@ -164,13 +188,17 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops	\
+ 		       oldiofsetpos64
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
+ tests-special += $(objpfx)test-freopen.out
++endif
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ ifeq (yes,$(build-shared))
+ # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
+ # library is enabled since they depend on tst-fopenloc.out.
+ tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out
+ endif
+ endif
++endif
+ 
+ include ../Rules
+ 
+diff --git a/libio/__fpurge.c b/libio/__fpurge.c
+index 065cf61..e32a3e9 100644
+--- a/libio/__fpurge.c
++++ b/libio/__fpurge.c
+@@ -21,7 +21,7 @@
+ void
+ __fpurge (FILE *fp)
+ {
+-  if (fp->_mode > 0)
++  if (_IO_is_wide (fp))
+     {
+       /* Wide-char stream.  */
+       if (_IO_in_backup (fp))
+diff --git a/libio/fileops.c b/libio/fileops.c
+index cbcd6f5..19e43c2 100644
+--- a/libio/fileops.c
++++ b/libio/fileops.c
+@@ -39,6 +39,7 @@
+ #include <string.h>
+ #include <errno.h>
+ #include <unistd.h>
++#include <gnu/option-groups.h>
+ #include <stdlib.h>
+ #if _LIBC
+ # include "../wcsmbs/wcsmbsload.h"
+@@ -173,7 +174,7 @@ _IO_new_file_close_it (_IO_FILE *fp)
+ 
+   /* Free buffer. */
+ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
+-  if (fp->_mode > 0)
++  if (_IO_is_wide (fp))
+     {
+       if (_IO_have_wbackup (fp))
+ 	_IO_free_wbackup_area (fp);
+@@ -348,6 +349,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
+       cs = strstr (last_recognized + 1, ",ccs=");
+       if (cs != NULL)
+ 	{
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ 	  /* Yep.  Load the appropriate conversions and set the orientation
+ 	     to wide.  */
+ 	  struct gconv_fcts fcts;
+@@ -418,6 +420,12 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
+ 
+ 	  /* Set the mode now.  */
+ 	  result->_mode = 1;
++#else
++          /* Treat this as if we couldn't find the given character set.  */
++          (void) _IO_file_close_it (fp);
++          __set_errno (EINVAL);
++          return NULL;
++#endif
+ 	}
+     }
+ 
+diff --git a/libio/iofwide.c b/libio/iofwide.c
+index 0c175d1..3e9f52b 100644
+--- a/libio/iofwide.c
++++ b/libio/iofwide.c
+@@ -26,6 +26,7 @@
+ 
+ #include <libioP.h>
+ #ifdef _LIBC
++# include <gnu/option-groups.h>
+ # include <dlfcn.h>
+ # include <wchar.h>
+ #endif
+@@ -43,6 +44,8 @@
+ #endif
+ 
+ 
++#if ! defined _LIBC || __OPTION_POSIX_C_LANG_WIDE_CHAR
++
+ /* Prototypes of libio's codecvt functions.  */
+ static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
+ 				     __mbstate_t *statep,
+@@ -499,3 +502,26 @@ do_max_length (struct _IO_codecvt *codecvt)
+   return MB_CUR_MAX;
+ #endif
+ }
++
++#else
++/* OPTION_POSIX_C_LANG_WIDE_CHAR is disabled.  */
++
++#undef _IO_fwide
++int
++_IO_fwide (fp, mode)
++     _IO_FILE *fp;
++     int mode;
++{
++  /* Die helpfully if the user tries to create a wide stream; I
++     disbelieve that most users check the return value from
++     'fwide (fp, 1)'.  */
++  assert (mode <= 0);
++
++  /* We can only make streams byte-oriented, which is trivial.  */
++  if (mode < 0)
++    fp->_mode = -1;
++
++  return fp->_mode;
++}
++
++#endif
+diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c
+index 11765cf..15d6230 100644
+--- a/libio/ioseekoff.c
++++ b/libio/ioseekoff.c
+@@ -60,7 +60,7 @@ _IO_seekoff_unlocked (fp, offset, dir, mode)
+ 	  else
+ 	    abort ();
+ 	}
+-      if (_IO_fwide (fp, 0) < 0)
++      if (! _IO_is_wide (fp))
+ 	_IO_free_backup_area (fp);
+       else
+ 	_IO_free_wbackup_area (fp);
+diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c
+index a7652a1..6938b68 100644
+--- a/libio/ioseekpos.c
++++ b/libio/ioseekpos.c
+@@ -35,7 +35,7 @@ _IO_seekpos_unlocked (fp, pos, mode)
+   /* If we have a backup buffer, get rid of it, since the __seekoff
+      callback may not know to do the right thing about it.
+      This may be over-kill, but it'll do for now. TODO */
+-  if (_IO_fwide (fp, 0) <= 0)
++  if (! _IO_is_wide (fp))
+     {
+       if (_IO_have_backup (fp))
+ 	_IO_free_backup_area (fp);
+diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c
+index 0a41c10..3d99fa0 100644
+--- a/libio/iosetbuffer.c
++++ b/libio/iosetbuffer.c
+@@ -24,6 +24,8 @@
+    This exception applies to code released by its copyright holders
+    in files containing the exception.  */
+ 
++#include <gnu/option-groups.h>
++
+ #include "libioP.h"
+ 
+ void
+@@ -38,9 +40,11 @@ _IO_setbuffer (fp, buf, size)
+   if (!buf)
+     size = 0;
+   (void) _IO_SETBUF (fp, buf, size);
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp))
+     /* We also have to set the buffer using the wide char function.  */
+     (void) _IO_WSETBUF (fp, buf, size);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+   _IO_release_lock (fp);
+ }
+ libc_hidden_def (_IO_setbuffer)
+diff --git a/libio/libioP.h b/libio/libioP.h
+index 0f16e2d..d2626d6 100644
+--- a/libio/libioP.h
++++ b/libio/libioP.h
+@@ -44,6 +44,10 @@
+ /*# include <comthread.h>*/
+ #endif
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #include <math_ldbl_opt.h>
+ 
+ #include "iolibio.h"
+@@ -523,8 +527,20 @@ extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW;
+ 
+ 
+ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
++
++/* _IO_is_wide (fp) is roughly equivalent to '_IO_fwide (fp, 0) > 0',
++   except that when OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, it
++   expands to a constant, allowing the compiler to realize that it can
++   eliminate code that references wide stream handling functions.
++   This, in turn, allows us to omit them.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define _IO_is_wide(_f) ((_f)->_mode > 0)
++#else
++# define _IO_is_wide(_f) (0)
++#endif
++
+ # define _IO_do_flush(_f) \
+-  ((_f)->_mode <= 0							      \
++  (! _IO_is_wide (_f)                                                         \
+    ? _IO_do_write(_f, (_f)->_IO_write_base,				      \
+ 		  (_f)->_IO_write_ptr-(_f)->_IO_write_base)		      \
+    : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base,		      \
+diff --git a/libio/wdummyfileops.c b/libio/wdummyfileops.c
+new file mode 100644
+index 0000000..c0150b8
+--- /dev/null
++++ b/libio/wdummyfileops.c
+@@ -0,0 +1,161 @@
++/* 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.
++
++   As a special exception, if you link the code in this file with
++   files compiled with a GNU compiler to produce an executable,
++   that does not cause the resulting executable to be covered by
++   the GNU Lesser General Public License.  This exception does not
++   however invalidate any other reasons why the executable file
++   might be covered by the GNU Lesser General Public License.
++   This exception applies to code released by its copyright holders
++   in files containing the exception.  */
++
++#include <assert.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <libioP.h>
++
++static void __THROW __attribute__ ((__noreturn__))
++_IO_wfile_wide_char_support_disabled (void)
++{
++  static const char errstr[]
++    = ("The application tried to use wide character I/O, but libc.so"
++       " was compiled\n"
++       "with the OPTION_POSIX_C_LANG_WIDE_CHAR option group disabled.\n");
++  __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
++  abort ();
++}
++
++static void
++_IO_wfile_disabled_void_int (_IO_FILE *fp, int x)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_int_int (_IO_FILE *fp, int x)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_int_none (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_size_t
++_IO_wfile_disabled_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_size_t
++_IO_wfile_disabled_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seekoff (_IO_FILE *fp, _IO_off64_t off, int dir, int mode)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seekpos (_IO_FILE *fp, _IO_off64_t pos, int flags)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_FILE *
++_IO_wfile_disabled_setbuf (_IO_FILE *fp, char *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_ssize_t
++_IO_wfile_disabled_read (_IO_FILE *fp, void *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_ssize_t
++_IO_wfile_disabled_write (_IO_FILE *fp, const void *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seek (_IO_FILE *fp, _IO_off64_t offset, int mode)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_close (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_stat (_IO_FILE *fp, void *buf)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_showmanyc (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static void
++_IO_wfile_disabled_imbue (_IO_FILE *fp, void *locale)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static const struct _IO_jump_t _IO_wfile_jumps_disabled =
++{
++  JUMP_INIT_DUMMY,
++  JUMP_INIT(finish, _IO_wfile_disabled_void_int),
++  JUMP_INIT(overflow, _IO_wfile_disabled_int_int),
++  JUMP_INIT(underflow, _IO_wfile_disabled_int_none),
++  JUMP_INIT(uflow, _IO_wfile_disabled_int_none),
++  JUMP_INIT(pbackfail, _IO_wfile_disabled_int_int),
++  JUMP_INIT(xsputn, _IO_wfile_disabled_xsputn),
++  JUMP_INIT(xsgetn, _IO_wfile_disabled_xsgetn),
++  JUMP_INIT(seekoff, _IO_wfile_disabled_seekoff),
++  JUMP_INIT(seekpos, _IO_wfile_disabled_seekpos),
++  JUMP_INIT(setbuf, _IO_wfile_disabled_setbuf),
++  JUMP_INIT(sync, _IO_wfile_disabled_int_none),
++  JUMP_INIT(doallocate, _IO_wfile_disabled_int_none),
++  JUMP_INIT(read, _IO_wfile_disabled_read),
++  JUMP_INIT(write, _IO_wfile_disabled_write),
++  JUMP_INIT(seek, _IO_wfile_disabled_seek),
++  JUMP_INIT(close, _IO_wfile_disabled_close),
++  JUMP_INIT(stat, _IO_wfile_disabled_stat),
++  JUMP_INIT(showmanyc, _IO_wfile_disabled_showmanyc),
++  JUMP_INIT(imbue, _IO_wfile_disabled_imbue)
++};
++
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps)
++libc_hidden_data_def (_IO_wfile_jumps)
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_mmap)
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_maybe_mmap)
+diff --git a/locale/C-ctype.c b/locale/C-ctype.c
+index aa5f19f..06be081 100644
+--- a/locale/C-ctype.c
++++ b/locale/C-ctype.c
+@@ -19,8 +19,11 @@
+ #include "localeinfo.h"
+ #include <endian.h>
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ #include "C-translit.h"
++#endif
+ 
+ /* This table's entries are taken from POSIX.2 Table 2-6
+    ``LC_CTYPE Category Definition in the POSIX Locale''.
+@@ -634,6 +637,7 @@ const struct __locale_data _nl_C_LC_CTYPE attribute_hidden =
+     { .word = L'7' },
+     { .word = L'8' },
+     { .word = L'9' },
++#if __OPTION_EGLIBC_LOCALE_CODE
+     /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
+     { .word = NTRANSLIT },
+     /* _NL_CTYPE_TRANSLIT_FROM_IDX */
+@@ -644,6 +648,22 @@ const struct __locale_data _nl_C_LC_CTYPE attribute_hidden =
+     { .wstr = translit_to_idx },
+     /* _NL_CTYPE_TRANSLIT_TO_TBL */
+     { .wstr = (uint32_t *) translit_to_tbl },
++#else
++    /* If the locale code isn't enabled, we don't have the
++       transliteration code in iconv/gconv_trans.c anyway, so there's
++       no need for the transliteration tables here.  We'll fall back
++       on the default missing replacement, '?'.  */
++    /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
++    { .word = 0 },
++    /* _NL_CTYPE_TRANSLIT_FROM_IDX */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_FROM_TBL */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_TO_IDX */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_TO_TBL */
++    { .wstr = NULL },
++#endif
+     /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN */
+     { .word = 1 },
+     /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING */
+diff --git a/locale/Makefile b/locale/Makefile
+index f1b4343..599a1a9 100644
+--- a/locale/Makefile
++++ b/locale/Makefile
+@@ -18,27 +18,43 @@
+ #
+ #	Makefile for locales.
+ #
++include ../option-groups.mak
++
+ subdir	:= locale
+ 
+ include ../Makeconfig
+ 
+ headers		= locale.h bits/locale.h langinfo.h xlocale.h
+-routines	= setlocale findlocale loadlocale loadarchive \
+-		  localeconv nl_langinfo nl_langinfo_l mb_cur_max \
+-		  newlocale duplocale freelocale uselocale
+-tests		= tst-C-locale tst-locname tst-duplocale
++# catnames is needed by OPTION_EGLIBC_LOCALE_CODE and by the 'intl' code.
++# If we put the latter in an option group, too, we can omit catnames
++# when both option groups are disabled.  libstdc++-v3 needs mb_cur_max.
++routines-y      := catnames mb_cur_max
++routines-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= setlocale findlocale loadlocale loadarchive \
++		   localeconv nl_langinfo nl_langinfo_l \
++		   newlocale duplocale freelocale uselocale
++ifneq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++routines-y	+= dummy-setlocale
++endif
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-C-locale tst-locname tst-duplocale
+ categories	= ctype messages monetary numeric time paper name \
+ 		  address telephone measurement identification collate
+-aux		= $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \
+-		  xlocale localename global-locale coll-lookup
+-others		= localedef locale
++# C-messages belongs in an intl option group.
++aux-y		:= C-ctype C-time \
++		   SYS_libc C_name xlocale global-locale coll-lookup
++aux-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= $(filter-out $(aux-y), \
++	                        $(categories:%=lc-%) $(categories:%=C-%)) \
++	           localename
++others-$(OPTION_EGLIBC_LOCALE_CODE) = localedef locale
+ #others-static	= localedef locale
+-install-bin	= localedef locale
+-extra-objs	= $(localedef-modules:=.o) $(localedef-aux:=.o) \
++install-bin	= $(others-y)
++extra-objs-$(OPTION_EGLIBC_LOCALE_CODE) \
++		= $(localedef-modules:=.o) $(localedef-aux:=.o) \
+ 		  $(locale-modules:=.o) $(lib-modules:=.o)
+ 
+-extra-libs	= libBrokenLocale
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_LOCALE_CODE) = libBrokenLocale
++extra-libs-others = $(extra-libs-y)
+ 
+ libBrokenLocale-routines = broken_cur_max
+ 
+@@ -93,6 +109,9 @@ CPPFLAGS-locale-programs = -DLOCALE_PATH='$(localepath)' \
+ CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts
+ CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts
+ CFLAGS-charmap-dir.c = -Wno-write-strings
++ifneq (y,$(OPTION_EGLIBC_SPAWN))
++CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
++endif
+ 
+ # Set libof-* for each routine.
+ cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \
+diff --git a/locale/catnames.c b/locale/catnames.c
+new file mode 100644
+index 0000000..9fad357
+--- /dev/null
++++ b/locale/catnames.c
+@@ -0,0 +1,48 @@
++/* Copyright (C) 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 "localeinfo.h"
++
++/* Define an array of category names (also the environment variable names).  */
++const union catnamestr_t _nl_category_names attribute_hidden =
++  {
++    {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++      category_name,
++#include "categories.def"
++#undef DEFINE_CATEGORY
++    }
++  };
++
++const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
++  {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
++#include "categories.def"
++#undef DEFINE_CATEGORY
++  };
++
++/* An array of their lengths, for convenience.  */
++const uint8_t _nl_category_name_sizes[] attribute_hidden =
++  {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++    [category] = sizeof (category_name) - 1,
++#include "categories.def"
++#undef	DEFINE_CATEGORY
++    [LC_ALL] = sizeof ("LC_ALL") - 1
++  };
+diff --git a/locale/dummy-setlocale.c b/locale/dummy-setlocale.c
+new file mode 100644
+index 0000000..219964a
+--- /dev/null
++++ b/locale/dummy-setlocale.c
+@@ -0,0 +1,33 @@
++/* Copyright (C) 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 <string.h>
++#include <locale.h>
++
++char *
++setlocale (int category, const char *locale)
++{
++  if (! locale
++      || locale[0] == '\0'
++      || strcmp (locale, "C") == 0
++      || strcmp (locale, "POSIX") == 0)
++    return (char *) "C";
++  else
++    return NULL;
++}
++libc_hidden_def (setlocale)
+diff --git a/locale/localeinfo.h b/locale/localeinfo.h
+index bdab9fe..a7516c0 100644
+--- a/locale/localeinfo.h
++++ b/locale/localeinfo.h
+@@ -232,7 +232,7 @@ __libc_tsd_define (extern, __locale_t, LOCALE)
+    unused.  We can manage this playing some tricks with weak references.
+    But with thread-local locale settings, it becomes quite ungainly unless
+    we can use __thread variables.  So only in that case do we attempt this.  */
+-#ifndef SHARED
++#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF
+ # include <tls.h>
+ # define NL_CURRENT_INDIRECT	1
+ #endif
+diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c
+index cf7adea..ef3b811 100644
+--- a/locale/programs/charmap-dir.c
++++ b/locale/programs/charmap-dir.c
+@@ -19,7 +19,9 @@
+ #include <error.h>
+ #include <fcntl.h>
+ #include <libintl.h>
++#ifndef NO_UNCOMPRESS
+ #include <spawn.h>
++#endif
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -156,6 +158,7 @@ charmap_closedir (CHARMAP_DIR *cdir)
+   return closedir (dir);
+ }
+ 
++#ifndef NO_UNCOMPRESS
+ /* Creates a subprocess decompressing the given pathname, and returns
+    a stream reading its output (the decompressed data).  */
+ static
+@@ -204,6 +207,7 @@ fopen_uncompressed (const char *pathname, const char *compressor)
+     }
+   return NULL;
+ }
++#endif
+ 
+ /* Opens a charmap for reading, given its name (not an alias name).  */
+ FILE *
+@@ -226,6 +230,7 @@ charmap_open (const char *directory, const char *name)
+   if (stream != NULL)
+     return stream;
+ 
++#ifndef NO_UNCOMPRESS
+   memcpy (p, ".gz", 4);
+   stream = fopen_uncompressed (pathname, "gzip");
+   if (stream != NULL)
+@@ -235,6 +240,7 @@ charmap_open (const char *directory, const char *name)
+   stream = fopen_uncompressed (pathname, "bzip2");
+   if (stream != NULL)
+     return stream;
++#endif
+ 
+   return NULL;
+ }
+diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
+index a39a94f..16e9039 100644
+--- a/locale/programs/ld-collate.c
++++ b/locale/programs/ld-collate.c
+@@ -351,7 +351,7 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
+     }
+   if (wcs != NULL)
+     {
+-      size_t nwcs = wcslen ((wchar_t *) wcs);
++      size_t nwcs = wcslen_uint32 (wcs);
+       uint32_t zero = 0;
+       /* Handle <U0000> as a single character.  */
+       if (nwcs == 0)
+@@ -1777,8 +1777,7 @@ symbol `%s' has the same encoding as"), (*eptr)->name);
+ 
+ 	      if ((*eptr)->nwcs == runp->nwcs)
+ 		{
+-		  int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
+-				   (wchar_t *) runp->wcs, runp->nwcs);
++		  int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs);
+ 
+ 		  if (c == 0)
+ 		    {
+@@ -2011,9 +2010,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
+ 	     one consecutive entry.  */
+ 	  if (runp->wcnext != NULL
+ 	      && runp->nwcs == runp->wcnext->nwcs
+-	      && wmemcmp ((wchar_t *) runp->wcs,
+-			  (wchar_t *)runp->wcnext->wcs,
+-			  runp->nwcs - 1) == 0
++	      && wmemcmp_uint32 (runp->wcs,
++				 runp->wcnext->wcs,
++				 runp->nwcs - 1) == 0
+ 	      && (runp->wcs[runp->nwcs - 1]
+ 		  == runp->wcnext->wcs[runp->nwcs - 1] + 1))
+ 	    {
+@@ -2037,9 +2036,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
+ 		runp = runp->wcnext;
+ 	      while (runp->wcnext != NULL
+ 		     && runp->nwcs == runp->wcnext->nwcs
+-		     && wmemcmp ((wchar_t *) runp->wcs,
+-				 (wchar_t *)runp->wcnext->wcs,
+-				 runp->nwcs - 1) == 0
++		     && wmemcmp_uint32 (runp->wcs,
++					runp->wcnext->wcs,
++					runp->nwcs - 1) == 0
+ 		     && (runp->wcs[runp->nwcs - 1]
+ 			 == runp->wcnext->wcs[runp->nwcs - 1] + 1));
+ 
+diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
+index 3f464ef..b7b6b51 100644
+--- a/locale/programs/ld-ctype.c
++++ b/locale/programs/ld-ctype.c
+@@ -926,7 +926,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
+   allocate_arrays (ctype, charmap, ctype->repertoire);
+ 
+   default_missing_len = (ctype->default_missing
+-			 ? wcslen ((wchar_t *) ctype->default_missing)
++			 ? wcslen_uint32 (ctype->default_missing)
+ 			 : 0);
+ 
+   init_locale_data (&file, nelems);
+@@ -1937,7 +1937,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
+ 	    ignore = 1;
+ 	  else
+ 	    /* This value is usable.  */
+-	    obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4);
++	    obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4);
+ 
+ 	  first = 0;
+ 	}
+@@ -2471,8 +2471,8 @@ with character code range values one must use the absolute ellipsis `...'"));
+ 	    }
+ 
+ 	handle_tok_digit:
+-	  class_bit = _ISwdigit;
+-	  class256_bit = _ISdigit;
++	  class_bit = BITw (tok_digit);
++	  class256_bit = BIT (tok_digit);
+ 	  handle_digits = 1;
+ 	  goto read_charclass;
+ 
+@@ -3929,8 +3929,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
+ 
+ 	  while (idx < number)
+ 	    {
+-	      int res = wcscmp ((const wchar_t *) sorted[idx]->from,
+-				(const wchar_t *) runp->from);
++	      int res = wcscmp_uint32 (sorted[idx]->from, runp->from);
+ 	      if (res == 0)
+ 		{
+ 		  replace = 1;
+@@ -3967,11 +3966,11 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
+       for (size_t cnt = 0; cnt < number; ++cnt)
+ 	{
+ 	  struct translit_to_t *srunp;
+-	  from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
++	  from_len += wcslen_uint32 (sorted[cnt]->from) + 1;
+ 	  srunp = sorted[cnt]->to;
+ 	  while (srunp != NULL)
+ 	    {
+-	      to_len += wcslen ((const wchar_t *) srunp->str) + 1;
++	      to_len += wcslen_uint32 (srunp->str) + 1;
+ 	      srunp = srunp->next;
+ 	    }
+ 	  /* Plus one for the extra NUL character marking the end of
+@@ -3995,18 +3994,18 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
+ 	  ctype->translit_from_idx[cnt] = from_len;
+ 	  ctype->translit_to_idx[cnt] = to_len;
+ 
+-	  len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
+-	  wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len],
+-		   (const wchar_t *) sorted[cnt]->from, len);
++	  len = wcslen_uint32 (sorted[cnt]->from) + 1;
++	  wmemcpy_uint32 (&ctype->translit_from_tbl[from_len],
++			  sorted[cnt]->from, len);
+ 	  from_len += len;
+ 
+ 	  ctype->translit_to_idx[cnt] = to_len;
+ 	  srunp = sorted[cnt]->to;
+ 	  while (srunp != NULL)
+ 	    {
+-	      len = wcslen ((const wchar_t *) srunp->str) + 1;
+-	      wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len],
+-		       (const wchar_t *) srunp->str, len);
++	      len = wcslen_uint32 (srunp->str) + 1;
++	      wmemcpy_uint32 (&ctype->translit_to_tbl[to_len],
++			      srunp->str, len);
+ 	      to_len += len;
+ 	      srunp = srunp->next;
+ 	    }
+diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c
+index ec1a80b..736eed8 100644
+--- a/locale/programs/ld-messages.c
++++ b/locale/programs/ld-messages.c
+@@ -25,6 +25,7 @@
+ #include <string.h>
+ #include <stdint.h>
+ #include <sys/uio.h>
++#include <gnu/option-groups.h>
+ 
+ #include <assert.h>
+ 
+@@ -124,6 +125,7 @@ No definition for %s category found"), "LC_MESSAGES"));
+     }
+   else
+     {
++#if __OPTION_POSIX_REGEXP
+       int result;
+       regex_t re;
+ 
+@@ -140,6 +142,7 @@ No definition for %s category found"), "LC_MESSAGES"));
+ 	}
+       else if (result != 0)
+ 	regfree (&re);
++#endif
+     }
+ 
+   if (messages->noexpr == NULL)
+@@ -158,6 +161,7 @@ No definition for %s category found"), "LC_MESSAGES"));
+     }
+   else
+     {
++#if __OPTION_POSIX_REGEXP
+       int result;
+       regex_t re;
+ 
+@@ -174,6 +178,7 @@ No definition for %s category found"), "LC_MESSAGES"));
+ 	}
+       else if (result != 0)
+ 	regfree (&re);
++#endif
+     }
+ }
+ 
+diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
+index db490c6..75dc505 100644
+--- a/locale/programs/ld-time.c
++++ b/locale/programs/ld-time.c
+@@ -215,8 +215,10 @@ No definition for %s category found"), "LC_TIME"));
+ 	}
+       else
+ 	{
++	  static const uint32_t wt_fmt_ampm[]
++	    = { '%','I',':','%','M',':','%','S',' ','%','p',0 };
+ 	  time->t_fmt_ampm = "%I:%M:%S %p";
+-	  time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
++	  time->wt_fmt_ampm = wt_fmt_ampm;
+ 	}
+     }
+ 
+@@ -226,7 +228,7 @@ No definition for %s category found"), "LC_TIME"));
+       const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
+ 				       31, 31, 30, 31 ,30, 31 };
+       size_t idx;
+-      wchar_t *wstr;
++      uint32_t *wstr;
+ 
+       time->era_entries =
+ 	(struct era_data *) xmalloc (time->num_era
+@@ -464,18 +466,18 @@ No definition for %s category found"), "LC_TIME"));
+ 	    }
+ 
+ 	  /* Now generate the wide character name and format.  */
+-	  wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end offset */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end start */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end end */
++	  wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */
+ 	  if (wstr != NULL)
+ 	    {
+-	      time->era_entries[idx].wname = (uint32_t *) wstr + 1;
+-	      wstr = wcschr (wstr + 1, L':');	/* end name */
++	      time->era_entries[idx].wname = wstr + 1;
++	      wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */
+ 	      if (wstr != NULL)
+ 		{
+ 		  *wstr = L'\0';
+-		  time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
++		  time->era_entries[idx].wformat = wstr + 1;
+ 		}
+ 	      else
+ 		time->era_entries[idx].wname =
+@@ -530,7 +532,16 @@ No definition for %s category found"), "LC_TIME"));
+   if (time->date_fmt == NULL)
+     time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
+   if (time->wdate_fmt == NULL)
+-    time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
++    {
++      static const uint32_t wdate_fmt[] =
++	{ '%','a',' ',
++	  '%','b',' ',
++	  '%','e',' ',
++	  '%','H',':','%','M',':','%','S',' ',
++	  '%','Z',' ',
++	  '%','Y',0 };
++      time->wdate_fmt = wdate_fmt;
++    }
+ }
+ 
+ 
+diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c
+index 2e05130..653b68c 100644
+--- a/locale/programs/linereader.c
++++ b/locale/programs/linereader.c
+@@ -595,7 +595,7 @@ get_string (struct linereader *lr, const struct charmap_t *charmap,
+ {
+   int return_widestr = lr->return_widestr;
+   char *buf;
+-  wchar_t *buf2 = NULL;
++  uint32_t *buf2 = NULL;
+   size_t bufact;
+   size_t bufmax = 56;
+ 
+diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
+index 2a0f2aa..583d233 100644
+--- a/locale/programs/localedef.c
++++ b/locale/programs/localedef.c
+@@ -114,6 +114,7 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+ #define OPT_LIST_ARCHIVE 309
+ #define OPT_LITTLE_ENDIAN 400
+ #define OPT_BIG_ENDIAN 401
++#define OPT_UINT32_ALIGN 402
+ 
+ /* Definitions of arguments for argp functions.  */
+ static const struct argp_option options[] =
+@@ -150,6 +151,8 @@ static const struct argp_option options[] =
+     N_("Generate little-endian output") },
+   { "big-endian", OPT_BIG_ENDIAN, NULL, 0,
+     N_("Generate big-endian output") },
++  { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0,
++    N_("Set the target's uint32_t alignment in bytes (default 4)") },
+   { NULL, 0, NULL, 0, NULL }
+ };
+ 
+@@ -239,12 +242,14 @@ main (int argc, char *argv[])
+      ctype locale.  (P1003.2 4.35.5.2)  */
+   setlocale (LC_CTYPE, "POSIX");
+ 
++#ifndef NO_SYSCONF
+   /* Look whether the system really allows locale definitions.  POSIX
+      defines error code 3 for this situation so I think it must be
+      a fatal error (see P1003.2 4.35.8).  */
+   if (sysconf (_SC_2_LOCALEDEF) < 0)
+     WITH_CUR_LOCALE (error (3, 0, _("\
+ FATAL: system does not define `_POSIX2_LOCALEDEF'")));
++#endif
+ 
+   /* Process charmap file.  */
+   charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1);
+@@ -338,6 +343,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
+     case OPT_BIG_ENDIAN:
+       set_big_endian (true);
+       break;
++    case OPT_UINT32_ALIGN:
++      uint32_align_mask = strtol (arg, NULL, 0) - 1;
++      break;
+     case 'c':
+       force_output = 1;
+       break;
+diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
+index 33da52e..f790c4c 100644
+--- a/locale/programs/locfile.c
++++ b/locale/programs/locfile.c
+@@ -544,6 +544,9 @@ compare_files (const char *filename1, const char *filename2, size_t size,
+    machine running localedef.  */
+ bool swap_endianness_p;
+ 
++/* The target's value of __align__(uint32_t) - 1.  */
++unsigned int uint32_align_mask = 3;
++
+ /* When called outside a start_locale_structure/end_locale_structure
+    or start_locale_prelude/end_locale_prelude block, record that the
+    next byte in FILE's obstack will be the first byte of a new element.
+@@ -621,7 +624,7 @@ add_locale_string (struct locale_file *file, const char *string)
+ void
+ add_locale_wstring (struct locale_file *file, const uint32_t *string)
+ {
+-  add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
++  add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1);
+ }
+ 
+ /* Record that FILE's next element is the 32-bit integer VALUE.  */
+diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h
+index 6fc441b..118b171 100644
+--- a/locale/programs/locfile.h
++++ b/locale/programs/locfile.h
+@@ -71,6 +71,8 @@ extern void write_all_categories (struct localedef_t *definitions,
+ 
+ extern bool swap_endianness_p;
+ 
++extern unsigned int uint32_align_mask;
++
+ /* Change the output to be big-endian if BIG_ENDIAN is true and
+    little-endian otherwise.  */
+ static inline void
+@@ -89,7 +91,8 @@ maybe_swap_uint32 (uint32_t value)
+ }
+ 
+ /* Likewise, but munge an array of N uint32_ts starting at ARRAY.  */
+-static inline void
++static void
++__attribute__ ((unused))
+ maybe_swap_uint32_array (uint32_t *array, size_t n)
+ {
+   if (swap_endianness_p)
+@@ -99,7 +102,8 @@ maybe_swap_uint32_array (uint32_t *array, size_t n)
+ 
+ /* Like maybe_swap_uint32_array, but the array of N elements is at
+    the end of OBSTACK's current object.  */
+-static inline void
++static void
++__attribute__ ((unused))
+ maybe_swap_uint32_obstack (struct obstack *obstack, size_t n)
+ {
+   maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n);
+@@ -276,4 +280,55 @@ extern void identification_output (struct localedef_t *locale,
+ 				   const struct charmap_t *charmap,
+ 				   const char *output_path);
+ 
++static size_t wcslen_uint32 (const uint32_t *str) __attribute__ ((unused));
++static uint32_t * wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
++static uint32_t * wcschr_uint32 (const uint32_t *s, uint32_t ch) __attribute__ ((unused));
++static int wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2) __attribute__ ((unused));
++static int wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
++
++static size_t
++wcslen_uint32 (const uint32_t *str)
++{
++  size_t len = 0;
++  while (str[len] != 0)
++    len++;
++  return len;
++}
++
++static  int
++wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n)
++{
++  while (n-- != 0)
++    {
++      int diff = *s1++ - *s2++;
++      if (diff != 0)
++	return diff;
++    }
++  return 0;
++}
++
++static int
++wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2)
++{
++  while (*s1 != 0 && *s1 == *s2)
++    s1++, s2++;
++  return *s1 - *s2;
++}
++
++static uint32_t *
++wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n)
++{
++  return memcpy (s1, s2, n * sizeof (uint32_t));
++}
++
++static uint32_t *
++wcschr_uint32 (const uint32_t *s, uint32_t ch)
++{
++  do
++    if (*s == ch)
++      return (uint32_t *) s;
++  while (*s++ != 0);
++  return 0;
++}
++
+ #endif /* locfile.h */
+diff --git a/locale/setlocale.c b/locale/setlocale.c
+index fa9cb3a..8eee284 100644
+--- a/locale/setlocale.c
++++ b/locale/setlocale.c
+@@ -64,36 +64,6 @@ static char *const _nl_current_used[] =
+ #endif
+ 
+ 
+-/* Define an array of category names (also the environment variable names).  */
+-const union catnamestr_t _nl_category_names attribute_hidden =
+-  {
+-    {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-      category_name,
+-#include "categories.def"
+-#undef DEFINE_CATEGORY
+-    }
+-  };
+-
+-const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
+-  {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
+-#include "categories.def"
+-#undef DEFINE_CATEGORY
+-  };
+-
+-/* An array of their lengths, for convenience.  */
+-const uint8_t _nl_category_name_sizes[] attribute_hidden =
+-  {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-    [category] = sizeof (category_name) - 1,
+-#include "categories.def"
+-#undef	DEFINE_CATEGORY
+-    [LC_ALL] = sizeof ("LC_ALL") - 1
+-  };
+-
+-
+ #ifdef NL_CURRENT_INDIRECT
+ # define WEAK_POSTLOAD(postload) weak_extern (postload)
+ #else
+diff --git a/locale/xlocale.c b/locale/xlocale.c
+index fec4564..f00269c 100644
+--- a/locale/xlocale.c
++++ b/locale/xlocale.c
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <locale.h>
++#include <gnu/option-groups.h>
+ #include "localeinfo.h"
+ 
+ #define DEFINE_CATEGORY(category, category_name, items, a) \
+@@ -25,6 +26,19 @@ extern struct __locale_data _nl_C_##category;
+ #include "categories.def"
+ #undef	DEFINE_CATEGORY
+ 
++/* If the locale support code isn't enabled, don't generate strong
++   reference to the C locale_data structures here; let the Makefile
++   decide which ones to include.  (In the static linking case, the
++   strong reference to the 'class', 'toupper', and 'tolower' tables
++   will cause C-ctype.o to be brought in, as it should be, even when
++   the reference to _nl_C_LC_CTYPE will be weak.)  */
++#if ! __OPTION_EGLIBC_LOCALE_CODE
++# define DEFINE_CATEGORY(category, category_name, items, a) \
++  weak_extern (_nl_C_##category)
++# include "categories.def"
++# undef	DEFINE_CATEGORY
++#endif
++
+ /* Defined in locale/C-ctype.c.  */
+ extern const char _nl_C_LC_CTYPE_class[] attribute_hidden;
+ extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden;
+@@ -52,3 +66,26 @@ const struct __locale_struct _nl_C_locobj attribute_hidden =
+     .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
+     .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
+   };
++
++
++#if ! __OPTION_EGLIBC_LOCALE_CODE
++/* When locale code is enabled, these are each defined in the
++   appropriate lc-CATEGORY.c file, so that static links (when __thread
++   is supported) bring in only those lc-CATEGORY.o files for
++   categories the program actually uses; look for NL_CURRENT_INDIRECT
++   in localeinfo.h.
++
++   When locale code is disabled, the _nl_C_CATEGORY objects are the
++   only possible referents.  At the moment, there isn't a way to get
++   __OPTION_EGLIBC_LOCALE_CODE defined in every compilation unit that
++   #includes localeinfo.h, so we can't just turn off
++   NL_CURRENT_INDIRECT.  So we'll define the _nl_current_CATEGORY
++   pointers here.  */
++#if defined (NL_CURRENT_INDIRECT)
++#define DEFINE_CATEGORY(category, category_name, items, a)      \
++  __thread struct __locale_data * const *_nl_current_##category   \
++  attribute_hidden = &_nl_C_locobj.__locales[category];
++#include "categories.def"
++#undef DEFINE_CATEGORY
++#endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+diff --git a/localedata/Makefile b/localedata/Makefile
+index ebf6ac9..1870753 100644
+--- a/localedata/Makefile
++++ b/localedata/Makefile
+@@ -21,12 +21,22 @@ subdir := localedata
+ 
+ include ../Makeconfig
+ 
+-# List with all available character set descriptions.
+-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
++include ../option-groups.mak
+ 
+ # List with all available character set descriptions.
+-locales := $(wildcard locales/*)
+-
++all-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
++
++all-locales := $(wildcard locales/*)
++
++# If the EGLIBC_LOCALES option group is not enabled, trim the
++# list of charmap and locale source files.
++ifeq ($(OPTION_EGLIBC_LOCALES),y)
++charmaps := $(all-charmaps)
++locales  := $(all-locales)
++else
++charmaps :=
++locales  := locales/POSIX
++endif
+ 
+ subdir-dirs = tests-mbwc
+ vpath %.c tests-mbwc
+@@ -71,14 +81,20 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl            \
+ 		     tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans      \
+ 		     tst_wctype tst_wcwidth
+ 
+-tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
++# Since these tests build their own locale files, they're not
++# dependent on the OPTION_EGLIBC_LOCALES option group.  But they do
++# need the locale functions to be present.
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++     += $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
+ 	tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \
+ 	tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
+ 	tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \
+ 	tst-wctype
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ tests-static = bug-setlocale1-static
+ tests += $(tests-static)
+-ifeq (yes,$(build-shared))
++endif
++ifeq (yesy,$(build-shared)$(OPTION_EGLIBC_LOCALE_CODE))
+ ifneq (no,$(PERL))
+ tests-special += $(objpfx)mtrace-tst-leaks.out
+ endif
+@@ -95,6 +111,7 @@ tests: $(objdir)/iconvdata/gconv-modules
+ tests-static += tst-langinfo-static
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ tests-special += $(objpfx)sort-test.out $(objpfx)tst-fmon.out \
+ 		 $(objpfx)tst-locale.out $(objpfx)tst-rpmatch.out \
+ 		 $(objpfx)tst-trans.out $(objpfx)tst-ctype.out \
+@@ -109,6 +126,7 @@ LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ANSI_X3.4-1968 \
+ 	   tr_TR.ISO-8859-9 en_GB.UTF-8 uk_UA.UTF-8
+ include ../gen-locales.mk
+ endif
++endif
+ 
+ include ../Rules
+ 
+@@ -191,6 +209,11 @@ endif
+ 
+ include SUPPORTED
+ 
++# Only install locale data if OPTION_EGLIBC_LOCALES is selected.
++ifneq ($(OPTION_EGLIBC_LOCALES),y)
++SUPPORTED-LOCALES :=
++endif
++
+ INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES))
+ 
+ # Sometimes the whole collection of locale files should be installed.
+diff --git a/login/Makefile b/login/Makefile
+index 0f4bb22..4036ddb 100644
+--- a/login/Makefile
++++ b/login/Makefile
+@@ -18,6 +18,7 @@
+ #
+ #	Sub-makefile for login portion of the library.
+ #
++include ../option-groups.mak
+ 
+ subdir	:= login
+ 
+@@ -25,14 +26,16 @@ include ../Makeconfig
+ 
+ headers	:= utmp.h bits/utmp.h lastlog.h pty.h
+ 
+-routines := getlogin getlogin_r setlogin getlogin_r_chk \
+-	    getutent getutent_r getutid getutline getutid_r getutline_r \
+-	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
+-	    ptsname_r_chk
++routines := getpt grantpt unlockpt ptsname ptsname_r_chk
++routines-$(OPTION_EGLIBC_UTMP) \
++	 += getutent getutent_r getutid getutline getutid_r getutline_r \
++	    utmp_file utmpname updwtmp
++routines-$(OPTION_EGLIBC_GETLOGIN) += getlogin getlogin_r getlogin_r_chk
++routines-$(OPTION_EGLIBC_BSD) += setlogin
+ 
+ CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"'
+ 
+-others = utmpdump
++others-$(OPTION_EGLIBC_UTMP) += utmpdump
+ 
+ ifeq (yes,$(build-pt-chown))
+ others += pt_chown
+@@ -46,8 +49,8 @@ vpath %.c programs
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin
+ 
+ # Build the -lutil library with these extra functions.
+-extra-libs      := libutil
+-extra-libs-others := $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_UTMP) := libutil
++extra-libs-others := $(extra-libs-y)
+ 
+ libutil-routines:= login login_tty logout logwtmp openpty forkpty
+ 
+diff --git a/malloc/Makefile b/malloc/Makefile
+index 67ed293..272ca4d 100644
+--- a/malloc/Makefile
++++ b/malloc/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for malloc routines
+ #
++include ../option-groups.mak
++
+ subdir	:= malloc
+ 
+ include ../Makeconfig
+@@ -39,9 +41,15 @@ install-lib := libmcheck.a
+ non-lib.a := libmcheck.a
+ 
+ # Additional library.
++ifeq ($(OPTION_EGLIBC_MEMUSAGE),y)
+ extra-libs = libmemusage
+ extra-libs-others = $(extra-libs)
+ 
++ifdef OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++CPPFLAGS-memusage += -D__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE=$(OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE)
++endif
++endif
++
+ libmemusage-routines = memusage
+ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
+ 
+@@ -71,7 +79,7 @@ endif
+ # Unless we get a test for the availability of libgd which also works
+ # for cross-compiling we disable the memusagestat generation in this
+ # situation.
+-ifneq ($(cross-compiling),yes)
++ifeq ($(cross-compiling)$(OPTION_EGLIBC_MEMUSAGE),noy)
+ # If the gd library is available we build the `memusagestat' program.
+ ifneq ($(LIBGD),no)
+ others: $(objpfx)memusage
+diff --git a/malloc/memusage.c b/malloc/memusage.c
+index a57ba8e..732ba9d 100644
+--- a/malloc/memusage.c
++++ b/malloc/memusage.c
+@@ -33,6 +33,7 @@
+ #include <stdint.h>
+ #include <sys/mman.h>
+ #include <sys/time.h>
++#include <gnu/option-groups.h>
+ 
+ #include <memusage.h>
+ 
+@@ -93,7 +94,11 @@ static __thread uintptr_t start_sp;
+ #define peak_stack      peak_use[1]
+ #define peak_total      peak_use[2]
+ 
+-#define DEFAULT_BUFFER_SIZE     32768
++#ifndef __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++# define DEFAULT_BUFFER_SIZE	32768
++#else
++# define DEFAULT_BUFFER_SIZE	__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++#endif
+ static size_t buffer_size;
+ 
+ static int fd = -1;
+diff --git a/malloc/memusage.sh b/malloc/memusage.sh
+index 8ab8cc2..d18f446 100755
+--- a/malloc/memusage.sh
++++ b/malloc/memusage.sh
+@@ -35,7 +35,7 @@ do_missing_arg() {
+ 
+ # Print help message
+ do_help() {
+-  echo $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
++  printf $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
+ Profile memory usage of PROGRAM.
+ 
+    -n,--progname=NAME     Name of the program file to profile
+diff --git a/math/Makefile b/math/Makefile
+index 6388bae..ed1c511 100644
+--- a/math/Makefile
++++ b/math/Makefile
+@@ -21,6 +21,8 @@ subdir		:= math
+ 
+ include ../Makeconfig
+ 
++include ../option-groups.mak
++
+ # Installed header files.
+ headers		:= math.h bits/mathcalls.h bits/mathinline.h bits/huge_val.h \
+ 		   bits/huge_valf.h bits/huge_vall.h bits/inf.h bits/nan.h \
+@@ -34,8 +36,8 @@ aux		:= setfpucw fpu_control
+ 
+ # Build the -lm library.
+ 
+-extra-libs	:= libm
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_LIBM) := libm
++extra-libs-others-$(OPTION_EGLIBC_LIBM) = $(extra-libs-$(OPTION_EGLIBC_LIBM))
+ 
+ libm-support = s_lib_version s_matherr s_signgam			\
+ 	       fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg		\
+diff --git a/misc/Makefile b/misc/Makefile
+index aecb0da..e6b7c23 100644
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -19,6 +19,10 @@
+ #	Sub-makefile for misc portion of the library.
+ #
+ 
++# Some system-dependent implementations of these functions use option
++# groups (see sysdeps/unix/sysv/linux/Makefile, for example).
++include ../option-groups.mak
++
+ subdir	:= misc
+ 
+ include ../Makeconfig
+@@ -46,40 +50,47 @@ routines := brk sbrk sstk ioctl \
+ 	    select pselect \
+ 	    acct chroot fsync sync fdatasync syncfs reboot \
+ 	    gethostid sethostid \
+-	    revoke vhangup \
++	    vhangup \
+ 	    swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
+ 	    mkostemp mkostemp64 mkstemps mkstemps64 mkostemps mkostemps64 \
+ 	    ualarm usleep \
+ 	    gtty stty \
+ 	    ptrace \
+-	    fstab mntent mntent_r \
++	    mntent mntent_r \
+ 	    utimes lutimes futimes futimesat \
+ 	    truncate ftruncate truncate64 ftruncate64 \
+-	    chflags fchflags \
+ 	    insremque getttyent getusershell getpass ttyslot \
+ 	    syslog syscall daemon \
+ 	    mmap mmap64 munmap mprotect msync madvise mincore remap_file_pages\
+ 	    mlock munlock mlockall munlockall \
+-	    efgcvt efgcvt_r qefgcvt qefgcvt_r \
+ 	    hsearch hsearch_r tsearch lsearch \
+ 	    err error ustat \
+-	    getsysstats dirname regexp \
++	    getsysstats dirname \
+ 	    getloadavg getclktck \
+ 	    fgetxattr flistxattr fremovexattr fsetxattr getxattr \
+ 	    listxattr lgetxattr llistxattr lremovexattr lsetxattr \
+ 	    removexattr setxattr getauxval ifunc-impl-list
+ 
++routines-$(OPTION_POSIX_REGEXP) += regexp
++routines-$(OPTION_EGLIBC_FSTAB) += fstab
++routines-$(OPTION_EGLIBC_BSD) += chflags fchflags revoke
++routines-$(OPTION_EGLIBC_FCVT) += efgcvt efgcvt_r qefgcvt qefgcvt_r
++
+ generated += tst-error1.mtrace tst-error1-mem.out
+ 
+ aux := init-misc
+ install-lib := libg.a
+ gpl2lgpl := error.c error.h
+ 
+-tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
+-	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
++tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
++	 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += tst-error1
++tests-$(OPTION_EGLIBC_FCVT) += tst-efgcvt
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
+ tests-special += $(objpfx)tst-error1-mem.out
+ endif
++endif
+ 
+ CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables
+ CFLAGS-tsearch.c = $(uses-callbacks)
+diff --git a/misc/err.c b/misc/err.c
+index 7b98157..efce8d5 100644
+--- a/misc/err.c
++++ b/misc/err.c
+@@ -22,6 +22,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <stdio.h>
++#include <gnu/option-groups.h>
+ 
+ #include <wchar.h>
+ #define flockfile(s) _IO_flockfile (s)
+@@ -37,6 +38,7 @@ extern char *__progname;
+   va_end (ap);								      \
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ static void
+ convert_and_print (const char *format, __gnuc_va_list ap)
+ {
+@@ -81,6 +83,7 @@ convert_and_print (const char *format, __gnuc_va_list ap)
+ 
+   __vfwprintf (stderr, wformat, ap);
+ }
++#endif
+ 
+ void
+ vwarnx (const char *format, __gnuc_va_list ap)
+@@ -88,9 +91,13 @@ vwarnx (const char *format, __gnuc_va_list ap)
+   flockfile (stderr);
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       __fwprintf (stderr, L"%s: ", __progname);
+       convert_and_print (format, ap);
+       putwc_unlocked (L'\n', stderr);
++#else
++      abort ();
++#endif
+     }
+   else
+     {
+@@ -111,6 +118,7 @@ vwarn (const char *format, __gnuc_va_list ap)
+   flockfile (stderr);
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       __fwprintf (stderr, L"%s: ", __progname);
+       if (format)
+ 	{
+@@ -119,6 +127,9 @@ vwarn (const char *format, __gnuc_va_list ap)
+ 	}
+       __set_errno (error);
+       __fwprintf (stderr, L"%m\n");
++#else
++      abort ();
++#endif
+     }
+   else
+     {
+diff --git a/misc/error.c b/misc/error.c
+index aaa120d..d6cbc82 100644
+--- a/misc/error.c
++++ b/misc/error.c
+@@ -35,6 +35,7 @@
+ #endif
+ 
+ #ifdef _LIBC
++# include <gnu/option-groups.h>
+ # include <libintl.h>
+ # include <stdbool.h>
+ # include <stdint.h>
+@@ -205,6 +206,7 @@ error_tail (int status, int errnum, const char *message, va_list args)
+ #if _LIBC
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       size_t len = strlen (message) + 1;
+       wchar_t *wmessage = NULL;
+       mbstate_t st;
+@@ -265,6 +267,9 @@ error_tail (int status, int errnum, const char *message, va_list args)
+ 
+       if (use_malloc)
+ 	free (wmessage);
++#else
++      abort ();
++#endif
+     }
+   else
+ #endif
+diff --git a/misc/tst-efgcvt.c b/misc/tst-efgcvt.c
+index 5083fec..79ed36c 100644
+--- a/misc/tst-efgcvt.c
++++ b/misc/tst-efgcvt.c
+@@ -59,7 +59,7 @@ static testcase ecvt_tests[] =
+   { 123.01, -4, 3, "" },
+   { 126.71, -4, 3, "" },
+   { 0.0, 4, 1, "0000" },
+-#if DBL_MANT_DIG == 53
++#if DBL_MANT_DIG == 53 && !(defined __powerpc__ && defined __NO_FPRS__ && !defined _SOFT_FLOAT && !defined _SOFT_DOUBLE)
+   { 0x1p-1074, 3, -323, "494" },
+   { -0x1p-1074, 3, -323, "494" },
+ #endif
+diff --git a/nis/Makefile b/nis/Makefile
+index 037e674..c967850 100644
+--- a/nis/Makefile
++++ b/nis/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for NIS/NIS+ part.
+ #
++include ../option-groups.mak
++
+ subdir	:= nis
+ 
+ include ../Makeconfig
+@@ -30,19 +32,26 @@ endif
+ 
+ # These are the databases available for the nis (and perhaps later nisplus)
+ # service.  This must be a superset of the services in nss.
+-databases		= proto service hosts network grp pwd rpc ethers \
+-			  spwd netgrp alias publickey
++databases-y		:= proto service hosts network grp pwd rpc ethers \
++			   spwd netgrp publickey
++databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
+ 
+ # Specify rules for the nss_* modules.
+-services		:= nis nisplus compat
++# The 'compat' module includes nis support, and the 'nss' directory
++# includes a bare-bones "files" library, so we'll include 'compat' in
++# OPTION_EGLIBC_NIS.
++services-y		:=
++services-$(OPTION_EGLIBC_NIS) += nis nisplus compat
++
++extra-libs-$(OPTION_EGLIBC_NIS) += libnsl
++extra-libs-y		+= $(services-y:%=libnss_%)
+ 
+-extra-libs		= libnsl $(services:%=libnss_%)
+ # These libraries will be built in the `others' pass rather than
+ # the `lib' pass, because they depend on libc.so being built already.
+-extra-libs-others	= $(extra-libs)
++extra-libs-others-y	+= $(extra-libs-y)
+ 
+ # The sources are found in the appropriate subdir.
+-subdir-dirs = $(services:%=nss_%)
++subdir-dirs = $(services-y:%=nss_%)
+ vpath %.c $(subdir-dirs)
+ 
+ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
+@@ -60,11 +69,11 @@ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
+ libnss_compat-routines	:= $(addprefix compat-,grp pwd spwd initgroups)
+ libnss_compat-inhibit-o	= $(filter-out .os,$(object-suffixes))
+ 
+-libnss_nis-routines	:= $(addprefix nis-,$(databases)) nis-initgroups \
++libnss_nis-routines	:= $(addprefix nis-,$(databases-y)) nis-initgroups \
+ 			   nss-nis
+ libnss_nis-inhibit-o	= $(filter-out .os,$(object-suffixes))
+ 
+-libnss_nisplus-routines	:= $(addprefix nisplus-,$(databases)) nisplus-parser \
++libnss_nisplus-routines	:= $(addprefix nisplus-,$(databases-y)) nisplus-parser \
+ 			   nss-nisplus nisplus-initgroups
+ libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes))
+ 
+@@ -80,12 +89,12 @@ libnsl-libc = $(common-objpfx)linkobj/libc.so
+ # Target-specific variable setting to link objects using deprecated
+ # RPC interfaces with the version of libc.so that makes them available
+ # for new links:
+-$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
++$(services-y:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
+   libc-for-link = $(libnsl-libc)
+ 
+ 
+ ifeq ($(build-shared),yes)
+-$(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
++$(others-y:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
+ else
+-$(others:%=$(objpfx)%): $(objpfx)libnsl.a
++$(others-y:%=$(objpfx)%): $(objpfx)libnsl.a
+ endif
+diff --git a/nptl/Makefile b/nptl/Makefile
+index aaca0a4..596ca3c 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for NPTL portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= nptl
+ 
+ include ../Makeconfig
+@@ -118,7 +120,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
+ 		      pt-raise pt-system \
+ 		      flockfile ftrylockfile funlockfile \
+ 		      sigaction \
+-		      herrno res pt-allocrtsig \
++		      pt-allocrtsig \
+ 		      pthread_kill_other_threads \
+ 		      pthread_getaffinity pthread_setaffinity \
+ 		      pthread_attr_getaffinity pthread_attr_setaffinity \
+@@ -138,8 +140,10 @@ libpthread-routines = nptl-init vars events version pt-interp \
+ #		      pthread_setgid pthread_setegid pthread_setregid \
+ #		      pthread_setresgid
+ 
++libpthread-routines-$(OPTION_EGLIBC_INET) := herrno res
+ libpthread-shared-only-routines = version pt-interp pt-allocrtsig \
+ 				  unwind-forcedunwind
++
+ libpthread-static-only-routines = pthread_atfork
+ 
+ # Since cancellation handling is in large parts handled using exceptions
+@@ -220,7 +224,7 @@ tests = tst-typesizes \
+ 	tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
+ 	tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
+ 	tst-mutexpi9 \
+-	tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
++	tst-spin1 tst-spin2 tst-spin3 \
+ 	tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
+ 	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
+ 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
+@@ -256,14 +260,14 @@ tests = tst-typesizes \
+ 	tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
+ 	tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
+ 	tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
+-	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
++	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel25 \
+ 	tst-cancel-self tst-cancel-self-cancelstate \
+ 	tst-cancel-self-canceltype tst-cancel-self-testcancel \
+ 	tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
+ 	tst-flock1 tst-flock2 \
+ 	tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
+ 	tst-signal6 tst-signal7 \
+-	tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
++	tst-exec2 tst-exec3 tst-exec4 \
+ 	tst-exit1 tst-exit2 tst-exit3 \
+ 	tst-stdio1 tst-stdio2 \
+ 	tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \
+@@ -271,13 +275,12 @@ tests = tst-typesizes \
+ 	tst-unload \
+ 	tst-dlsym1 \
+ 	tst-sysconf \
+-	tst-locale1 tst-locale2 \
++	tst-locale2 \
+ 	tst-umask1 \
+ 	tst-popen1 \
+ 	tst-clock1 \
+ 	tst-context1 \
+ 	tst-sched1 \
+-	tst-backtrace1 \
+ 	tst-abstime \
+ 	tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
+ 	tst-getpid3 \
+@@ -288,9 +291,16 @@ xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
+ 	tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
+ test-srcs = tst-oddstacklimit
+ 
+-# Test expected to fail on most targets (except x86_64) due to bug
+-# 18435 - pthread_once hangs when init routine throws an exception.
+-test-xfail-tst-once5 = yes
++# This test uses the posix_spawn functions.
++tests-$(OPTION_EGLIBC_SPAWN) += tst-exec1
++
++# This test uses the 'backtrace' functions.
++tests-$(OPTION_EGLIBC_BACKTRACE) += tst-backtrace1
++
++# This test is written in C++.
++tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24
++
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-locale1
+ 
+ # Files which must not be linked with libpthread.
+ tests-nolibpthread = tst-unload
+diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
+index d10f4ea..14257ce 100644
+--- a/nptl/pthread_create.c
++++ b/nptl/pthread_create.c
+@@ -33,6 +33,7 @@
+ #include <default-sched.h>
+ #include <futex-internal.h>
+ 
++#include <gnu/option-groups.h>
+ #include <shlib-compat.h>
+ 
+ #include <stap-probe.h>
+@@ -262,8 +263,10 @@ START_THREAD_DEFN
+   THREAD_SETMEM (pd, cpuclock_offset, now);
+ #endif
+ 
++#if __OPTION_EGLIBC_INET
+   /* Initialize resolver state pointer.  */
+   __resp = &pd->res;
++#endif
+ 
+   /* Initialize pointers to locale data.  */
+   __ctype_init ();
+@@ -346,8 +349,10 @@ START_THREAD_DEFN
+   /* Run the destructor for the thread-local data.  */
+   __nptl_deallocate_tsd ();
+ 
++#if __OPTION_EGLIBC_INET
+   /* Clean up any state libc stored in thread-local variables.  */
+   __libc_thread_freeres ();
++#endif
+ 
+   /* If this is the last thread we terminate the process now.  We
+      do not notify the debugger, it might just irritate it if there
+diff --git a/nscd/Makefile b/nscd/Makefile
+index ede941d..f4f3f8d 100644
+--- a/nscd/Makefile
++++ b/nscd/Makefile
+@@ -18,14 +18,17 @@
+ #
+ #	Sub-makefile for nscd portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= nscd
+ 
+ include ../Makeconfig
+ 
+ ifneq ($(use-nscd),no)
+-routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
++routines-$(OPTION_EGLIBC_INET) += \
++	     nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
+ 	    nscd_initgroups nscd_getserv_r nscd_netgroup
+-aux	:= nscd_helper
++aux-$(OPTION_EGLIBC_INET) += nscd_helper
+ endif
+ 
+ # To find xmalloc.c
+@@ -37,14 +40,18 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
+ 		dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
+ 		xmalloc xstrdup aicache initgrcache gai res_hconf \
+ 		netgroupcache
+-
++ifneq (y,$(OPTION_EGLIBC_NIS))
++# If we haven't build libnsl.so, then we'll need to include our
++# own copy of nis_hash.
++nscd-modules += nis_hash
++endif
+ ifeq ($(build-nscd)$(have-thread-library),yesyes)
+ 
+-others += nscd
+-others-pie += nscd
+-install-sbin := nscd
++others-$(OPTION_EGLIBC_INET) += nscd
++others-pie-$(OPTION_EGLIBC_INET) += nscd
++install-sbin-$(OPTION_EGLIBC_INET) += nscd
+ 
+-extra-objs = $(nscd-modules:=.o)
++extra-objs-$(OPTION_EGLIBC_INET) += $(nscd-modules:=.o)
+ 
+ endif
+ 
+@@ -100,7 +107,15 @@ include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
+ $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o)
+ 
+ ifeq ($(build-shared),yes)
+-$(objpfx)nscd: $(shared-thread-library) $(common-objpfx)nis/libnsl.so
++$(objpfx)nscd: $(shared-thread-library)
++else
++$(objpfx)nscd: $(static-thread-library)
++endif
++
++ifeq (y,$(OPTION_EGLIBC_NIS))
++ifeq ($(build-shared),yes)
++$(objpfx)nscd: $(common-objpfx)nis/libnsl.so
+ else
+-$(objpfx)nscd: $(static-thread-library) $(common-objpfx)nis/libnsl.a
++$(objpfx)nscd: $(common-objpfx)nis/libnsl.a
++endif
+ endif
+diff --git a/nscd/nis_hash.c b/nscd/nis_hash.c
+new file mode 100644
+index 0000000..d244c41
+--- /dev/null
++++ b/nscd/nis_hash.c
+@@ -0,0 +1,3 @@
++/* If OPTION_EGLIBC_NIS is disabled, nscd can't get this from libnsl.so;
++   we need our own copy.  */
++#include "../nis/nis_hash.c"
+diff --git a/nss/Makefile b/nss/Makefile
+index 65ab7b5..19f0aef 100644
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -18,28 +18,35 @@
+ #
+ #	Makefile for name service switch.
+ #
++include ../option-groups.mak
++
+ subdir	:= nss
+ 
+ include ../Makeconfig
+ 
+ headers			:= nss.h
+ 
+-# This is the trivial part which goes into libc itself.
+-routines		= nsswitch getnssent getnssent_r digits_dots \
+-			  $(addsuffix -lookup,$(databases))
+-
+ # These are the databases that go through nss dispatch.
+ # Caution: if you add a database here, you must add its real name
+ # in databases.def, too.
+-databases		= proto service hosts network grp pwd ethers \
+-			  spwd netgrp alias sgrp
++databases-y		= grp pwd spwd sgrp
++databases-$(OPTION_EGLIBC_INET) \
++			+= proto service hosts network ethers \
++			   netgrp
++databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
++
++routines-$(OPTION_EGLIBC_INET) += digits_dots
+ 
+ ifneq (,$(filter sunrpc,$(subdirs)))
+-databases		+= key rpc
++databases-$(OPTION_EGLIBC_INET)	+= key rpc
+ have-sunrpc		:= 1
+ else
+ have-sunrpc		:= 0
+ endif
++# This is the trivial part which goes into libc itself.
++routines-y		+= nsswitch getnssent getnssent_r \
++			  $(addsuffix -lookup,$(databases-y))
++
+ CPPFLAGS-getent.c	= -DHAVE_SUNRPC=$(have-sunrpc)
+ 
+ others                  := getent makedb
+@@ -47,8 +54,9 @@ install-bin             := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs		+= $(makedb-modules:=.o)
+ 
+-tests			= test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
+-xtests			= bug-erange
++tests			= tst-nss-test1 tst-nss-getpwent
++tests-$(OPTION_EGLIBC_INET)	+= test-netdb test-digits-dots
++xtests-$(OPTION_EGLIBC_INET)	+= bug-erange
+ 
+ # Specify rules for the nss_* modules.  We have some services.
+ services		:= files db
+@@ -63,7 +71,7 @@ subdir-dirs = $(services:%=nss_%)
+ vpath %.c $(subdir-dirs) ../locale/programs ../intl
+ 
+ 
+-libnss_files-routines	:= $(addprefix files-,$(databases)) \
++libnss_files-routines	:= $(addprefix files-,$(databases-y)) \
+ 			   files-initgroups files-have_o_cloexec files-init
+ 
+ libnss_db-dbs		:= $(addprefix db-,\
+@@ -86,6 +94,45 @@ tests-static		= tst-nss-static
+ tests			+= $(tests-static)
+ endif
+ 
++ifneq ($(OPTION_EGLIBC_NSSWITCH),y)
++
++ifndef OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG
++$(error OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG variable left unset)
++endif
++
++ifndef OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS
++$(error OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS variable left unset)
++endif
++
++ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)))
++$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed config file)
++$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG))
++endif
++
++ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)))
++$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed functions file)
++$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS))
++endif
++
++before-compile := $(objpfx)fixed-nsswitch.h
++generated := fixed-nsswitch.h
++$(objpfx)fixed-nsswitch.h $(objfpx)fixed-nsswitch-libs:	\
++    $(objpfx)gen-fixed-nsswitch				\
++    $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
++	$< $(objpfx)fixed-nsswitch.h			\
++	   $(objpfx)fixed-nsswitch-libs			\
++	   $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
++
++$(objpfx)gen-fixed-nsswitch: gen-fixed-nsswitch.c	\
++    $(common-objpfx)option-groups.config		\
++    $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)
++	$(native-compile)
++gen-fixed-nsswitch-CFLAGS =						\
++	-g3 -O -Wall							\
++	-I $(objpfx)							\
++	-DFIXED_FUNCTIONS='"$(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)"'
++endif
++
+ include ../Rules
+ 
+ ifeq (yes,$(have-selinux))
+diff --git a/nss/fixed-nsswitch.conf b/nss/fixed-nsswitch.conf
+new file mode 100644
+index 0000000..91bb675
+--- /dev/null
++++ b/nss/fixed-nsswitch.conf
+@@ -0,0 +1,22 @@
++# /etc/nsswitch.conf
++#
++# Example configuration for fixed name service.
++# See the description of OPTION_EGLIBC_NSSWITCH in option-groups.def
++# for details.
++#
++
++aliases:        files
++
++passwd:         files
++group:          files
++shadow:         files
++
++hosts:          files dns
++networks:       files dns
++
++protocols:      files
++services:       files
++ethers:         files
++rpc:            files
++
++netgroup:       files
+diff --git a/nss/fixed-nsswitch.functions b/nss/fixed-nsswitch.functions
+new file mode 100644
+index 0000000..2f3fa83
+--- /dev/null
++++ b/nss/fixed-nsswitch.functions
+@@ -0,0 +1,121 @@
++/* List of functions defined for fixed NSS in GNU C Library.
++   Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   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.  */
++
++/* When OPTION_EGLIBC_NSSWITCH is disabled (see option-groups.def),
++   EGLIBC does not use the 'dlopen' and 'dlsym' functions to look for
++   database query functions in the individual name service libraries.
++   Instead, it uses a set of functions chosen at compile time, as
++   directed by the OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS file.  This
++   file is a sample of what you might use there.
++
++   This file is C source code; it should only contain invocations of
++   the following macros:
++
++   - DEFINE_ENT (DATABASE, SERVICE, X)
++
++     Declare the 'setXent', 'getXent_r', and 'endXent' functions that
++     query DATABASE using the service library 'libnss_SERVICE.so.2'.
++     DATABASE should be the full name of the database as it appears in
++     'nsswitch.conf', like 'passwd' or 'aliases'.
++
++     (The non-reentrant 'getXent' functions are implemented in terms
++     of the reentrant 'getXent_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++   - DEFINE_GETBY (DATABASE, SERVICE, X, KEY)
++
++     Declare the 'getXbyKEY_r' functions that query DATABASE using
++     SERVICE.  DATABASE and SERVICE are as described above.
++
++     (The non-reentrant 'getXbyKEY' functions are implemented in terms
++     of the reentrant 'getXbyKEY_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++     Use the special key 'name3' for the service library function that
++     implements the 'getaddrinfo' function.
++
++   - DEFINE_GET (DATABASE, SERVICE, QUERY)
++
++     Declare the 'getQUERY_r' functions that query DATABASE using
++     SERVICE.  This is used for functions like 'getpwnam'.
++
++     (The non-reentrant 'getQUERY' functions are implemented in terms
++     of the reentrant 'getQUERY_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++   This sample file only includes functions that consult the files in
++   '/etc', and the Domain Name System (DNS).  */
++
++/* aliases */
++DEFINE_ENT (aliases, files, alias)
++DEFINE_GETBY (aliases, files, alias, name)
++
++/* ethers */
++DEFINE_ENT (ethers, files, ether)
++
++/* group */
++DEFINE_ENT (group, files, gr)
++DEFINE_GET (group, files, grgid)
++DEFINE_GET (group, files, grnam)
++
++/* hosts */
++DEFINE_ENT (hosts, files, host)
++DEFINE_GETBY (hosts, files, host, addr)
++DEFINE_GETBY (hosts, files, host, name)
++DEFINE_GETBY (hosts, files, host, name2)
++DEFINE_GET (hosts, files, hostton)
++DEFINE_GET (hosts, files, ntohost)
++DEFINE_GETBY (hosts, dns, host, addr)
++DEFINE_GETBY (hosts, dns, host, name)
++DEFINE_GETBY (hosts, dns, host, name2)
++DEFINE_GETBY (hosts, dns, host, name3)
++
++/* netgroup */
++DEFINE_ENT (netgroup, files, netgr)
++
++/* networks */
++DEFINE_ENT (networks, files, net)
++DEFINE_GETBY (networks, files, net, name)
++DEFINE_GETBY (networks, files, net, addr)
++DEFINE_GETBY (networks, dns, net, name)
++DEFINE_GETBY (networks, dns, net, addr)
++
++/* protocols */
++DEFINE_ENT (protocols, files, proto)
++DEFINE_GETBY (protocols, files, proto, name)
++DEFINE_GETBY (protocols, files, proto, number)
++
++/* passwd */
++DEFINE_ENT (passwd, files, pw)
++DEFINE_GET (passwd, files, pwnam)
++DEFINE_GET (passwd, files, pwuid)
++
++/* rpc */
++DEFINE_ENT (rpc, files, rpc)
++DEFINE_GETBY (rpc, files, rpc, name)
++DEFINE_GETBY (rpc, files, rpc, number)
++
++/* services */
++DEFINE_ENT (services, files, serv)
++DEFINE_GETBY (services, files, serv, name)
++DEFINE_GETBY (services, files, serv, port)
++
++/* shadow */
++DEFINE_ENT (shadow, files, sp)
++DEFINE_GET (shadow, files, spnam)
+diff --git a/nss/gen-fixed-nsswitch.c b/nss/gen-fixed-nsswitch.c
+new file mode 100644
+index 0000000..6e1c98c
+--- /dev/null
++++ b/nss/gen-fixed-nsswitch.c
+@@ -0,0 +1,803 @@
++/* gen-fixed-nsswitch.c --- generate fixed name service data structures
++   Copyright (C) 1996-1999, 2001-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.  */
++
++#define _GNU_SOURCE
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <errno.h>
++#include <string.h>
++#include <stdarg.h>
++#include <assert.h>
++#include <ctype.h>
++
++#include "gnu/lib-names.h"
++#include "nss.h"
++
++/* Provide a fallback definition to allow this file to be compiled outside
++   libc.  */
++#ifndef internal_function
++# define internal_function
++#endif
++
++\f
++/* Simple utilities.  */
++
++void __attribute__ ((noreturn))
++error (const char *message)
++{
++  fprintf (stderr, "%s\n", message);
++  exit (1);
++}
++
++
++void *
++check_alloc (void *p)
++{
++  if (p)
++    return p;
++  else
++    error ("out of memory");
++}
++
++void *
++xmalloc (size_t size)
++{
++  return check_alloc (malloc (size));
++}
++
++
++/* Format ARGS according to FORMAT, and return the result as a
++   malloc'ed string.  */
++char *
++saprintf (const char *format, ...)
++{
++  va_list args;
++  size_t len;
++  char *buf;
++
++  va_start (args, format);
++  len = vsnprintf (NULL, 0, format, args);
++  va_end (args);
++
++  buf = xmalloc (len + 1);
++  va_start (args, format);
++  assert (len == vsnprintf (buf, len + 1, format, args));
++  va_end (args);
++
++  return buf;
++}
++
++
++\f
++/* Data structures representing the configuration file in memory.  */
++
++/* These are copied from nsswitch.h.
++
++   We could simply #include that file, but this program runs on the
++   build machine and links against the build machine's libraries,
++   whereas that header is meant for use by target code; it uses
++   'libc_hidden_proto', 'internal_function', and related hair.  Since
++   we've copied the parsing code, we might as well copy the data
++   structure definitions as well.  */
++
++/* Actions performed after lookup finished.  */
++typedef enum
++{
++  NSS_ACTION_CONTINUE,
++  NSS_ACTION_RETURN
++} lookup_actions;
++
++
++typedef struct service_library
++{
++  /* Name of service (`files', `dns', `nis', ...).  */
++  const char *name;
++  /* Pointer to the loaded shared library.  */
++  void *lib_handle;
++  /* And the link to the next entry.  */
++  struct service_library *next;
++} service_library;
++
++
++/* For mapping a function name to a function pointer.  It is known in
++   nsswitch.c:nss_lookup_function that a string pointer for the lookup key
++   is the first member.  */
++typedef struct
++{
++  const char *fct_name;
++  void *fct_ptr;
++} known_function;
++
++
++typedef struct service_user
++{
++  /* And the link to the next entry.  */
++  struct service_user *next;
++  /* Action according to result.  */
++  lookup_actions actions[5];
++  /* Link to the underlying library object.  */
++  service_library *library;
++  /* Collection of known functions.
++
++     With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
++     'tsearch'-style tree.
++
++     With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
++     pointers to known_function structures, NULL-terminated.  */
++  union
++  {
++    void *tree;
++    const known_function **array;
++  } known;
++  /* Name of the service (`files', `dns', `nis', ...).  */
++  const char *name;
++} service_user;
++
++/* To access the action based on the status value use this macro.  */
++#define nss_next_action(ni, status) ((ni)->actions[2 + status])
++
++
++typedef struct name_database_entry
++{
++  /* And the link to the next entry.  */
++  struct name_database_entry *next;
++  /* List of service to be used.  */
++  service_user *service;
++  /* Name of the database.  */
++  const char *name;
++} name_database_entry;
++
++
++typedef struct name_database
++{
++  /* List of all known databases.  */
++  name_database_entry *entry;
++  /* List of libraries with service implementation.  */
++  service_library *library;
++} name_database;
++
++
++\f
++/* Gathering the contents of the FIXED_FUNCTIONS file.  */
++
++/* It should be possible to generate this list automatically by
++   looking at the services and databases used in the nsswitch.conf
++   file, and having a hard-coded set of queries supported on each
++   database.  */
++
++/* We #include the FIXED_FUNCTIONS file several times to build an
++   array of function structures holding its data.  */
++enum function_kind {
++  fk_end = 0,                   /* Last entry.  */
++  fk_setent,                    /* Like setpwent.  */
++  fk_getent,                    /* Like getpwent.  */
++  fk_endent,                    /* Like endpwent.  */
++  fk_getby,                     /* Like gethostbyname.  */
++  fk_get                        /* Like getpwnam.  */
++};
++
++
++struct function {
++  /* What kind of function this is.  */
++  enum function_kind kind;
++
++  /* The database and service of the function being hardwired in.  */
++  char *database, *service;
++
++  /* The kind of entry being queried, for 'fk_setent', 'fk_getent',
++     'fk_endent', and 'fk_getby' functions.  */
++  char *entry;
++
++  /* The key, for 'fk_getby' entries.  */
++  char *key;
++
++  /* The value and key, for 'fk_get' entries.  */
++  char *value_and_key;
++};
++
++
++const struct function functions[] =
++  {
++
++#define DEFINE_ENT(database, service, entry)    \
++    { fk_setent, #database, #service, #entry }, \
++    { fk_getent, #database, #service, #entry }, \
++    { fk_endent, #database, #service, #entry },
++#define DEFINE_GETBY(database, service, entry, key)   \
++    { fk_getby, #database, #service, #entry, #key },
++#define DEFINE_GET(database, service, value_and_key)     \
++    { fk_get, #database, #service, NULL, NULL, #value_and_key },
++
++#include FIXED_FUNCTIONS
++
++#undef DEFINE_ENT
++#undef DEFINE_GETBY
++#undef DEFINE_GET
++
++    { fk_end }
++  };
++
++\f
++/* Parsing the config file.  Functions copied from nsswitch.c.  */
++
++#define __strchrnul strchrnul
++#define __getline getline
++#define __strncasecmp strncasecmp
++
++/* Prototypes for the local functions.  */
++static name_database *nss_parse_file (const char *fname) internal_function;
++static name_database_entry *nss_getline (char *line) internal_function;
++static service_user *nss_parse_service_list (const char *line)
++     internal_function;
++
++static name_database *
++internal_function
++nss_parse_file (const char *fname)
++{
++  FILE *fp;
++  name_database *result;
++  name_database_entry *last;
++  char *line;
++  size_t len;
++
++  /* Open the configuration file.  */
++  fp = fopen (fname, "rc");
++  if (fp == NULL)
++    return NULL;
++
++  // /* No threads use this stream.  */
++  // __fsetlocking (fp, FSETLOCKING_BYCALLER);
++
++  result = (name_database *) xmalloc (sizeof (name_database));
++
++  result->entry = NULL;
++  result->library = NULL;
++  last = NULL;
++  line = NULL;
++  len = 0;
++  do
++    {
++      name_database_entry *this;
++      ssize_t n;
++
++      n = __getline (&line, &len, fp);
++      if (n < 0)
++	break;
++      if (line[n - 1] == '\n')
++	line[n - 1] = '\0';
++
++      /* Because the file format does not know any form of quoting we
++	 can search forward for the next '#' character and if found
++	 make it terminating the line.  */
++      *__strchrnul (line, '#') = '\0';
++
++      /* If the line is blank it is ignored.  */
++      if (line[0] == '\0')
++	continue;
++
++      /* Each line completely specifies the actions for a database.  */
++      this = nss_getline (line);
++      if (this != NULL)
++	{
++	  if (last != NULL)
++	    last->next = this;
++	  else
++	    result->entry = this;
++
++	  last = this;
++	}
++    }
++  while (!feof_unlocked (fp));
++
++  /* Free the buffer.  */
++  free (line);
++  /* Close configuration file.  */
++  fclose (fp);
++
++  return result;
++}
++
++
++/* Read the source names:
++	`( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
++   */
++static service_user *
++internal_function
++nss_parse_service_list (const char *line)
++{
++  service_user *result = NULL, **nextp = &result;
++
++  while (1)
++    {
++      service_user *new_service;
++      const char *name;
++
++      while (isspace (line[0]))
++	++line;
++      if (line[0] == '\0')
++	/* No source specified.  */
++	return result;
++
++      /* Read <source> identifier.  */
++      name = line;
++      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
++	++line;
++      if (name == line)
++	return result;
++
++
++      new_service = (service_user *) xmalloc (sizeof (*new_service));
++      new_service->name = (char *) xmalloc (line - name + 1);
++
++      *((char *) __mempcpy ((char *) new_service->name, name, line - name))
++        = '\0';
++
++      /* Set default actions.  */
++      new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
++      new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
++      new_service->library = NULL;
++      new_service->known.tree = NULL;
++      new_service->next = NULL;
++
++      while (isspace (line[0]))
++	++line;
++
++      if (line[0] == '[')
++	{
++	  /* Read criterions.  */
++	  do
++	    ++line;
++	  while (line[0] != '\0' && isspace (line[0]));
++
++	  do
++	    {
++	      int not;
++	      enum nss_status status;
++	      lookup_actions action;
++
++	      /* Grok ! before name to mean all statii but that one.  */
++	      not = line[0] == '!';
++	      if (not)
++		++line;
++
++	      /* Read status name.  */
++	      name = line;
++	      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
++		     && line[0] != ']')
++		++line;
++
++	      /* Compare with known statii.  */
++	      if (line - name == 7)
++		{
++		  if (__strncasecmp (name, "SUCCESS", 7) == 0)
++		    status = NSS_STATUS_SUCCESS;
++		  else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
++		    status = NSS_STATUS_UNAVAIL;
++		  else
++		    return result;
++		}
++	      else if (line - name == 8)
++		{
++		  if (__strncasecmp (name, "NOTFOUND", 8) == 0)
++		    status = NSS_STATUS_NOTFOUND;
++		  else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
++		    status = NSS_STATUS_TRYAGAIN;
++		  else
++		    return result;
++		}
++	      else
++		return result;
++
++	      while (isspace (line[0]))
++		++line;
++	      if (line[0] != '=')
++		return result;
++	      do
++		++line;
++	      while (isspace (line[0]));
++
++	      name = line;
++	      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
++		     && line[0] != ']')
++		++line;
++
++	      if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
++		action = NSS_ACTION_RETURN;
++	      else if (line - name == 8
++		       && __strncasecmp (name, "CONTINUE", 8) == 0)
++		action = NSS_ACTION_CONTINUE;
++	      else
++		return result;
++
++	      if (not)
++		{
++		  /* Save the current action setting for this status,
++		     set them all to the given action, and reset this one.  */
++		  const lookup_actions save = new_service->actions[2 + status];
++		  new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action;
++		  new_service->actions[2 + NSS_STATUS_UNAVAIL] = action;
++		  new_service->actions[2 + NSS_STATUS_NOTFOUND] = action;
++		  new_service->actions[2 + NSS_STATUS_SUCCESS] = action;
++		  new_service->actions[2 + status] = save;
++		}
++	      else
++		new_service->actions[2 + status] = action;
++
++	      /* Skip white spaces.  */
++	      while (isspace (line[0]))
++		++line;
++	    }
++	  while (line[0] != ']');
++
++	  /* Skip the ']'.  */
++	  ++line;
++	}
++
++      *nextp = new_service;
++      nextp = &new_service->next;
++    }
++}
++
++static name_database_entry *
++internal_function
++nss_getline (char *line)
++{
++  const char *name;
++  name_database_entry *result;
++  size_t len;
++
++  /* Ignore leading white spaces.  ATTENTION: this is different from
++     what is implemented in Solaris.  The Solaris man page says a line
++     beginning with a white space character is ignored.  We regard
++     this as just another misfeature in Solaris.  */
++  while (isspace (line[0]))
++    ++line;
++
++  /* Recognize `<database> ":"'.  */
++  name = line;
++  while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':')
++    ++line;
++  if (line[0] == '\0' || name == line)
++    /* Syntax error.  */
++    return NULL;
++  *line++ = '\0';
++
++  len = strlen (name) + 1;
++
++  result = (name_database_entry *) xmalloc (sizeof (*result));
++  result->name = (char *) xmalloc (len);
++
++  /* Save the database name.  */
++  memcpy ((char *) result->name, name, len);
++
++  /* Parse the list of services.  */
++  result->service = nss_parse_service_list (line);
++
++  result->next = NULL;
++  return result;
++}
++
++
++\f
++/* Generating code for statically initialized nsswitch structures.  */
++
++
++/* Return the service-neutral suffix of the name of the service
++   library function referred to by the function F.  The result is
++   allocated with malloc.  */
++char *
++known_function_suffix (const struct function *f)
++{
++  switch (f->kind)
++    {
++    case fk_setent:
++      return saprintf ("set%sent", f->entry);
++
++    case fk_getent:
++      return saprintf ("get%sent_r", f->entry);
++
++    case fk_endent:
++      return saprintf ("end%sent", f->entry);
++
++    case fk_getby:
++      return saprintf ("get%sby%s_r", f->entry, f->key);
++
++    case fk_get:
++      return saprintf ("get%s_r", f->value_and_key);
++
++    default:
++      abort ();
++    }
++}
++
++
++/* Return the name of the service library function referred to by the
++   function F.  The result is allocated with malloc.  */
++char *
++known_function_name (const struct function *f)
++{
++  return saprintf ("_nss_%s_%s", f->service, known_function_suffix (f));
++}
++
++
++/* Write initialized known_function structures to OUT for
++   all the functions we'll use.  */
++void
++generate_known_functions (FILE *out)
++{
++  int i;
++
++  /* First, generate weak references to the functions.  The service
++     libraries depend on libc, and if these references weren't weak,
++     we'd be making libc depend circularly on the service
++     libraries.  */
++  for (i = 0; functions[i].kind; i++)
++    {
++      char *name = known_function_name (&functions[i]);
++      fprintf (out, "typeof (%s) %s __attribute__ ((weak));\n",
++               name, name);
++    }
++  fputs ("\n", out);
++
++  /* Then, a table mapping names to functions.  */
++  fputs ("static const known_function fixed_known_functions[] = {\n",
++         out);
++  for (i = 0; functions[i].kind; i++)
++    {
++      const struct function *f = &functions[i];
++      char *suffix = known_function_suffix (f);
++
++      fprintf (out, "  /* %2d */ { \"%s\", _nss_%s_%s },\n",
++               i, suffix, f->service, suffix);
++    }
++  fputs ("};\n", out);
++  fputs ("\n", out);
++}
++
++
++/* Print code to OUT for an initialized array of pointers to the
++   'known_function' structures needed for USER, which is for
++   DATABASE.  Return its name, allocated with malloc.  */
++char *
++generate_known_function_list (FILE *out,
++                              const name_database_entry *database,
++                              const service_user *user)
++{
++  char *list_name = saprintf ("fixed_%s_%s_known_funcs",
++                              database->name, user->name);
++  fprintf (out, "static const known_function *%s[] = {\n",
++           list_name);
++  int i;
++  for (i = 0; functions[i].kind; i++)
++    if (strcmp (functions[i].database, database->name) == 0
++        && strcmp (functions[i].service, user->name) == 0)
++      fprintf (out, "  &fixed_known_functions[%d], /* %s */\n",
++               i, known_function_name (&functions[i]));
++  fputs ("  NULL\n", out);
++  fputs ("};\n", out);
++  fputs ("\n", out);
++
++  return list_name;
++}
++
++
++/* Return the name of the status value STATUS, as a statically
++   allocated string.  */
++const char *
++lookup_status_name (enum nss_status status)
++{
++  switch (status)
++    {
++    case NSS_STATUS_TRYAGAIN: return "NSS_STATUS_TRYAGAIN";
++    case NSS_STATUS_UNAVAIL: return "NSS_STATUS_UNAVAIL";
++    case NSS_STATUS_NOTFOUND: return "NSS_STATUS_NOTFOUND";
++    case NSS_STATUS_SUCCESS: return "NSS_STATUS_SUCCESS";
++    case NSS_STATUS_RETURN: return "NSS_STATUS_RETURN";
++    default: abort ();
++    };
++}
++
++
++/* Return the name of ACTION as a statically allocated string.  */
++const char *
++lookup_action_name (lookup_actions action)
++{
++  switch (action)
++    {
++    case NSS_ACTION_CONTINUE: return "NSS_ACTION_CONTINUE";
++    case NSS_ACTION_RETURN: return "NSS_ACTION_RETURN";
++    default: abort ();
++    }
++}
++
++
++/* Print code to OUT for the list of service_user structures starting
++   with USER, which are all for DATABASE.  Return the name of the
++   first structure in that list, or zero if USER is NULL.  */
++char *
++generate_service_user_list (FILE *out,
++                            name_database_entry *database,
++                            service_user *user)
++{
++  if (user)
++    {
++      /* Generate the tail of the list.  */
++      char *next_name = generate_service_user_list (out, database, user->next);
++      /* Generate our known function list.  */
++      char *known_function_list_name =
++        generate_known_function_list (out, database, user);
++
++      char *name = saprintf ("fixed_%s_%s_user", database->name, user->name);
++
++      fprintf (out, "static const service_user %s = {\n", name);
++      if (next_name)
++        fprintf (out, "  (service_user *) &%s,\n", next_name);
++      else
++        fprintf (out, "  NULL, /* no next entry */\n");
++      fputs ("  {\n", out);
++      int i;
++      for (i = 0; i < sizeof (user->actions) / sizeof (user->actions[0]); i++)
++        fprintf (out, "    %s, /* %s */\n",
++                 lookup_action_name (user->actions[i]),
++                 lookup_status_name (i - 2));
++      fputs ("  },\n", out);
++      fprintf (out, "  NULL,  /* we never need the service library */\n");
++      fprintf (out, "  { .array = %s },\n", known_function_list_name);
++      fprintf (out, "  \"%s\"\n", user->name);
++      fputs ("};\n", out);
++      fputs ("\n", out);
++
++      return name;
++    }
++  else
++    return NULL;
++}
++
++
++/* Print code to OUT for the list of name_database_entry structures
++   starting with DATABASE.  Return the name of the first structure
++   in that list, or zero if DATABASE is NULL.  */
++char *
++generate_name_database_entries (FILE *out, name_database_entry *database)
++{
++  if (database)
++    {
++      char *next_name = generate_name_database_entries (out, database->next);
++      char *service_user_name
++        = generate_service_user_list (out, database, database->service);
++      char *name = saprintf ("fixed_%s_name_database", database->name);
++
++      fprintf (out, "static const name_database_entry %s = {\n", name);
++
++      if (next_name)
++        fprintf (out, "  (name_database_entry *) &%s,\n", next_name);
++      else
++        fprintf (out, "  NULL,\n");
++
++      if (service_user_name)
++        fprintf (out, "  (service_user *) &%s,\n", service_user_name);
++      else
++        fprintf (out, "  NULL,\n");
++
++      fprintf (out, "  \"%s\"\n", database->name);
++      fprintf (out, "};\n");
++      fputs ("\n", out);
++
++      return name;
++    }
++  else
++    return NULL;
++}
++
++
++void
++generate_name_database (FILE *out, name_database *service_table)
++{
++  /* Produce a linked list of the known name_database_entry
++     structures.  */
++  char *entries = generate_name_database_entries (out, service_table->entry);
++
++  /* Now produce the main structure that points to them all.  */
++  fprintf (out, "static const name_database fixed_name_database = {\n");
++  if (entries)
++    fprintf (out, "  (name_database_entry *) &%s,\n", entries);
++  else
++    fprintf (out, "  NULL,\n");
++  fputs ("  NULL /* we don't need the libraries */\n"
++         "};\n",
++         out);
++}
++
++
++\f
++/* Generating the list of service libraries we generate references to.  */
++
++/* String with revision number of the shared object files.  */
++static const char *const nss_shlib_revision = LIBNSS_FILES_SO + 15;
++
++void
++generate_service_lib_list (FILE *out, name_database *service_table)
++{
++  int i, j;
++  int printed_any = 0;
++
++  for (i = 0; functions[i].kind; i++)
++    {
++      /* Mention each service library only once.  */
++      for (j = 0; j < i; j++)
++        if (strcmp (functions[i].service, functions[j].service) == 0)
++          break;
++
++      if (j >= i)
++        {
++          if (printed_any)
++            putc (' ', out);
++          fprintf (out, "-lnss_%s",
++                   functions[i].service,
++                   nss_shlib_revision);
++          printed_any = 1;
++        }
++    }
++}
++
++\f
++/* Main.  */
++
++int
++main (int argc, char **argv)
++{
++  if (argc != 4)
++    {
++      fprintf (stderr, "usage: gen-fixed-nsswitch HEADER SERVLIBS CONFIG\n");
++      exit (1);
++    }
++
++  name_database *service_table = nss_parse_file (argv[3]);
++
++  FILE *header = fopen (argv[1], "w");
++  if (! header)
++    {
++      fprintf (stderr,
++               "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
++               argv[1], strerror (errno));
++      exit (1);
++    }
++  fputs ("/* Generated by nss/gen-fixed-nsswitch.c.  */\n", header);
++  fputs ("\n", header);
++  generate_known_functions (header);
++  generate_name_database (header, service_table);
++  fclose (header);
++
++  FILE *service_lib_list = fopen (argv[2], "w");
++  if (! service_lib_list)
++    {
++      fprintf (stderr,
++               "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
++               argv[2], strerror (errno));
++      exit (1);
++    }
++  generate_service_lib_list (service_lib_list, service_table);
++  fclose (service_lib_list);
++
++  return 0;
++}
+diff --git a/nss/getent.c b/nss/getent.c
+index 34df848..674c8ee 100644
+--- a/nss/getent.c
++++ b/nss/getent.c
+@@ -39,6 +39,7 @@
+ #include <netinet/ether.h>
+ #include <netinet/in.h>
+ #include <sys/socket.h>
++#include <gnu/option-groups.h>
+ 
+ /* Get libc version number.  */
+ #include <version.h>
+@@ -91,6 +92,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+   fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
+ }
+ 
++#if __OPTION_EGLIBC_DB_ALIASES
+ /* This is for aliases */
+ static void
+ print_aliases (struct aliasent *alias)
+@@ -135,7 +137,9 @@ aliases_keys (int number, char *key[])
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_DB_ALIASES */
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for ethers */
+ static int
+ ethers_keys (int number, char *key[])
+@@ -179,6 +183,7 @@ ethers_keys (int number, char *key[])
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* This is for group */
+ static void
+@@ -301,6 +306,7 @@ gshadow_keys (int number, char *key[])
+   return result;
+ }
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for hosts */
+ static void
+ print_hosts (struct hostent *host)
+@@ -598,6 +604,7 @@ networks_keys (int number, char *key[])
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* Now is all for passwd */
+ static void
+@@ -650,6 +657,7 @@ passwd_keys (int number, char *key[])
+   return result;
+ }
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for protocols */
+ static void
+ print_protocols (struct protoent *proto)
+@@ -807,6 +815,7 @@ services_keys (int number, char *key[])
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* This is for shadow */
+ static void
+@@ -873,23 +882,36 @@ struct
+   } databases[] =
+   {
+ #define D(name) { #name, name ## _keys },
+-D(ahosts)
+-D(ahostsv4)
+-D(ahostsv6)
+-D(aliases)
+-D(ethers)
++
++#if __OPTION_EGLIBC_INET
++# define DN(name) D(name)
++#else
++# define DN(name)
++#endif
++
++#if __OPTION_EGLIBC_DB_ALIASES
++# define DA(name) D(name)
++#else
++# define DA(name)
++#endif
++
++DN(ahosts)
++DN(ahostsv4)
++DN(ahostsv6)
++DA(aliases)
++DN(ethers)
+ D(group)
+ D(gshadow)
+-D(hosts)
+-D(initgroups)
+-D(netgroup)
+-D(networks)
++DN(hosts)
++DN(initgroups)
++DN(netgroup)
++DN(networks)
+ D(passwd)
+-D(protocols)
++DN(protocols)
+ #if HAVE_SUNRPC
+-D(rpc)
++DN(rpc)
+ #endif
+-D(services)
++DN(services)
+ D(shadow)
+ #undef D
+     { NULL, NULL }
+diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c
+index f5b9036..f09f7fe 100644
+--- a/nss/getnssent_r.c
++++ b/nss/getnssent_r.c
+@@ -16,6 +16,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <errno.h>
++#include <gnu/option-groups.h>
+ #include <netdb.h>
+ #include "nsswitch.h"
+ 
+@@ -59,11 +60,13 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
+   } fct;
+   int no_more;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       __set_h_errno (NETDB_INTERNAL);
+       return;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Cycle through the services and run their `setXXent' functions until
+      we find an available service.  */
+@@ -101,11 +104,13 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct,
+   } fct;
+   int no_more;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       __set_h_errno (NETDB_INTERNAL);
+       return;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Cycle through all the services and run their endXXent functions.  */
+   no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
+@@ -141,12 +146,14 @@ __nss_getent_r (const char *getent_func_name,
+   int no_more;
+   enum nss_status status;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       *h_errnop = NETDB_INTERNAL;
+       *result = NULL;
+       return errno;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Initialize status to return if no more functions are found.  */
+   status = NSS_STATUS_NOTFOUND;
+@@ -161,7 +168,7 @@ __nss_getent_r (const char *getent_func_name,
+       int is_last_nip = *nip == *last_nip;
+ 
+       status = DL_CALL_FCT (fct.f,
+-			    (resbuf, buffer, buflen, &errno, &h_errno));
++			    (resbuf, buffer, buflen, &errno, h_errnop));
+ 
+       /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
+ 	 provided buffer is too small.  In this case we should give
+diff --git a/nss/nsswitch.c b/nss/nsswitch.c
+index 9712623..c81e207 100644
+--- a/nss/nsswitch.c
++++ b/nss/nsswitch.c
+@@ -26,6 +26,7 @@
+ #include <stdio_ext.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ #include <aliases.h>
+ #include <grp.h>
+@@ -41,6 +42,15 @@
+ #include "../nscd/nscd_proto.h"
+ #include <sysdep.h>
+ 
++/* When OPTION_EGLIBC_NSSWITCH is disabled, we use fixed tables of
++   databases and services, generated at library build time.  Thus:
++   - We can't reconfigure individual databases, so we don't need a
++     name-to-database map.
++   - We never add databases or service libraries, or look up functions
++     at runtime, so there's no need for a lock to protect our tables.
++   See ../option-groups.def for the details.  */
++#if __OPTION_EGLIBC_NSSWITCH
++
+ /* Prototypes for the local functions.  */
+ static name_database *nss_parse_file (const char *fname) internal_function;
+ static name_database_entry *nss_getline (char *line) internal_function;
+@@ -79,6 +89,9 @@ bool __nss_database_custom[NSS_DBSIDX_max];
+ 
+ __libc_lock_define_initialized (static, lock)
+ 
++#define lock_nsswitch __libc_lock_lock (lock)
++#define unlock_nsswitch __libc_lock_unlock (lock)
++
+ #if !defined DO_STATIC_NSS || defined SHARED
+ /* String with revision number of the shared object files.  */
+ static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
+@@ -93,6 +106,20 @@ static name_database *service_table;
+    __libc_freeres.  */
+ static name_database_entry *defconfig_entries;
+ 
++#else /* __OPTION_EGLIBC_NSSWITCH */
++
++/* Bring in the statically initialized service table we generated at
++   build time.  */
++#include "fixed-nsswitch.h"
++
++const static name_database *service_table = &fixed_name_database;
++
++/* Nothing ever changes, so there's no need to lock anything.  */
++#define lock_nsswitch (0)
++#define unlock_nsswitch (0)
++
++#endif /* __OPTION_EGLIBC_NSSWITCH */
++
+ 
+ #ifdef USE_NSCD
+ /* Nonzero if this is the nscd process.  */
+@@ -109,20 +136,22 @@ __nss_database_lookup (const char *database, const char *alternate_name,
+ 		       const char *defconfig, service_user **ni)
+ {
+   /* Prevent multiple threads to change the service table.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Reconsider database variable in case some other thread called
+      `__nss_configure_lookup' while we waited for the lock.  */
+   if (*ni != NULL)
+     {
+-      __libc_lock_unlock (lock);
++      unlock_nsswitch;
+       return 0;
+     }
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+   /* Are we initialized yet?  */
+   if (service_table == NULL)
+     /* Read config file.  */
+     service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
++#endif
+ 
+   /* Test whether configuration data is available.  */
+   if (service_table != NULL)
+@@ -144,6 +173,7 @@ __nss_database_lookup (const char *database, const char *alternate_name,
+ 	    *ni = entry->service;
+     }
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+   /* No configuration data is available, either because nsswitch.conf
+      doesn't exist or because it doesn't have a line for this database.
+ 
+@@ -166,13 +196,23 @@ __nss_database_lookup (const char *database, const char *alternate_name,
+ 	    {
+ 	      entry->next = defconfig_entries;
+ 	      entry->service = *ni;
+-	      entry->name[0] = '\0';
++	      entry->name = "";
+ 	      defconfig_entries = entry;
+ 	    }
+ 	}
+     }
++#else
++  /* Without the dynamic behavior, we can't process defconfig.  The
++     databases the user specified at library build time are all you
++     get.  */
++  if (*ni == NULL)
++    {
++      unlock_nsswitch;
++      return -1;
++    }
++#endif
+ 
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return *ni != NULL ? 0 : -1;
+ }
+@@ -252,6 +292,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name,
+ libc_hidden_def (__nss_next2)
+ 
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+ int
+ attribute_compat_text_section
+ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
+@@ -300,13 +341,13 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
+     }
+ 
+   /* Prevent multiple threads to change the service table.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Install new rules.  */
+   *databases[cnt].dbp = new_db;
+   __nss_database_custom[cnt] = true;
+ 
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return 0;
+ }
+@@ -402,7 +443,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
+   void **found, *result;
+ 
+   /* We now modify global data.  Protect it.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Search the tree of functions previously requested.  Data in the
+      tree are `known_function' structures, whose first member is a
+@@ -413,7 +454,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
+      enough to a pointer to our structure to use as a lookup key that
+      will be passed to `known_compare' (above).  */
+ 
+-  found = __tsearch (&fct_name, &ni->known, &known_compare);
++  found = __tsearch (&fct_name, &ni->known.tree, &known_compare);
+   if (found == NULL)
+     /* This means out-of-memory.  */
+     result = NULL;
+@@ -440,7 +481,7 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
+ #endif
+ 	  /* Oops.  We can't instantiate this node properly.
+ 	     Remove it from the tree.  */
+-	  __tdelete (&fct_name, &ni->known, &known_compare);
++	  __tdelete (&fct_name, &ni->known.tree, &known_compare);
+ 	  free (known);
+ 	  result = NULL;
+ 	}
+@@ -520,13 +561,43 @@ __nss_lookup_function (service_user *ni, const char *fct_name)
+     }
+ 
+   /* Remove the lock.  */
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return result;
+ }
+ libc_hidden_def (__nss_lookup_function)
+ 
+ 
++#else /* below if ! __OPTION_EGLIBC_NSSWITCH */
++
++
++int
++__nss_configure_lookup (const char *dbname, const char *service_line)
++{
++  /* We can't dynamically configure lookup without
++     OPTION_EGLIBC_NSSWITCH.  */
++  __set_errno (EINVAL);
++  return -1;
++}
++
++
++void *
++__nss_lookup_function (service_user *ni, const char *fct_name)
++{
++  int i;
++  const known_function **known = ni->known.array;
++
++  for (i = 0; known[i]; i++)
++    if (strcmp (fct_name, known[i]->fct_name) == 0)
++      return known[i]->fct_ptr;
++
++  return NULL;
++}
++libc_hidden_def (__nss_lookup_function)
++#endif
++
++
++#if __OPTION_EGLIBC_NSSWITCH
+ static name_database *
+ internal_function
+ nss_parse_file (const char *fname)
+@@ -632,8 +703,10 @@ nss_parse_service_list (const char *line)
+ 					     + (line - name + 1));
+       if (new_service == NULL)
+ 	return result;
++      new_service->name = (char *) (new_service + 1);
+ 
+-      *((char *) __mempcpy (new_service->name, name, line - name)) = '\0';
++      *((char *) __mempcpy ((char *) new_service->name, name, line - name))
++        = '\0';
+ 
+       /* Set default actions.  */
+       new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
+@@ -642,7 +715,7 @@ nss_parse_service_list (const char *line)
+       new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
+       new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
+       new_service->library = NULL;
+-      new_service->known = NULL;
++      new_service->known.tree = NULL;
+       new_service->next = NULL;
+ 
+       while (isspace (line[0]))
+@@ -778,9 +851,10 @@ nss_getline (char *line)
+   result = (name_database_entry *) malloc (sizeof (name_database_entry) + len);
+   if (result == NULL)
+     return NULL;
++  result->name = (char *) (result + 1);
+ 
+   /* Save the database name.  */
+-  memcpy (result->name, name, len);
++  memcpy ((char *) result->name, name, len);
+ 
+   /* Parse the list of services.  */
+   result->service = nss_parse_service_list (line);
+@@ -816,6 +890,7 @@ nss_new_service (name_database *database, const char *name)
+   return *currentp;
+ }
+ #endif
++#endif /* __OPTION_EGLIBC_NSSWITCH */
+ 
+ 
+ #if defined SHARED && defined USE_NSCD
+@@ -834,6 +909,7 @@ nss_load_all_libraries (const char *service, const char *def)
+ }
+ 
+ 
++#if __OPTION_EGLIBC_INET
+ /* Called by nscd and nscd alone.  */
+ void
+ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
+@@ -857,8 +933,10 @@ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
+   __nss_not_use_nscd_services = -1;
+   __nss_not_use_nscd_netgroup = -1;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ #endif
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+ static void
+ free_database_entries (name_database_entry *entry)
+ {
+@@ -871,8 +949,8 @@ free_database_entries (name_database_entry *entry)
+ 	{
+ 	  service_user *olds = service;
+ 
+-	  if (service->known != NULL)
+-	    __tdestroy (service->known, free);
++	  if (service->known.tree != NULL)
++	    __tdestroy (service->known.tree, free);
+ 
+ 	  service = service->next;
+ 	  free (olds);
+@@ -926,3 +1004,4 @@ libc_freeres_fn (free_mem)
+ 
+   free (top);
+ }
++#endif /* __OPTION_EGLIBC_NSSWITCH */
+diff --git a/nss/nsswitch.h b/nss/nsswitch.h
+index a5318fa..1730977 100644
+--- a/nss/nsswitch.h
++++ b/nss/nsswitch.h
+@@ -65,10 +65,20 @@ typedef struct service_user
+   lookup_actions actions[5];
+   /* Link to the underlying library object.  */
+   service_library *library;
+-  /* Collection of known functions.  */
+-  void *known;
++  /* Collection of known functions.
++
++     With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
++     'tsearch'-style tree.
++
++     With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
++     pointers to known_function structures, NULL-terminated.  */
++  union
++  {
++    void *tree;
++    const known_function **array;
++  } known;
+   /* Name of the service (`files', `dns', `nis', ...).  */
+-  char name[0];
++  const char *name;
+ } service_user;
+ 
+ /* To access the action based on the status value use this macro.  */
+@@ -82,7 +92,7 @@ typedef struct name_database_entry
+   /* List of service to be used.  */
+   service_user *service;
+   /* Name of the database.  */
+-  char name[0];
++  const char *name;
+ } name_database_entry;
+ 
+ 
+diff --git a/posix/Makefile b/posix/Makefile
+index 15e8818..609ed03 100644
+--- a/posix/Makefile
++++ b/posix/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for POSIX portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= posix
+ 
+ include ../Makeconfig
+@@ -43,13 +45,24 @@ routines :=								      \
+ 	getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid	      \
+ 	getresuid getresgid setresuid setresgid				      \
+ 	pathconf sysconf fpathconf					      \
+-	glob glob64 fnmatch regex					      \
++	glob glob64 fnmatch						      \
+ 	confstr								      \
+ 	getopt getopt1 getopt_init					      \
+ 	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
+ 	sched_primin sched_rr_gi sched_getaffinity sched_setaffinity	      \
+-	getaddrinfo gai_strerror wordexp				      \
+ 	pread pwrite pread64 pwrite64					      \
++	posix_madvise							      \
++	get_child_max sched_cpucount sched_cpualloc sched_cpufree
++
++routines-$(OPTION_EGLIBC_INET) += getaddrinfo gai_strerror
++
++ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
++routines-$(OPTION_POSIX_REGEXP) += regex
++else
++routines-$(OPTION_POSIX_REGEXP) += xregex
++endif
++
++routines-$(OPTION_EGLIBC_SPAWN) +=					      \
+ 	spawn_faction_init spawn_faction_destroy spawn_faction_addclose	      \
+ 	spawn_faction_addopen spawn_faction_adddup2			      \
+ 	spawnattr_init spawnattr_destroy				      \
+@@ -61,37 +74,54 @@ routines :=								      \
+ 	posix_madvise							      \
+ 	get_child_max sched_cpucount sched_cpualloc sched_cpufree
+ 
++routines-$(OPTION_EGLIBC_WORDEXP) += wordexp
++
+ aux		:= init-posix environ
+-tests		:= tstgetopt testfnm runtests runptests	     \
++tests		:= tstgetopt testfnm runtests \
+ 		   tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \
+-		   tst-mmap tst-getaddrinfo tst-truncate \
+-		   tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \
+-		   tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \
+-		   tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \
+-		   bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \
+-		   bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
+-		   bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
+-		   bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
+-		   bug-regex25 bug-regex26 bug-regex27 bug-regex28 \
++		   tst-mmap tst-truncate \
++		   tst-truncate64 tst-fork tst-dir \
++		   tst-chmod bug-regex2 bug-regex3 bug-regex4 \
++		   tst-gnuglob bug-regex6 bug-regex7 \
++		   bug-regex8 bug-regex9 bug-regex10 bug-regex12 \
++		   bug-regex14 bug-regex15 \
++		   bug-regex21 bug-regex24 \
++		   bug-regex27 bug-regex28 \
+ 		   bug-regex29 bug-regex30 bug-regex31 bug-regex32 \
+-		   bug-regex33 tst-nice tst-nanosleep tst-regex2 \
+-		   transbug tst-rxspencer tst-pcre tst-boost \
+-		   bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
+-		   tst-getaddrinfo2 bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
++		   tst-nice tst-nanosleep \
++		   transbug \
++		   tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
++		   bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
+ 		   tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
+ 		   tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
+ 		   tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
+-		   tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
+-		   tst-rfc3484-3 \
+-		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
++		   tst-execvp3 tst-execvp4 \
++		   tst-fnmatch2 tst-cpucount tst-cpuset \
+ 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
+ 		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
+ 		   tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
+ 		   tst-fnmatch3 bug-regex36 tst-getaddrinfo5
+-xtests		:= bug-ga2
++
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= tst-fnmatch tst-regexloc bug-regex1 bug-regex5 \
++		   bug-regex23 bug-regex25 bug-regex32 bug-regex33
++tests-$(OPTION_EGLIBC_INET) \
++		+= tst-getaddrinfo bug-ga1 tst-getaddrinfo2 \
++		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 tst-getaddrinfo3
++tests-$(OPTION_POSIX_REGEXP_GLIBC) \
++		+= runptests bug-regex11 bug-regex13 bug-regex16 \
++		   tst-regex2 tst-rxspencer tst-pcre tst-boost
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP_GLIBC))
++tests		+= tst-regex bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
++		   bug-regex22 bug-regex26
++endif
++xtests-$(OPTION_EGLIBC_INET) += bug-ga2
++
+ ifeq (yes,$(build-shared))
+ test-srcs	:= globtest
+-tests           += wordexp-test tst-exec tst-spawn
++tests		+= tst-exec
++tests-$(OPTION_EGLIBC_SPAWN) += tst-spawn
++tests-$(OPTION_EGLIBC_WORDEXP) += wordexp-test
+ endif
+ tests-static	= tst-exec-static tst-spawn-static
+ tests		+= $(tests-static)
+@@ -117,7 +147,10 @@ generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
+ 
+ ifeq ($(run-built-tests),yes)
+ ifeq (yes,$(build-shared))
+-tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
++tests-special += $(objpfx)globtest.out
++ifeq (y,$(OPTION_EGLIBC_WORDEXP))
++tests-special += $(objpfx)wordexp-tst.out
++endif
+ endif
+ endif
+ 
+@@ -125,12 +158,16 @@ endif
+ # XXX Please note that for now we ignore the result of this test.
+ tests-special += $(objpfx)annexc.out
+ ifeq ($(run-built-tests),yes)
+-tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
++tests-special += $(objpfx)bug-regex2-mem.out \
+ 		 $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
+-		 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
+-		 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
++		 $(objpfx)tst-getconf.out \
+ 		 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
+ 		 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
++ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
++tests-special += $(objpfx)bug-regex14-mem.out $(objpfx)tst-rxspencer-no-utf8-mem.out \
++  		 $(objpfx)tst-pcre-mem.out $(objpfx)tst-boost-mem.out
++endif
++
+ xtests-special += $(objpfx)bug-ga2-mem.out
+ endif
+ 
+@@ -143,6 +180,8 @@ $(objpfx)globtest.out: globtest.sh $(objpfx)globtest
+ 	$(SHELL) $< $(common-objpfx) '$(test-via-rtld-prefix)' \
+ 		'$(test-program-prefix)' '$(test-wrapper-env)'; \
+ 	$(evaluate-test)
++LDLIBS-globtest += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
++
+ $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
+ 	$(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \
+ 		 '$(run-program-env)' '$(test-program-prefix-after-env)'; \
+@@ -205,7 +244,10 @@ tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir);
+ tst-chmod-ARGS = $(objdir)
+ tst-vfork3-ARGS = --test-dir=$(objpfx)
+ 
+-tst-rxspencer-ARGS = --utf8 rxspencer/tests
++tst-rxspencer-ARGS = rxspencer/tests
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++tst-rxspencer-ARGS += --utf8
++endif
+ tst-rxspencer-no-utf8-ARGS = rxspencer/tests
+ tst-pcre-ARGS = PCRE.tests
+ tst-boost-ARGS = BOOST.tests
+diff --git a/posix/bug-regex1.c b/posix/bug-regex1.c
+index 38eb543..17cd1a0 100644
+--- a/posix/bug-regex1.c
++++ b/posix/bug-regex1.c
+@@ -4,6 +4,7 @@
+ #include <string.h>
+ #include <regex.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ int
+ main (void)
+@@ -17,7 +18,9 @@ main (void)
+   memset (&regex, '\0', sizeof (regex));
+ 
+   setlocale (LC_ALL, "de_DE.ISO-8859-1");
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+   fwide (stdout, -1);
++#endif
+ 
+   re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_DEBUG);
+ 
+diff --git a/posix/bug-regex6.c b/posix/bug-regex6.c
+index efcc890..3b270c7 100644
+--- a/posix/bug-regex6.c
++++ b/posix/bug-regex6.c
+@@ -22,6 +22,7 @@
+ #include <string.h>
+ #include <sys/types.h>
+ #include <regex.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -30,7 +31,12 @@ main (int argc, char *argv[])
+   regex_t re;
+   regmatch_t mat[10];
+   int i, j, ret = 0;
+-  const char *locales[] = { "C", "de_DE.UTF-8" };
++  const char *locales[] = {
++    "C",
++#if __OPTION_EGLIBC_LOCALE_CODE
++    "de_DE.UTF-8"
++#endif
++  };
+   const char *string = "http://www.regex.com/pattern/matching.html#intro";
+   regmatch_t expect[10] = {
+     { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 },
+diff --git a/posix/fnmatch.c b/posix/fnmatch.c
+index fd85efa..01cc9fe 100644
+--- a/posix/fnmatch.c
++++ b/posix/fnmatch.c
+@@ -30,6 +30,10 @@
+ #include <ctype.h>
+ #include <string.h>
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined STDC_HEADERS || defined _LIBC
+ # include <stdlib.h>
+ #endif
+@@ -131,7 +135,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags);
+ #   define ISWCTYPE(WC, WT)	iswctype (WC, WT)
+ #  endif
+ 
+-#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
++#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS && _LIBC && __OPTION_EGLIBC_LOCALE_CODE)
+ /* In this case we are implementing the multibyte character handling.  */
+ #   define HANDLE_MULTIBYTE	1
+ #  endif
+diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c
+index f46c9df..74e1754 100644
+--- a/posix/fnmatch_loop.c
++++ b/posix/fnmatch_loop.c
+@@ -15,6 +15,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
++
+ #include <stdint.h>
+ 
+ struct STRUCT
+@@ -54,10 +56,15 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+   const char *collseq = (const char *)
+     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+ # else
++#  if __OPTION_EGLIBC_LOCALE_CODE
+   const UCHAR *collseq = (const UCHAR *)
+     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+-# endif
+-#endif
++#   define COLLSEQ_BYTE_LOOKUP(ix) (collseq[(ix)])
++#  else
++#   define COLLSEQ_BYTE_LOOKUP(ix) (ix)
++#  endif /* __OPTION_EGLIBC_LOCALE_CODE */
++# endif /* WIDE_CHAR_VERSION */
++#endif /* _LIBC */
+ 
+   while ((c = *p++) != L('\0'))
+     {
+@@ -277,7 +284,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+ 		    /* Leave room for the null.  */
+ 		    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
+ 		    size_t c1 = 0;
+-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
++#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ 		    wctype_t wt;
+ #endif
+ 		    const CHAR *startp = p;
+@@ -307,7 +314,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+ 		      }
+ 		    str[c1] = L('\0');
+ 
+-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
++#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ 		    wt = IS_CHAR_CLASS (str);
+ 		    if (wt == 0)
+ 		      /* Invalid character class name.  */
+@@ -680,8 +687,10 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+ 			else
+ 			  lcollseq = __collseq_table_lookup (collseq, cold);
+ # else
+-			fcollseq = collseq[fn];
+-			lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
++			fcollseq = COLLSEQ_BYTE_LOOKUP (fn);
++			lcollseq = (is_seqval
++                                    ? cold
++                                    : COLLSEQ_BYTE_LOOKUP ((UCHAR) cold));
+ # endif
+ 
+ 			is_seqval = 0;
+@@ -857,7 +866,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+ 				    goto matched;
+ 				  }
+ # else
+-				hcollseq = collseq[cend];
++				hcollseq = COLLSEQ_BYTE_LOOKUP (cend);
+ # endif
+ 			      }
+ 
+diff --git a/posix/glob.c b/posix/glob.c
+index d65e55d..1ac00a1 100644
+--- a/posix/glob.c
++++ b/posix/glob.c
+@@ -25,6 +25,9 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stddef.h>
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
+ 
+ /* Outcomment the following line for production quality code.  */
+ /* #define NDEBUG 1 */
+@@ -607,6 +610,7 @@ glob (pattern, flags, errfunc, pglob)
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    home_dir = "c:/users/default"; /* poor default */
+ #  else
++#   if ! _LIBC || __OPTION_EGLIBC_GETLOGIN
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    {
+ 	      int success;
+@@ -623,19 +627,19 @@ glob (pattern, flags, errfunc, pglob)
+ 	      if (success)
+ 		{
+ 		  struct passwd *p;
+-#   if defined HAVE_GETPWNAM_R || defined _LIBC
++#    if defined HAVE_GETPWNAM_R || defined _LIBC
+ 		  long int pwbuflen = GETPW_R_SIZE_MAX ();
+ 		  char *pwtmpbuf;
+ 		  struct passwd pwbuf;
+ 		  int malloc_pwtmpbuf = 0;
+ 		  int save = errno;
+ 
+-#    ifndef _LIBC
++#     ifndef _LIBC
+ 		  if (pwbuflen == -1)
+ 		    /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
+ 		       Try a moderate value.  */
+ 		    pwbuflen = 1024;
+-#    endif
++#     endif
+ 		  if (__libc_use_alloca (alloca_used + pwbuflen))
+ 		    pwtmpbuf = alloca_account (pwbuflen, alloca_used);
+ 		  else
+@@ -682,9 +686,9 @@ glob (pattern, flags, errfunc, pglob)
+ 			}
+ 		      __set_errno (save);
+ 		    }
+-#   else
++#    else
+ 		  p = getpwnam (name);
+-#   endif
++#    endif
+ 		  if (p != NULL)
+ 		    {
+ 		      if (!malloc_pwtmpbuf)
+@@ -713,6 +717,7 @@ glob (pattern, flags, errfunc, pglob)
+ 		    }
+ 		}
+ 	    }
++#   endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    {
+ 	      if (flags & GLOB_TILDE_CHECK)
+diff --git a/posix/regcomp.c b/posix/regcomp.c
+index bf8aa16..6a41251 100644
+--- a/posix/regcomp.c
++++ b/posix/regcomp.c
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
+ #ifdef _LIBC
+ # include <locale/weight.h>
+@@ -309,7 +310,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+ {
+   re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+   int node_cnt;
+-  int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
++  int icase = (dfa_mb_cur_max (dfa) == 1 && (bufp->syntax & RE_ICASE));
+   for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
+     {
+       int node = init_state->nodes.elems[node_cnt];
+@@ -319,9 +320,9 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+ 	{
+ 	  re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
+ #ifdef RE_ENABLE_I18N
+-	  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
++	  if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
+ 	    {
+-	      unsigned char *buf = alloca (dfa->mb_cur_max), *p;
++	      unsigned char *buf = alloca (dfa_mb_cur_max (dfa)), *p;
+ 	      wchar_t wc;
+ 	      mbstate_t state;
+ 
+@@ -352,7 +353,11 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+ 		  re_set_fastmap (fastmap, icase, ch);
+ 	    }
+ 	}
+-#ifdef RE_ENABLE_I18N
++
++      /* When OPTION_EGLIBC_LOCALE_CODE is disabled, the current
++         locale is always C, which has no rules and no multi-byte
++         characters.  */
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+       else if (type == COMPLEX_BRACKET)
+ 	{
+ 	  re_charset_t *cset = dfa->nodes[node].opr.mbcset;
+@@ -380,7 +385,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+ 	     i.e. where we would not find an invalid sequence.  This only
+ 	     applies to multibyte character sets; for single byte character
+ 	     sets, the SIMPLE_BRACKET again suffices.  */
+-	  if (dfa->mb_cur_max > 1
++	  if (dfa_mb_cur_max (dfa) > 1
+ 	      && (cset->nchar_classes || cset->non_match || cset->nranges
+ # ifdef _LIBC
+ 		  || cset->nequiv_classes
+@@ -408,7 +413,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+ 		  memset (&state, '\0', sizeof (state));
+ 		  if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
+ 		    re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+-		  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
++		  if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
+ 		    {
+ 		      if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state)
+ 			  != (size_t) -1)
+@@ -417,7 +422,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+ 		}
+ 	    }
+ 	}
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+       else if (type == OP_PERIOD
+ #ifdef RE_ENABLE_I18N
+ 	       || type == OP_UTF8_PERIOD
+@@ -860,11 +865,15 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
+ 
+   dfa->mb_cur_max = MB_CUR_MAX;
+ #ifdef _LIBC
+-  if (dfa->mb_cur_max == 6
++  if (dfa_mb_cur_max (dfa) == 6
+       && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
+     dfa->is_utf8 = 1;
++# if __OPTION_EGLIBC_LOCALE_CODE
+   dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
+ 		       != 0);
++# else
++  dfa->map_notascii = 0;
++# endif
+ #else
+ # ifdef HAVE_LANGINFO_CODESET
+   codeset_name = nl_langinfo (CODESET);
+@@ -890,7 +899,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
+ #endif
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     {
+       if (dfa->is_utf8)
+ 	dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
+@@ -1788,7 +1797,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+   token->word_char = 0;
+ #ifdef RE_ENABLE_I18N
+   token->mb_partial = 0;
+-  if (input->mb_cur_max > 1 &&
++  if (string_mb_cur_max (input) > 1 &&
+       !re_string_first_byte (input, re_string_cur_idx (input)))
+     {
+       token->type = CHARACTER;
+@@ -1809,7 +1818,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+       token->opr.c = c2;
+       token->type = CHARACTER;
+ #ifdef RE_ENABLE_I18N
+-      if (input->mb_cur_max > 1)
++      if (string_mb_cur_max (input) > 1)
+ 	{
+ 	  wint_t wc = re_string_wchar_at (input,
+ 					  re_string_cur_idx (input) + 1);
+@@ -1923,7 +1932,7 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+ 
+   token->type = CHARACTER;
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1)
++  if (string_mb_cur_max (input) > 1)
+     {
+       wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
+       token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+@@ -2023,7 +2032,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+   token->opr.c = c;
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1 &&
++  if (string_mb_cur_max (input) > 1 &&
+       !re_string_first_byte (input, re_string_cur_idx (input)))
+     {
+       token->type = CHARACTER;
+@@ -2246,7 +2255,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
+ 	  return NULL;
+ 	}
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  while (!re_string_eoi (regexp)
+ 		 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
+@@ -2384,7 +2393,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
+ 	  *err = REG_ESPACE;
+ 	  return NULL;
+ 	}
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	dfa->has_mb_node = 1;
+       break;
+     case OP_WORD:
+@@ -2690,7 +2699,7 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
+        However, for !_LIBC we have no collation elements: if the
+        character set is single byte, the single byte character set
+        that we build below suffices.  parse_bracket_exp passes
+-       no MBCSET if dfa->mb_cur_max == 1.  */
++       no MBCSET if dfa_mb_cur_max (dfa) == 1.  */
+     if (mbcset)
+       {
+ 	/* Check the space of the arrays.  */
+@@ -2786,7 +2795,13 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 		   reg_syntax_t syntax, reg_errcode_t *err)
+ {
+ #ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+   const unsigned char *collseqmb;
++# define COLLSEQMB_LOOKUP(ix) (collseqmb[(ix)])
++#else
++# define COLLSEQMB_LOOKUP(ix) (ix)
++#endif
++
+   const char *collseqwc;
+   uint32_t nrules;
+   int32_t table_size;
+@@ -2834,18 +2849,20 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 	  if (MB_CUR_MAX == 1)
+ 	  */
+ 	  if (nrules == 0)
+-	    return collseqmb[br_elem->opr.ch];
++	    return COLLSEQMB_LOOKUP (br_elem->opr.ch);
+ 	  else
+ 	    {
+ 	      wint_t wc = __btowc (br_elem->opr.ch);
+ 	      return __collseq_table_lookup (collseqwc, wc);
+ 	    }
+ 	}
++#if __OPTION_EGLIBC_LOCALE_CODE
+       else if (br_elem->type == MB_CHAR)
+ 	{
+ 	  if (nrules != 0)
+ 	    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+ 	}
++#endif
+       else if (br_elem->type == COLL_SYM)
+ 	{
+ 	  size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+@@ -2876,11 +2893,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 		{
+ 		  /* No valid character.  Match it as a single byte
+ 		     character.  */
+-		  return collseqmb[br_elem->opr.name[0]];
++		  return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
+ 		}
+ 	    }
+ 	  else if (sym_name_len == 1)
+-	    return collseqmb[br_elem->opr.name[0]];
++	    return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
+ 	}
+       return UINT_MAX;
+     }
+@@ -2920,7 +2937,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 	 However, if we have no collation elements, and the character set
+ 	 is single byte, the single byte character set that we
+ 	 build below suffices. */
+-      if (nrules > 0 || dfa->mb_cur_max > 1)
++      if (nrules > 0 || dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  /* Check the space of the arrays.  */
+ 	  if (BE (*range_alloc == mbcset->nranges, 0))
+@@ -2957,7 +2974,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 	  if (MB_CUR_MAX == 1)
+ 	  */
+ 	  if (nrules == 0)
+-	    ch_collseq = collseqmb[ch];
++	    ch_collseq = COLLSEQMB_LOOKUP (ch);
+ 	  else
+ 	    ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+ 	  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+@@ -3035,7 +3052,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+   re_bitset_ptr_t sbcset;
+ #ifdef RE_ENABLE_I18N
+   re_charset_t *mbcset;
+-  int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
++  int coll_sym_alloc = 0, range_alloc = 0;
++#if __OPTION_EGLIBC_LOCALE_CODE
++  int mbchar_alloc = 0;
++#endif
+   int equiv_class_alloc = 0, char_class_alloc = 0;
+ #endif /* not RE_ENABLE_I18N */
+   int non_match = 0;
+@@ -3043,9 +3063,15 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+   int token_len;
+   int first_round = 1;
+ #ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+   collseqmb = (const unsigned char *)
+     _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+   nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++#else
++  /* This is true when OPTION_EGLIBC_LOCALE_CODE is disabled, but the
++     compiler can't figure that out.  */
++  nrules = 0;
++#endif
+   if (nrules)
+     {
+       /*
+@@ -3175,7 +3201,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ #else
+ # ifdef RE_ENABLE_I18N
+ 	  *err = build_range_exp (sbcset,
+-				  dfa->mb_cur_max > 1 ? mbcset : NULL,
++				  dfa_mb_cur_max (dfa) > 1 ? mbcset : NULL,
+ 				  &range_alloc, &start_elem, &end_elem);
+ # else
+ 	  *err = build_range_exp (sbcset, &start_elem, &end_elem);
+@@ -3191,7 +3217,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 	    case SB_CHAR:
+ 	      bitset_set (sbcset, start_elem.opr.ch);
+ 	      break;
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+ 	    case MB_CHAR:
+ 	      /* Check whether the array has enough space.  */
+ 	      if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+@@ -3209,7 +3235,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 		}
+ 	      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
+ 	      break;
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+ 	    case EQUIV_CLASS:
+ 	      *err = build_equiv_class (sbcset,
+ #ifdef RE_ENABLE_I18N
+@@ -3259,11 +3285,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+ 
+ #ifdef RE_ENABLE_I18N
+   /* Ensure only single byte characters are set.  */
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     bitset_mask (sbcset, dfa->sb_char);
+ 
+   if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
+-      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
++      || mbcset->nranges || (dfa_mb_cur_max (dfa) > 1 && (mbcset->nchar_classes
+ 						     || mbcset->non_match)))
+     {
+       bin_tree_t *mbc_tree;
+@@ -3332,7 +3358,7 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
+ 		       re_token_t *token, int token_len, re_dfa_t *dfa,
+ 		       reg_syntax_t syntax, int accept_hyphen)
+ {
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+   int cur_char_size;
+   cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
+   if (cur_char_size > 1)
+@@ -3342,7 +3368,7 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
+       re_string_skip_bytes (regexp, cur_char_size);
+       return REG_NOERROR;
+     }
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+   re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+   if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+       || token->type == OP_OPEN_EQUIV_CLASS)
+@@ -3422,7 +3448,9 @@ build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
+ build_equiv_class (bitset_t sbcset, const unsigned char *name)
+ #endif /* not RE_ENABLE_I18N */
+ {
+-#ifdef _LIBC
++  /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C locale
++     is supported; it has no collation rules.  */
++#if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+   uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+   if (nrules != 0)
+     {
+@@ -3492,7 +3520,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
+       mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
+     }
+   else
+-#endif /* _LIBC */
++#endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+     {
+       if (BE (strlen ((const char *) name) != 1, 0))
+ 	return REG_ECOLLATE;
+@@ -3526,7 +3554,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+       && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
+     name = "alpha";
+ 
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+   /* Check the space of the arrays.  */
+   if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+     {
+@@ -3542,7 +3570,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+       *char_class_alloc = new_char_class_alloc;
+     }
+   mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+ 
+ #define BUILD_CHARCLASS_LOOP(ctype_func)	\
+   do {						\
+@@ -3653,7 +3681,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
+ 
+ #ifdef RE_ENABLE_I18N
+   /* Ensure only single byte characters are set.  */
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     bitset_mask (sbcset, dfa->sb_char);
+ #endif
+ 
+@@ -3665,7 +3693,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
+     goto build_word_op_espace;
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     {
+       bin_tree_t *mbc_tree;
+       /* Build a tree for complex bracket.  */
+diff --git a/posix/regex.h b/posix/regex.h
+index 5b1981e..2941f94 100644
+--- a/posix/regex.h
++++ b/posix/regex.h
+@@ -21,6 +21,7 @@
+ #define _REGEX_H 1
+ 
+ #include <sys/types.h>
++#include <gnu/option-groups.h>
+ 
+ /* Allow the use in C++ code.  */
+ #ifdef __cplusplus
+@@ -156,6 +157,8 @@ typedef unsigned long int reg_syntax_t;
+    treated as 'a\{1'.  */
+ # define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+ 
++/* EGLIBC: Old regex implementation does not support these.  */
++# if __OPTION_POSIX_REGEXP_GLIBC
+ /* If this bit is set, then ignore case when matching.
+    If not set, then case is significant.  */
+ # define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+@@ -172,6 +175,7 @@ typedef unsigned long int reg_syntax_t;
+ /* If this bit is set, then no_sub will be set to 1 during
+    re_compile_pattern.  */
+ # define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
++# endif /* __OPTION_POSIX_REGEXP_GLIBC */
+ #endif
+ 
+ /* This global variable defines the particular regexp syntax to use (for
+@@ -231,8 +235,13 @@ extern reg_syntax_t re_syntax_options;
+   (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
+    | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+ 
++#if __OPTION_POSIX_REGEXP_GLIBC
+ #define RE_SYNTAX_POSIX_BASIC						\
+   (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
++#else
++#define RE_SYNTAX_POSIX_BASIC						\
++  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
++#endif
+ 
+ /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+    RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+@@ -298,9 +307,11 @@ extern reg_syntax_t re_syntax_options;
+ /* Like REG_NOTBOL, except for the end-of-line.  */
+ #define REG_NOTEOL (1 << 1)
+ 
++#if __OPTION_POSIX_REGEXP_GLIBC
+ /* Use PMATCH[0] to delimit the start and end of the search in the
+    buffer.  */
+ #define REG_STARTEND (1 << 2)
++#endif
+ 
+ 
+ /* If any error codes are removed, changed, or added, update the
+diff --git a/posix/regex_internal.c b/posix/regex_internal.c
+index 8597d7e..d53b2a8 100644
+--- a/posix/regex_internal.c
++++ b/posix/regex_internal.c
+@@ -43,8 +43,8 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
+   int init_buf_len;
+ 
+   /* Ensure at least one character fits into the buffers.  */
+-  if (init_len < dfa->mb_cur_max)
+-    init_len = dfa->mb_cur_max;
++  if (init_len < dfa_mb_cur_max (dfa))
++    init_len = dfa_mb_cur_max (dfa);
+   init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
+   re_string_construct_common (str, len, pstr, trans, icase, dfa);
+ 
+@@ -55,7 +55,7 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
+   pstr->word_char = dfa->word_char;
+   pstr->word_ops_used = dfa->word_ops_used;
+   pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+-  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
++  pstr->valid_len = (pstr->mbs_allocated || dfa_mb_cur_max (dfa) > 1) ? 0 : len;
+   pstr->valid_raw_len = pstr->valid_len;
+   return REG_NOERROR;
+ }
+@@ -82,7 +82,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
+   if (icase)
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  while (1)
+ 	    {
+@@ -91,7 +91,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
+ 		return ret;
+ 	      if (pstr->valid_raw_len >= len)
+ 		break;
+-	      if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
++	      if (pstr->bufs_len > pstr->valid_len + dfa_mb_cur_max (dfa))
+ 		break;
+ 	      ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+ 	      if (BE (ret != REG_NOERROR, 0))
+@@ -105,7 +105,7 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
+   else
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	build_wcs_buffer (pstr);
+       else
+ #endif /* RE_ENABLE_I18N  */
+@@ -130,7 +130,7 @@ internal_function __attribute_warn_unused_result__
+ re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
+ {
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1)
++  if (string_mb_cur_max (pstr) > 1)
+     {
+       wint_t *new_wcs;
+ 
+@@ -177,7 +177,7 @@ re_string_construct_common (const char *str, int len, re_string_t *pstr,
+   pstr->trans = trans;
+   pstr->icase = icase ? 1 : 0;
+   pstr->mbs_allocated = (trans != NULL || icase);
+-  pstr->mb_cur_max = dfa->mb_cur_max;
++  pstr->mb_cur_max = dfa_mb_cur_max (dfa);
+   pstr->is_utf8 = dfa->is_utf8;
+   pstr->map_notascii = dfa->map_notascii;
+   pstr->stop = pstr->len;
+@@ -203,7 +203,7 @@ build_wcs_buffer (re_string_t *pstr)
+ {
+ #ifdef _LIBC
+   unsigned char buf[MB_LEN_MAX];
+-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
++  assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
+ #else
+   unsigned char buf[64];
+ #endif
+@@ -226,7 +226,7 @@ build_wcs_buffer (re_string_t *pstr)
+ 	{
+ 	  int i, ch;
+ 
+-	  for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
++	  for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
+ 	    {
+ 	      ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
+ 	      buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
+@@ -275,7 +275,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
+   size_t mbclen;
+ #ifdef _LIBC
+   char buf[MB_LEN_MAX];
+-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
++  assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
+ #else
+   char buf[64];
+ #endif
+@@ -369,7 +369,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
+ 	  {
+ 	    int i, ch;
+ 
+-	    for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
++	    for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
+ 	      {
+ 		ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
+ 		buf[i] = pstr->trans[ch];
+@@ -567,8 +567,9 @@ re_string_translate_buffer (re_string_t *pstr)
+ }
+ 
+ /* This function re-construct the buffers.
+-   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+-   convert to upper case in case of REG_ICASE, apply translation.  */
++   Concretely, convert to wide character in case of
++   string_mb_cur_max (pstr) > 1, convert to upper case in case of
++   REG_ICASE, apply translation.  */
+ 
+ static reg_errcode_t
+ internal_function __attribute_warn_unused_result__
+@@ -579,7 +580,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
+     {
+       /* Reset buffer.  */
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+ #endif /* RE_ENABLE_I18N */
+       pstr->len = pstr->raw_len;
+@@ -670,7 +671,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
+ 	      pstr->tip_context = re_string_context_at (pstr, offset - 1,
+ 							eflags);
+ #ifdef RE_ENABLE_I18N
+-	      if (pstr->mb_cur_max > 1)
++	      if (string_mb_cur_max (pstr) > 1)
+ 		memmove (pstr->wcs, pstr->wcs + offset,
+ 			 (pstr->valid_len - offset) * sizeof (wint_t));
+ #endif /* RE_ENABLE_I18N */
+@@ -699,7 +700,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
+ #endif
+ 	  pstr->valid_len = 0;
+ #ifdef RE_ENABLE_I18N
+-	  if (pstr->mb_cur_max > 1)
++	  if (string_mb_cur_max (pstr) > 1)
+ 	    {
+ 	      int wcs_idx;
+ 	      wint_t wc = WEOF;
+@@ -711,7 +712,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
+ 		  /* Special case UTF-8.  Multi-byte chars start with any
+ 		     byte other than 0x80 - 0xbf.  */
+ 		  raw = pstr->raw_mbs + pstr->raw_mbs_idx;
+-		  end = raw + (offset - pstr->mb_cur_max);
++		  end = raw + (offset - string_mb_cur_max (pstr));
+ 		  if (end < pstr->raw_mbs)
+ 		    end = pstr->raw_mbs;
+ 		  p = raw + offset - 1;
+@@ -803,7 +804,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
+ 
+   /* Then build the buffers.  */
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1)
++  if (string_mb_cur_max (pstr) > 1)
+     {
+       if (pstr->icase)
+ 	{
+@@ -841,7 +842,7 @@ re_string_peek_byte_case (const re_string_t *pstr, int idx)
+     return re_string_peek_byte (pstr, idx);
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1
++  if (string_mb_cur_max (pstr) > 1
+       && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
+     return re_string_peek_byte (pstr, idx);
+ #endif
+@@ -930,7 +931,7 @@ re_string_context_at (const re_string_t *input, int idx, int eflags)
+     return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+ 	    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1)
++  if (string_mb_cur_max (input) > 1)
+     {
+       wint_t wc;
+       int wc_idx = idx;
+@@ -1444,7 +1445,7 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
+   dfa->nodes[dfa->nodes_len].constraint = 0;
+ #ifdef RE_ENABLE_I18N
+   dfa->nodes[dfa->nodes_len].accept_mb =
+-    (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
++    (type == OP_PERIOD && dfa_mb_cur_max (dfa) > 1) || type == COMPLEX_BRACKET;
+ #endif
+   dfa->nexts[dfa->nodes_len] = -1;
+   re_node_set_init_empty (dfa->edests + dfa->nodes_len);
+diff --git a/posix/regex_internal.h b/posix/regex_internal.h
+index 154e969..c43909a 100644
+--- a/posix/regex_internal.h
++++ b/posix/regex_internal.h
+@@ -26,6 +26,10 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
+ # include <langinfo.h>
+ #endif
+@@ -369,6 +373,13 @@ struct re_string_t
+ };
+ typedef struct re_string_t re_string_t;
+ 
++/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
++   help the compiler make use of that fact.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define string_mb_cur_max(str) ((str)->mb_cur_max + 0)
++#else
++# define string_mb_cur_max(str) (1)
++#endif
+ 
+ struct re_dfa_t;
+ typedef struct re_dfa_t re_dfa_t;
+@@ -654,6 +665,14 @@ struct re_dfa_t
+   __libc_lock_define (, lock)
+ };
+ 
++/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
++   help the compiler make use of that fact.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define dfa_mb_cur_max(dfa) ((dfa)->mb_cur_max + 0)
++#else
++# define dfa_mb_cur_max(dfa) (1)
++#endif
++
+ #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+ #define re_node_set_remove(set,id) \
+   (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+@@ -714,7 +733,7 @@ internal_function __attribute__ ((pure, unused))
+ re_string_char_size_at (const re_string_t *pstr, int idx)
+ {
+   int byte_idx;
+-  if (pstr->mb_cur_max == 1)
++  if (string_mb_cur_max (pstr) == 1)
+     return 1;
+   for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
+     if (pstr->wcs[idx + byte_idx] != WEOF)
+@@ -726,7 +745,7 @@ static wint_t
+ internal_function __attribute__ ((pure, unused))
+ re_string_wchar_at (const re_string_t *pstr, int idx)
+ {
+-  if (pstr->mb_cur_max == 1)
++  if (string_mb_cur_max (pstr) == 1)
+     return (wint_t) pstr->mbs[idx];
+   return (wint_t) pstr->wcs[idx];
+ }
+diff --git a/posix/regexec-compat.c b/posix/regexec-compat.c
+new file mode 100644
+index 0000000..0f9b7c7
+--- /dev/null
++++ b/posix/regexec-compat.c
+@@ -0,0 +1,39 @@
++/* Extended regular expression matching and search library.
++   Copyright (C) 2008 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
++
++   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.  */
++
++#ifdef _LIBC
++# include <shlib-compat.h>
++versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
++
++# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
++__typeof__ (__regexec) __compat_regexec;
++
++int
++attribute_compat_text_section
++__compat_regexec (const regex_t *__restrict preg,
++		  const char *__restrict string, size_t nmatch,
++		  regmatch_t pmatch[], int eflags)
++{
++  return regexec (preg, string, nmatch, pmatch,
++		  eflags & (REG_NOTBOL | REG_NOTEOL));
++}
++compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
++# endif
++#endif
+diff --git a/posix/regexec.c b/posix/regexec.c
+index 70cd606..e3b49e4 100644
+--- a/posix/regexec.c
++++ b/posix/regexec.c
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
+ static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+ 				     int n) internal_function;
+@@ -186,11 +187,11 @@ static int build_trtable (const re_dfa_t *dfa,
+ static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+ 				    const re_string_t *input, int idx)
+      internal_function;
+-# ifdef _LIBC
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+ static unsigned int find_collation_sequence_value (const unsigned char *mbs,
+ 						   size_t name_len)
+      internal_function;
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ #endif /* RE_ENABLE_I18N */
+ static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
+ 				       const re_dfastate_t *state,
+@@ -255,25 +256,9 @@ regexec (preg, string, nmatch, pmatch, eflags)
+   return err != REG_NOERROR;
+ }
+ 
+-#ifdef _LIBC
+-# include <shlib-compat.h>
+-versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
+-
+-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+-__typeof__ (__regexec) __compat_regexec;
+-
+-int
+-attribute_compat_text_section
+-__compat_regexec (const regex_t *__restrict preg,
+-		  const char *__restrict string, size_t nmatch,
+-		  regmatch_t pmatch[], int eflags)
+-{
+-  return regexec (preg, string, nmatch, pmatch,
+-		  eflags & (REG_NOTBOL | REG_NOTEOL));
+-}
+-compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+-# endif
+-#endif
++/* EGLIBC: The code that used to be here was move to a separate file
++   so that it can be shared with xregex.c.  */
++#include "regexec-compat.c"
+ 
+ /* Entry points for GNU code.  */
+ 
+@@ -728,7 +713,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
+   incr = (range < 0) ? -1 : 1;
+   left_lim = (range < 0) ? start + range : start;
+   right_lim = (range < 0) ? start : start + range;
+-  sb = dfa->mb_cur_max == 1;
++  sb = dfa_mb_cur_max (dfa) == 1;
+   match_kind =
+     (fastmap
+      ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+@@ -3448,7 +3433,7 @@ out_free:
+ 	  if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+ 	    goto out_free;
+ 
+-	  if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
++	  if (dest_states[i] != dest_states_word[i] && dfa_mb_cur_max (dfa) > 1)
+ 	    need_word_trtable = 1;
+ 
+ 	  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+@@ -3590,7 +3575,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+       else if (type == OP_PERIOD)
+ 	{
+ #ifdef RE_ENABLE_I18N
+-	  if (dfa->mb_cur_max > 1)
++	  if (dfa_mb_cur_max (dfa) > 1)
+ 	    bitset_merge (accepts, dfa->sb_char);
+ 	  else
+ #endif
+@@ -3641,7 +3626,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+ 		  continue;
+ 		}
+ #ifdef RE_ENABLE_I18N
+-	      if (dfa->mb_cur_max > 1)
++	      if (dfa_mb_cur_max (dfa) > 1)
+ 		for (j = 0; j < BITSET_WORDS; ++j)
+ 		  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
+ 	      else
+@@ -3660,7 +3645,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+ 		  continue;
+ 		}
+ #ifdef RE_ENABLE_I18N
+-	      if (dfa->mb_cur_max > 1)
++	      if (dfa_mb_cur_max (dfa) > 1)
+ 		for (j = 0; j < BITSET_WORDS; ++j)
+ 		  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
+ 	      else
+@@ -3836,12 +3821,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+   if (node->type == COMPLEX_BRACKET)
+     {
+       const re_charset_t *cset = node->opr.mbcset;
+-# ifdef _LIBC
+-      const unsigned char *pin
+-	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
+-      int j;
+-      uint32_t nrules;
+-# endif /* _LIBC */
+       int match_len = 0;
+       wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
+ 		    ? re_string_wchar_at (input, str_idx) : 0);
+@@ -3853,6 +3832,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+ 	    match_len = char_len;
+ 	    goto check_node_accept_bytes_match;
+ 	  }
++#if __OPTION_EGLIBC_LOCALE_CODE
+       /* match with character_class?  */
+       for (i = 0; i < cset->nchar_classes; ++i)
+ 	{
+@@ -3863,14 +3843,22 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+ 	      goto check_node_accept_bytes_match;
+ 	    }
+ 	}
++#endif
++
++      /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C
++         locale is supported; it has no collation rules.  */
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
++      const unsigned char *pin
++	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
++      int j;
++      uint32_t nrules;
+ 
+-# ifdef _LIBC
+       nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+       if (nrules != 0)
+ 	{
+ 	  unsigned int in_collseq = 0;
+ 	  const int32_t *table, *indirect;
+-	  const unsigned char *weights, *extra;
++	  const unsigned char *weights, *extra = NULL;
+ 	  const char *collseqwc;
+ 
+ 	  /* match with collating_symbol?  */
+@@ -3955,8 +3943,12 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+ 	    }
+ 	}
+       else
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ 	{
++          /* In the _LIBC version, if OPTION_EGLIBC_LOCALE_CODE is
++             disabled, there can be no multibyte range endpoints, and
++             cset->nranges is always zero.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	  /* match with range expression?  */
+ #if __GNUC__ >= 2
+ 	  wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
+@@ -3975,6 +3967,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+ 		  goto check_node_accept_bytes_match;
+ 		}
+ 	    }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 	}
+     check_node_accept_bytes_match:
+       if (!cset->non_match)
+@@ -3990,7 +3983,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+   return 0;
+ }
+ 
+-# ifdef _LIBC
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+ static unsigned int
+ internal_function
+ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
+@@ -4048,7 +4041,7 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
+       return UINT_MAX;
+     }
+ }
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ #endif /* RE_ENABLE_I18N */
+ 
+ /* Check whether the node accepts the byte which is IDX-th
+@@ -4139,7 +4132,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
+   if (pstr->icase)
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	{
+ 	  ret = build_wcs_upper_buffer (pstr);
+ 	  if (BE (ret != REG_NOERROR, 0))
+@@ -4152,7 +4145,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
+   else
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	build_wcs_buffer (pstr);
+       else
+ #endif /* RE_ENABLE_I18N  */
+diff --git a/posix/xregex.c b/posix/xregex.c
+new file mode 100644
+index 0000000..d3f7ace
+--- /dev/null
++++ b/posix/xregex.c
+@@ -0,0 +1,8215 @@
++/* Extended regular expression matching and search library,
++   version 0.12.
++   (Implements POSIX draft P1003.2/D11.2, except for some of the
++   internationalization features.)
++
++   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
++   2002, 2005 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   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., 51 Franklin Street, Fifth Floor, Boston, MA
++   02110-1301 USA.  */
++
++/* AIX requires this to be the first thing in the file. */
++#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC
++  #pragma alloca
++#endif
++
++#undef	_GNU_SOURCE
++#define _GNU_SOURCE
++
++#ifndef INSIDE_RECURSION
++# ifdef HAVE_CONFIG_H
++#  include <config.h>
++# endif
++#endif
++
++/*#include <ansidecl.h>*/
++
++
++#ifndef INSIDE_RECURSION
++
++# if defined STDC_HEADERS && !defined emacs
++#  include <stddef.h>
++# else
++/* We need this for `regex.h', and perhaps for the Emacs include files.  */
++#  include <sys/types.h>
++# endif
++
++# if (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_BTOWC)
++#  define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
++# else
++#  define WIDE_CHAR_SUPPORT 0
++# endif
++/* For platform which support the ISO C amendement 1 functionality we
++   support user defined character classes.  */
++# if WIDE_CHAR_SUPPORT
++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
++#  include <wchar.h>
++#  include <wctype.h>
++# endif
++
++# ifdef _LIBC
++/* We have to keep the namespace clean.  */
++#  define regfree(preg) __regfree (preg)
++#  define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
++#  define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
++#  define regerror(errcode, preg, errbuf, errbuf_size) \
++	__regerror(errcode, preg, errbuf, errbuf_size)
++#  define re_set_registers(bu, re, nu, st, en) \
++	__re_set_registers (bu, re, nu, st, en)
++#  define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
++	__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
++#  define re_match(bufp, string, size, pos, regs) \
++	__re_match (bufp, string, size, pos, regs)
++#  define re_search(bufp, string, size, startpos, range, regs) \
++	__re_search (bufp, string, size, startpos, range, regs)
++#  define re_compile_pattern(pattern, length, bufp) \
++	__re_compile_pattern (pattern, length, bufp)
++#  define re_set_syntax(syntax) __re_set_syntax (syntax)
++#  define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
++	__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
++#  define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
++
++#  define btowc __btowc
++
++/* We are also using some library internals.  */
++#  include <locale/localeinfo.h>
++#  include <locale/elem-hash.h>
++#  include <langinfo.h>
++#  include <locale/coll-lookup.h>
++# endif
++
++/* This is for other GNU distributions with internationalized messages.  */
++# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
++#  include <libintl.h>
++#  ifdef _LIBC
++#   undef gettext
++#   define gettext(msgid) __dcgettext ("libc", msgid, LC_MESSAGES)
++#  endif
++# else
++#  define gettext(msgid) (msgid)
++# endif
++
++# ifndef gettext_noop
++/* This define is so xgettext can find the internationalizable
++   strings.  */
++#  define gettext_noop(String) String
++# endif
++
++/* The `emacs' switch turns on certain matching commands
++   that make sense only in Emacs. */
++# ifdef emacs
++
++#  include "lisp.h"
++#  include "buffer.h"
++#  include "syntax.h"
++
++# else  /* not emacs */
++
++/* If we are not linking with Emacs proper,
++   we can't use the relocating allocator
++   even if config.h says that we can.  */
++#  undef REL_ALLOC
++
++#  if defined STDC_HEADERS || defined _LIBC
++#   include <stdlib.h>
++#  else
++char *malloc ();
++char *realloc ();
++#  endif
++
++/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
++   If nothing else has been done, use the method below.  */
++#  ifdef INHIBIT_STRING_HEADER
++#   if !(defined HAVE_BZERO && defined HAVE_BCOPY)
++#    if !defined bzero && !defined bcopy
++#     undef INHIBIT_STRING_HEADER
++#    endif
++#   endif
++#  endif
++
++/* This is the normal way of making sure we have a bcopy and a bzero.
++   This is used in most programs--a few other programs avoid this
++   by defining INHIBIT_STRING_HEADER.  */
++#  ifndef INHIBIT_STRING_HEADER
++#   if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
++#    include <string.h>
++#    ifndef bzero
++#     ifndef _LIBC
++#      define bzero(s, n)	(memset (s, '\0', n), (s))
++#     else
++#      define bzero(s, n)	__bzero (s, n)
++#     endif
++#    endif
++#   else
++#    include <strings.h>
++#    ifndef memcmp
++#     define memcmp(s1, s2, n)	bcmp (s1, s2, n)
++#    endif
++#    ifndef memcpy
++#     define memcpy(d, s, n)	(bcopy (s, d, n), (d))
++#    endif
++#   endif
++#  endif
++
++/* Define the syntax stuff for \<, \>, etc.  */
++
++/* This must be nonzero for the wordchar and notwordchar pattern
++   commands in re_match_2.  */
++#  ifndef Sword
++#   define Sword 1
++#  endif
++
++#  ifdef SWITCH_ENUM_BUG
++#   define SWITCH_ENUM_CAST(x) ((int)(x))
++#  else
++#   define SWITCH_ENUM_CAST(x) (x)
++#  endif
++
++# endif /* not emacs */
++
++# if defined _LIBC || HAVE_LIMITS_H
++#  include <limits.h>
++# endif
++
++# ifndef MB_LEN_MAX
++#  define MB_LEN_MAX 1
++# endif
++\f
++/* Get the interface, including the syntax bits.  */
++# include "regex.h"
++
++/* isalpha etc. are used for the character classes.  */
++# include <ctype.h>
++
++/* Jim Meyering writes:
++
++   "... Some ctype macros are valid only for character codes that
++   isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
++   using /bin/cc or gcc but without giving an ansi option).  So, all
++   ctype uses should be through macros like ISPRINT...  If
++   STDC_HEADERS is defined, then autoconf has verified that the ctype
++   macros don't need to be guarded with references to isascii. ...
++   Defining isascii to 1 should let any compiler worth its salt
++   eliminate the && through constant folding."
++   Solaris defines some of these symbols so we must undefine them first.  */
++
++# undef ISASCII
++# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
++#  define ISASCII(c) 1
++# else
++#  define ISASCII(c) isascii(c)
++# endif
++
++# ifdef isblank
++#  define ISBLANK(c) (ISASCII (c) && isblank (c))
++# else
++#  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
++# endif
++# ifdef isgraph
++#  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
++# else
++#  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
++# endif
++
++# undef ISPRINT
++# define ISPRINT(c) (ISASCII (c) && isprint (c))
++# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
++# define ISALNUM(c) (ISASCII (c) && isalnum (c))
++# define ISALPHA(c) (ISASCII (c) && isalpha (c))
++# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
++# define ISLOWER(c) (ISASCII (c) && islower (c))
++# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
++# define ISSPACE(c) (ISASCII (c) && isspace (c))
++# define ISUPPER(c) (ISASCII (c) && isupper (c))
++# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
++
++# ifdef _tolower
++#  define TOLOWER(c) _tolower(c)
++# else
++#  define TOLOWER(c) tolower(c)
++# endif
++
++# ifndef NULL
++#  define NULL (void *)0
++# endif
++
++/* We remove any previous definition of `SIGN_EXTEND_CHAR',
++   since ours (we hope) works properly with all combinations of
++   machines, compilers, `char' and `unsigned char' argument types.
++   (Per Bothner suggested the basic approach.)  */
++# undef SIGN_EXTEND_CHAR
++# if __STDC__
++#  define SIGN_EXTEND_CHAR(c) ((signed char) (c))
++# else  /* not __STDC__ */
++/* As in Harbison and Steele.  */
++#  define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
++# endif
++\f
++# ifndef emacs
++/* How many characters in the character set.  */
++#  define CHAR_SET_SIZE 256
++
++#  ifdef SYNTAX_TABLE
++
++extern char *re_syntax_table;
++
++#  else /* not SYNTAX_TABLE */
++
++static char re_syntax_table[CHAR_SET_SIZE];
++
++static void init_syntax_once (void);
++
++static void
++init_syntax_once (void)
++{
++   register int c;
++   static int done = 0;
++
++   if (done)
++     return;
++   bzero (re_syntax_table, sizeof re_syntax_table);
++
++   for (c = 0; c < CHAR_SET_SIZE; ++c)
++     if (ISALNUM (c))
++	re_syntax_table[c] = Sword;
++
++   re_syntax_table['_'] = Sword;
++
++   done = 1;
++}
++
++#  endif /* not SYNTAX_TABLE */
++
++#  define SYNTAX(c) re_syntax_table[(unsigned char) (c)]
++
++# endif /* emacs */
++\f
++/* Integer type for pointers.  */
++# if !defined _LIBC && !defined HAVE_UINTPTR_T
++typedef unsigned long int uintptr_t;
++# endif
++
++/* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
++   use `alloca' instead of `malloc'.  This is because using malloc in
++   re_search* or re_match* could cause memory leaks when C-g is used in
++   Emacs; also, malloc is slower and causes storage fragmentation.  On
++   the other hand, malloc is more portable, and easier to debug.
++
++   Because we sometimes use alloca, some routines have to be macros,
++   not functions -- `alloca'-allocated space disappears at the end of the
++   function it is called in.  */
++
++# ifdef REGEX_MALLOC
++
++#  define REGEX_ALLOCATE malloc
++#  define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
++#  define REGEX_FREE free
++
++# else /* not REGEX_MALLOC  */
++
++/* Emacs already defines alloca, sometimes.  */
++#  ifndef alloca
++
++/* Make alloca work the best possible way.  */
++#   ifdef __GNUC__
++#    define alloca __builtin_alloca
++#   else /* not __GNUC__ */
++#    if HAVE_ALLOCA_H
++#     include <alloca.h>
++#    endif /* HAVE_ALLOCA_H */
++#   endif /* not __GNUC__ */
++
++#  endif /* not alloca */
++
++#  define REGEX_ALLOCATE alloca
++
++/* Assumes a `char *destination' variable.  */
++#  define REGEX_REALLOCATE(source, osize, nsize)			\
++  (destination = (char *) alloca (nsize),				\
++   memcpy (destination, source, osize))
++
++/* No need to do anything to free, after alloca.  */
++#  define REGEX_FREE(arg) ((void)0) /* Do nothing!  But inhibit gcc warning.  */
++
++# endif /* not REGEX_MALLOC */
++
++/* Define how to allocate the failure stack.  */
++
++# if defined REL_ALLOC && defined REGEX_MALLOC
++
++#  define REGEX_ALLOCATE_STACK(size)				\
++  r_alloc (&failure_stack_ptr, (size))
++#  define REGEX_REALLOCATE_STACK(source, osize, nsize)		\
++  r_re_alloc (&failure_stack_ptr, (nsize))
++#  define REGEX_FREE_STACK(ptr)					\
++  r_alloc_free (&failure_stack_ptr)
++
++# else /* not using relocating allocator */
++
++#  ifdef REGEX_MALLOC
++
++#   define REGEX_ALLOCATE_STACK malloc
++#   define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
++#   define REGEX_FREE_STACK free
++
++#  else /* not REGEX_MALLOC */
++
++#   define REGEX_ALLOCATE_STACK alloca
++
++#   define REGEX_REALLOCATE_STACK(source, osize, nsize)			\
++   REGEX_REALLOCATE (source, osize, nsize)
++/* No need to explicitly free anything.  */
++#   define REGEX_FREE_STACK(arg)
++
++#  endif /* not REGEX_MALLOC */
++# endif /* not using relocating allocator */
++
++
++/* True if `size1' is non-NULL and PTR is pointing anywhere inside
++   `string1' or just past its end.  This works if PTR is NULL, which is
++   a good thing.  */
++# define FIRST_STRING_P(ptr) 					\
++  (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
++
++/* (Re)Allocate N items of type T using malloc, or fail.  */
++# define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
++# define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
++# define RETALLOC_IF(addr, n, t) \
++  if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
++# define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
++
++# define BYTEWIDTH 8 /* In bits.  */
++
++# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
++
++# undef MAX
++# undef MIN
++# define MAX(a, b) ((a) > (b) ? (a) : (b))
++# define MIN(a, b) ((a) < (b) ? (a) : (b))
++
++typedef char boolean;
++# define false 0
++# define true 1
++
++static reg_errcode_t byte_regex_compile (const char *pattern, size_t size,
++                                         reg_syntax_t syntax,
++                                         struct re_pattern_buffer *bufp);
++
++static int byte_re_match_2_internal (struct re_pattern_buffer *bufp,
++                                     const char *string1, int size1,
++                                     const char *string2, int size2,
++                                     int pos,
++                                     struct re_registers *regs,
++                                     int stop);
++static int byte_re_search_2 (struct re_pattern_buffer *bufp,
++                             const char *string1, int size1,
++                             const char *string2, int size2,
++                             int startpos, int range,
++                             struct re_registers *regs, int stop);
++static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp);
++
++#ifdef MBS_SUPPORT
++static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size,
++                                        reg_syntax_t syntax,
++                                        struct re_pattern_buffer *bufp);
++
++
++static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
++                                    const char *cstring1, int csize1,
++                                    const char *cstring2, int csize2,
++                                    int pos,
++                                    struct re_registers *regs,
++                                    int stop,
++                                    wchar_t *string1, int size1,
++                                    wchar_t *string2, int size2,
++                                    int *mbs_offset1, int *mbs_offset2);
++static int wcs_re_search_2 (struct re_pattern_buffer *bufp,
++                            const char *string1, int size1,
++                            const char *string2, int size2,
++                            int startpos, int range,
++                            struct re_registers *regs, int stop);
++static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp);
++#endif
++\f
++/* These are the command codes that appear in compiled regular
++   expressions.  Some opcodes are followed by argument bytes.  A
++   command code can specify any interpretation whatsoever for its
++   arguments.  Zero bytes may appear in the compiled regular expression.  */
++
++typedef enum
++{
++  no_op = 0,
++
++  /* Succeed right away--no more backtracking.  */
++  succeed,
++
++        /* Followed by one byte giving n, then by n literal bytes.  */
++  exactn,
++
++# ifdef MBS_SUPPORT
++	/* Same as exactn, but contains binary data.  */
++  exactn_bin,
++# endif
++
++        /* Matches any (more or less) character.  */
++  anychar,
++
++        /* Matches any one char belonging to specified set.  First
++           following byte is number of bitmap bytes.  Then come bytes
++           for a bitmap saying which chars are in.  Bits in each byte
++           are ordered low-bit-first.  A character is in the set if its
++           bit is 1.  A character too large to have a bit in the map is
++           automatically not in the set.  */
++        /* ifdef MBS_SUPPORT, following element is length of character
++	   classes, length of collating symbols, length of equivalence
++	   classes, length of character ranges, and length of characters.
++	   Next, character class element, collating symbols elements,
++	   equivalence class elements, range elements, and character
++	   elements follow.
++	   See regex_compile function.  */
++  charset,
++
++        /* Same parameters as charset, but match any character that is
++           not one of those specified.  */
++  charset_not,
++
++        /* Start remembering the text that is matched, for storing in a
++           register.  Followed by one byte with the register number, in
++           the range 0 to one less than the pattern buffer's re_nsub
++           field.  Then followed by one byte with the number of groups
++           inner to this one.  (This last has to be part of the
++           start_memory only because we need it in the on_failure_jump
++           of re_match_2.)  */
++  start_memory,
++
++        /* Stop remembering the text that is matched and store it in a
++           memory register.  Followed by one byte with the register
++           number, in the range 0 to one less than `re_nsub' in the
++           pattern buffer, and one byte with the number of inner groups,
++           just like `start_memory'.  (We need the number of inner
++           groups here because we don't have any easy way of finding the
++           corresponding start_memory when we're at a stop_memory.)  */
++  stop_memory,
++
++        /* Match a duplicate of something remembered. Followed by one
++           byte containing the register number.  */
++  duplicate,
++
++        /* Fail unless at beginning of line.  */
++  begline,
++
++        /* Fail unless at end of line.  */
++  endline,
++
++        /* Succeeds if at beginning of buffer (if emacs) or at beginning
++           of string to be matched (if not).  */
++  begbuf,
++
++        /* Analogously, for end of buffer/string.  */
++  endbuf,
++
++        /* Followed by two byte relative address to which to jump.  */
++  jump,
++
++	/* Same as jump, but marks the end of an alternative.  */
++  jump_past_alt,
++
++        /* Followed by two-byte relative address of place to resume at
++           in case of failure.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  on_failure_jump,
++
++        /* Like on_failure_jump, but pushes a placeholder instead of the
++           current string position when executed.  */
++  on_failure_keep_string_jump,
++
++        /* Throw away latest failure point and then jump to following
++           two-byte relative address.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  pop_failure_jump,
++
++        /* Change to pop_failure_jump if know won't have to backtrack to
++           match; otherwise change to jump.  This is used to jump
++           back to the beginning of a repeat.  If what follows this jump
++           clearly won't match what the repeat does, such that we can be
++           sure that there is no use backtracking out of repetitions
++           already matched, then we change it to a pop_failure_jump.
++           Followed by two-byte address.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  maybe_pop_jump,
++
++        /* Jump to following two-byte address, and push a dummy failure
++           point. This failure point will be thrown away if an attempt
++           is made to use it for a failure.  A `+' construct makes this
++           before the first repeat.  Also used as an intermediary kind
++           of jump when compiling an alternative.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  dummy_failure_jump,
++
++	/* Push a dummy failure point and continue.  Used at the end of
++	   alternatives.  */
++  push_dummy_failure,
++
++        /* Followed by two-byte relative address and two-byte number n.
++           After matching N times, jump to the address upon failure.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  succeed_n,
++
++        /* Followed by two-byte relative address, and two-byte number n.
++           Jump to the address N times, then fail.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  jump_n,
++
++        /* Set the following two-byte relative address to the
++           subsequent two-byte number.  The address *includes* the two
++           bytes of number.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  set_number_at,
++
++  wordchar,	/* Matches any word-constituent character.  */
++  notwordchar,	/* Matches any char that is not a word-constituent.  */
++
++  wordbeg,	/* Succeeds if at word beginning.  */
++  wordend,	/* Succeeds if at word end.  */
++
++  wordbound,	/* Succeeds if at a word boundary.  */
++  notwordbound	/* Succeeds if not at a word boundary.  */
++
++# ifdef emacs
++  ,before_dot,	/* Succeeds if before point.  */
++  at_dot,	/* Succeeds if at point.  */
++  after_dot,	/* Succeeds if after point.  */
++
++	/* Matches any character whose syntax is specified.  Followed by
++           a byte which contains a syntax code, e.g., Sword.  */
++  syntaxspec,
++
++	/* Matches any character whose syntax is not that specified.  */
++  notsyntaxspec
++# endif /* emacs */
++} re_opcode_t;
++#endif /* not INSIDE_RECURSION */
++\f
++
++#ifdef BYTE
++# define CHAR_T char
++# define UCHAR_T unsigned char
++# define COMPILED_BUFFER_VAR bufp->buffer
++# define OFFSET_ADDRESS_SIZE 2
++# define PREFIX(name) byte_##name
++# define ARG_PREFIX(name) name
++# define PUT_CHAR(c) putchar (c)
++# include <locale/weight.h>
++# define FINDIDX findidx
++#else
++# ifdef WCHAR
++#  define CHAR_T wchar_t
++#  define UCHAR_T wchar_t
++#  define COMPILED_BUFFER_VAR wc_buffer
++#  define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */
++#  define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1)
++#  define PREFIX(name) wcs_##name
++#  define ARG_PREFIX(name) c##name
++/* Should we use wide stream??  */
++#  define PUT_CHAR(c) printf ("%C", c);
++#  define TRUE 1
++#  define FALSE 0
++#  define findidx findidxwc
++#  include <locale/weightwc.h>
++#  undef findidx
++#  define FINDIDX findidxwc
++# else
++#  ifdef MBS_SUPPORT
++#   define WCHAR
++#   define INSIDE_RECURSION
++#   include "xregex.c"
++#   undef INSIDE_RECURSION
++#  endif
++#  define BYTE
++#  define INSIDE_RECURSION
++#  include "xregex.c"
++#  undef INSIDE_RECURSION
++# endif
++#endif
++
++#ifdef INSIDE_RECURSION
++/* Common operations on the compiled pattern.  */
++
++/* Store NUMBER in two contiguous bytes starting at DESTINATION.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# ifdef WCHAR
++#  define STORE_NUMBER(destination, number)				\
++  do {									\
++    *(destination) = (UCHAR_T)(number);				\
++  } while (0)
++# else /* BYTE */
++#  define STORE_NUMBER(destination, number)				\
++  do {									\
++    (destination)[0] = (number) & 0377;					\
++    (destination)[1] = (number) >> 8;					\
++  } while (0)
++# endif /* WCHAR */
++
++/* Same as STORE_NUMBER, except increment DESTINATION to
++   the byte after where the number is stored.  Therefore, DESTINATION
++   must be an lvalue.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# define STORE_NUMBER_AND_INCR(destination, number)			\
++  do {									\
++    STORE_NUMBER (destination, number);					\
++    (destination) += OFFSET_ADDRESS_SIZE;				\
++  } while (0)
++
++/* Put into DESTINATION a number stored in two contiguous bytes starting
++   at SOURCE.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# ifdef WCHAR
++#  define EXTRACT_NUMBER(destination, source)				\
++  do {									\
++    (destination) = *(source);						\
++  } while (0)
++# else /* BYTE */
++#  define EXTRACT_NUMBER(destination, source)				\
++  do {									\
++    (destination) = *(source) & 0377;					\
++    (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8;		\
++  } while (0)
++# endif
++
++# ifdef DEBUG
++static void PREFIX(extract_number) (int *dest, UCHAR_T *source);
++static void
++PREFIX(extract_number) (int *dest, UCHAR_T *source)
++{
++#  ifdef WCHAR
++  *dest = *source;
++#  else /* BYTE */
++  int temp = SIGN_EXTEND_CHAR (*(source + 1));
++  *dest = *source & 0377;
++  *dest += temp << 8;
++#  endif
++}
++
++#  ifndef EXTRACT_MACROS /* To debug the macros.  */
++#   undef EXTRACT_NUMBER
++#   define EXTRACT_NUMBER(dest, src) PREFIX(extract_number) (&dest, src)
++#  endif /* not EXTRACT_MACROS */
++
++# endif /* DEBUG */
++
++/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
++   SOURCE must be an lvalue.  */
++
++# define EXTRACT_NUMBER_AND_INCR(destination, source)			\
++  do {									\
++    EXTRACT_NUMBER (destination, source);				\
++    (source) += OFFSET_ADDRESS_SIZE; 					\
++  } while (0)
++
++# ifdef DEBUG
++static void PREFIX(extract_number_and_incr) (int *destination,
++                                             UCHAR_T **source);
++static void
++PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source)
++{
++  PREFIX(extract_number) (destination, *source);
++  *source += OFFSET_ADDRESS_SIZE;
++}
++
++#  ifndef EXTRACT_MACROS
++#   undef EXTRACT_NUMBER_AND_INCR
++#   define EXTRACT_NUMBER_AND_INCR(dest, src) \
++  PREFIX(extract_number_and_incr) (&dest, &src)
++#  endif /* not EXTRACT_MACROS */
++
++# endif /* DEBUG */
++
++\f
++
++/* If DEBUG is defined, Regex prints many voluminous messages about what
++   it is doing (if the variable `debug' is nonzero).  If linked with the
++   main program in `iregex.c', you can enter patterns and strings
++   interactively.  And if linked with the main program in `main.c' and
++   the other test files, you can run the already-written tests.  */
++
++# ifdef DEBUG
++
++#  ifndef DEFINED_ONCE
++
++/* We use standard I/O for debugging.  */
++#   include <stdio.h>
++
++/* It is useful to test things that ``must'' be true when debugging.  */
++#   include <assert.h>
++
++static int debug;
++
++#   define DEBUG_STATEMENT(e) e
++#   define DEBUG_PRINT1(x) if (debug) printf (x)
++#   define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
++#   define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
++#   define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
++#  endif /* not DEFINED_ONCE */
++
++#  define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) 			\
++  if (debug) PREFIX(print_partial_compiled_pattern) (s, e)
++#  define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)		\
++  if (debug) PREFIX(print_double_string) (w, s1, sz1, s2, sz2)
++
++
++/* Print the fastmap in human-readable form.  */
++
++#  ifndef DEFINED_ONCE
++void
++print_fastmap (char *fastmap)
++{
++  unsigned was_a_range = 0;
++  unsigned i = 0;
++
++  while (i < (1 << BYTEWIDTH))
++    {
++      if (fastmap[i++])
++	{
++	  was_a_range = 0;
++          putchar (i - 1);
++          while (i < (1 << BYTEWIDTH)  &&  fastmap[i])
++            {
++              was_a_range = 1;
++              i++;
++            }
++	  if (was_a_range)
++            {
++              printf ("-");
++              putchar (i - 1);
++            }
++        }
++    }
++  putchar ('\n');
++}
++#  endif /* not DEFINED_ONCE */
++
++
++/* Print a compiled pattern string in human-readable form, starting at
++   the START pointer into it and ending just before the pointer END.  */
++
++void
++PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
++{
++  int mcnt, mcnt2;
++  UCHAR_T *p1;
++  UCHAR_T *p = start;
++  UCHAR_T *pend = end;
++
++  if (start == NULL)
++    {
++      printf ("(null)\n");
++      return;
++    }
++
++  /* Loop over pattern commands.  */
++  while (p < pend)
++    {
++#  ifdef _LIBC
++      printf ("%td:\t", p - start);
++#  else
++      printf ("%ld:\t", (long int) (p - start));
++#  endif
++
++      switch ((re_opcode_t) *p++)
++	{
++        case no_op:
++          printf ("/no_op");
++          break;
++
++	case exactn:
++	  mcnt = *p++;
++          printf ("/exactn/%d", mcnt);
++          do
++	    {
++              putchar ('/');
++	      PUT_CHAR (*p++);
++            }
++          while (--mcnt);
++          break;
++
++#  ifdef MBS_SUPPORT
++	case exactn_bin:
++	  mcnt = *p++;
++	  printf ("/exactn_bin/%d", mcnt);
++          do
++	    {
++	      printf("/%lx", (long int) *p++);
++            }
++          while (--mcnt);
++          break;
++#  endif /* MBS_SUPPORT */
++
++	case start_memory:
++          mcnt = *p++;
++          printf ("/start_memory/%d/%ld", mcnt, (long int) *p++);
++          break;
++
++	case stop_memory:
++          mcnt = *p++;
++	  printf ("/stop_memory/%d/%ld", mcnt, (long int) *p++);
++          break;
++
++	case duplicate:
++	  printf ("/duplicate/%ld", (long int) *p++);
++	  break;
++
++	case anychar:
++	  printf ("/anychar");
++	  break;
++
++	case charset:
++        case charset_not:
++          {
++#  ifdef WCHAR
++	    int i, length;
++	    wchar_t *workp = p;
++	    printf ("/charset [%s",
++	            (re_opcode_t) *(workp - 1) == charset_not ? "^" : "");
++	    p += 5;
++	    length = *workp++; /* the length of char_classes */
++	    for (i=0 ; i<length ; i++)
++	      printf("[:%lx:]", (long int) *p++);
++	    length = *workp++; /* the length of collating_symbol */
++	    for (i=0 ; i<length ;)
++	      {
++		printf("[.");
++		while(*p != 0)
++		  PUT_CHAR((i++,*p++));
++		i++,p++;
++		printf(".]");
++	      }
++	    length = *workp++; /* the length of equivalence_class */
++	    for (i=0 ; i<length ;)
++	      {
++		printf("[=");
++		while(*p != 0)
++		  PUT_CHAR((i++,*p++));
++		i++,p++;
++		printf("=]");
++	      }
++	    length = *workp++; /* the length of char_range */
++	    for (i=0 ; i<length ; i++)
++	      {
++		wchar_t range_start = *p++;
++		wchar_t range_end = *p++;
++		printf("%C-%C", range_start, range_end);
++	      }
++	    length = *workp++; /* the length of char */
++	    for (i=0 ; i<length ; i++)
++	      printf("%C", *p++);
++	    putchar (']');
++#  else
++            register int c, last = -100;
++	    register int in_range = 0;
++
++	    printf ("/charset [%s",
++	            (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
++
++            assert (p + *p < pend);
++
++            for (c = 0; c < 256; c++)
++	      if (c / 8 < *p
++		  && (p[1 + (c/8)] & (1 << (c % 8))))
++		{
++		  /* Are we starting a range?  */
++		  if (last + 1 == c && ! in_range)
++		    {
++		      putchar ('-');
++		      in_range = 1;
++		    }
++		  /* Have we broken a range?  */
++		  else if (last + 1 != c && in_range)
++              {
++		      putchar (last);
++		      in_range = 0;
++		    }
++
++		  if (! in_range)
++		    putchar (c);
++
++		  last = c;
++              }
++
++	    if (in_range)
++	      putchar (last);
++
++	    putchar (']');
++
++	    p += 1 + *p;
++#  endif /* WCHAR */
++	  }
++	  break;
++
++	case begline:
++	  printf ("/begline");
++          break;
++
++	case endline:
++          printf ("/endline");
++          break;
++
++	case on_failure_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/on_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/on_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case on_failure_keep_string_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/on_failure_keep_string_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/on_failure_keep_string_jump to %ld",
++		  (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case dummy_failure_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/dummy_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/dummy_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case push_dummy_failure:
++          printf ("/push_dummy_failure");
++          break;
++
++        case maybe_pop_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/maybe_pop_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/maybe_pop_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case pop_failure_jump:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/pop_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/pop_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case jump_past_alt:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/jump_past_alt to %td", p + mcnt - start);
++#  else
++  	  printf ("/jump_past_alt to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case jump:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case succeed_n:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++#  ifdef _LIBC
++	  printf ("/succeed_n to %td, %d times", p1 - start, mcnt2);
++#  else
++	  printf ("/succeed_n to %ld, %d times",
++		  (long int) (p1 - start), mcnt2);
++#  endif
++          break;
++
++        case jump_n:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++	  printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
++          break;
++
++        case set_number_at:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++#  ifdef _LIBC
++	  printf ("/set_number_at location %td to %d", p1 - start, mcnt2);
++#  else
++	  printf ("/set_number_at location %ld to %d",
++		  (long int) (p1 - start), mcnt2);
++#  endif
++          break;
++
++        case wordbound:
++	  printf ("/wordbound");
++	  break;
++
++	case notwordbound:
++	  printf ("/notwordbound");
++          break;
++
++	case wordbeg:
++	  printf ("/wordbeg");
++	  break;
++
++	case wordend:
++	  printf ("/wordend");
++	  break;
++
++#  ifdef emacs
++	case before_dot:
++	  printf ("/before_dot");
++          break;
++
++	case at_dot:
++	  printf ("/at_dot");
++          break;
++
++	case after_dot:
++	  printf ("/after_dot");
++          break;
++
++	case syntaxspec:
++          printf ("/syntaxspec");
++	  mcnt = *p++;
++	  printf ("/%d", mcnt);
++          break;
++
++	case notsyntaxspec:
++          printf ("/notsyntaxspec");
++	  mcnt = *p++;
++	  printf ("/%d", mcnt);
++	  break;
++#  endif /* emacs */
++
++	case wordchar:
++	  printf ("/wordchar");
++          break;
++
++	case notwordchar:
++	  printf ("/notwordchar");
++          break;
++
++	case begbuf:
++	  printf ("/begbuf");
++          break;
++
++	case endbuf:
++	  printf ("/endbuf");
++          break;
++
++        default:
++          printf ("?%ld", (long int) *(p-1));
++	}
++
++      putchar ('\n');
++    }
++
++#  ifdef _LIBC
++  printf ("%td:\tend of pattern.\n", p - start);
++#  else
++  printf ("%ld:\tend of pattern.\n", (long int) (p - start));
++#  endif
++}
++
++
++void
++PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
++{
++  UCHAR_T *buffer = (UCHAR_T*) bufp->buffer;
++
++  PREFIX(print_partial_compiled_pattern) (buffer, buffer
++				  + bufp->used / sizeof(UCHAR_T));
++  printf ("%ld bytes used/%ld bytes allocated.\n",
++	  bufp->used, bufp->allocated);
++
++  if (bufp->fastmap_accurate && bufp->fastmap)
++    {
++      printf ("fastmap: ");
++      print_fastmap (bufp->fastmap);
++    }
++
++#  ifdef _LIBC
++  printf ("re_nsub: %Zd\t", bufp->re_nsub);
++#  else
++  printf ("re_nsub: %ld\t", (long int) bufp->re_nsub);
++#  endif
++  printf ("regs_alloc: %d\t", bufp->regs_allocated);
++  printf ("can_be_null: %d\t", bufp->can_be_null);
++  printf ("newline_anchor: %d\n", bufp->newline_anchor);
++  printf ("no_sub: %d\t", bufp->no_sub);
++  printf ("not_bol: %d\t", bufp->not_bol);
++  printf ("not_eol: %d\t", bufp->not_eol);
++  printf ("syntax: %lx\n", bufp->syntax);
++  /* Perhaps we should print the translate table?  */
++}
++
++
++void
++PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1,
++                             int size1, const CHAR_T *string2, int size2)
++{
++  int this_char;
++
++  if (where == NULL)
++    printf ("(null)");
++  else
++    {
++      int cnt;
++
++      if (FIRST_STRING_P (where))
++        {
++          for (this_char = where - string1; this_char < size1; this_char++)
++	    PUT_CHAR (string1[this_char]);
++
++          where = string2;
++        }
++
++      cnt = 0;
++      for (this_char = where - string2; this_char < size2; this_char++)
++	{
++	  PUT_CHAR (string2[this_char]);
++	  if (++cnt > 100)
++	    {
++	      fputs ("...", stdout);
++	      break;
++	    }
++	}
++    }
++}
++
++#  ifndef DEFINED_ONCE
++void
++printchar (int c)
++{
++  putc (c, stderr);
++}
++#  endif
++
++# else /* not DEBUG */
++
++#  ifndef DEFINED_ONCE
++#   undef assert
++#   define assert(e)
++
++#   define DEBUG_STATEMENT(e)
++#   define DEBUG_PRINT1(x)
++#   define DEBUG_PRINT2(x1, x2)
++#   define DEBUG_PRINT3(x1, x2, x3)
++#   define DEBUG_PRINT4(x1, x2, x3, x4)
++#  endif /* not DEFINED_ONCE */
++#  define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
++#  define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
++
++# endif /* not DEBUG */
++
++\f
++
++# ifdef WCHAR
++/* This  convert a multibyte string to a wide character string.
++   And write their correspondances to offset_buffer(see below)
++   and write whether each wchar_t is binary data to is_binary.
++   This assume invalid multibyte sequences as binary data.
++   We assume offset_buffer and is_binary is already allocated
++   enough space.  */
++
++static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src,
++				  size_t len, int *offset_buffer,
++				  char *is_binary);
++static size_t
++convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len,
++                    int *offset_buffer, char *is_binary)
++     /* It hold correspondances between src(char string) and
++	dest(wchar_t string) for optimization.
++	e.g. src  = "xxxyzz"
++             dest = {'X', 'Y', 'Z'}
++	      (each "xxx", "y" and "zz" represent one multibyte character
++	       corresponding to 'X', 'Y' and 'Z'.)
++	  offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")}
++	  	        = {0, 3, 4, 6}
++     */
++{
++  wchar_t *pdest = dest;
++  const unsigned char *psrc = src;
++  size_t wc_count = 0;
++
++  mbstate_t mbs;
++  int i, consumed;
++  size_t mb_remain = len;
++  size_t mb_count = 0;
++
++  /* Initialize the conversion state.  */
++  memset (&mbs, 0, sizeof (mbstate_t));
++
++  offset_buffer[0] = 0;
++  for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed,
++	 psrc += consumed)
++    {
++#ifdef _LIBC
++      consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs);
++#else
++      consumed = mbrtowc (pdest, psrc, mb_remain, &mbs);
++#endif
++
++      if (consumed <= 0)
++	/* failed to convert. maybe src contains binary data.
++	   So we consume 1 byte manualy.  */
++	{
++	  *pdest = *psrc;
++	  consumed = 1;
++	  is_binary[wc_count] = TRUE;
++	}
++      else
++	is_binary[wc_count] = FALSE;
++      /* In sjis encoding, we use yen sign as escape character in
++	 place of reverse solidus. So we convert 0x5c(yen sign in
++	 sjis) to not 0xa5(yen sign in UCS2) but 0x5c(reverse
++	 solidus in UCS2).  */
++      if (consumed == 1 && (int) *psrc == 0x5c && (int) *pdest == 0xa5)
++	*pdest = (wchar_t) *psrc;
++
++      offset_buffer[wc_count + 1] = mb_count += consumed;
++    }
++
++  /* Fill remain of the buffer with sentinel.  */
++  for (i = wc_count + 1 ; i <= len ; i++)
++    offset_buffer[i] = mb_count + 1;
++
++  return wc_count;
++}
++
++# endif /* WCHAR */
++
++#else /* not INSIDE_RECURSION */
++
++/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
++   also be assigned to arbitrarily: each pattern buffer stores its own
++   syntax, so it can be changed between regex compilations.  */
++/* This has no initializer because initialized variables in Emacs
++   become read-only after dumping.  */
++reg_syntax_t re_syntax_options;
++
++
++/* Specify the precise syntax of regexps for compilation.  This provides
++   for compatibility for various utilities which historically have
++   different, incompatible syntaxes.
++
++   The argument SYNTAX is a bit mask comprised of the various bits
++   defined in regex.h.  We return the old syntax.  */
++
++reg_syntax_t
++re_set_syntax (reg_syntax_t syntax)
++{
++  reg_syntax_t ret = re_syntax_options;
++
++  re_syntax_options = syntax;
++# ifdef DEBUG
++  if (syntax & RE_DEBUG)
++    debug = 1;
++  else if (debug) /* was on but now is not */
++    debug = 0;
++# endif /* DEBUG */
++  return ret;
++}
++# ifdef _LIBC
++weak_alias (__re_set_syntax, re_set_syntax)
++# endif
++\f
++/* This table gives an error message for each of the error codes listed
++   in regex.h.  Obviously the order here has to be same as there.
++   POSIX doesn't require that we do anything for REG_NOERROR,
++   but why not be nice?  */
++
++static const char *re_error_msgid[] =
++  {
++    gettext_noop ("Success"),	/* REG_NOERROR */
++    gettext_noop ("No match"),	/* REG_NOMATCH */
++    gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
++    gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
++    gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
++    gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
++    gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
++    gettext_noop ("Unmatched [ or [^"),	/* REG_EBRACK */
++    gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
++    gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
++    gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
++    gettext_noop ("Invalid range end"),	/* REG_ERANGE */
++    gettext_noop ("Memory exhausted"), /* REG_ESPACE */
++    gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
++    gettext_noop ("Premature end of regular expression"), /* REG_EEND */
++    gettext_noop ("Regular expression too big"), /* REG_ESIZE */
++    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
++  };
++\f
++#endif /* INSIDE_RECURSION */
++
++#ifndef DEFINED_ONCE
++/* Avoiding alloca during matching, to placate r_alloc.  */
++
++/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
++   searching and matching functions should not call alloca.  On some
++   systems, alloca is implemented in terms of malloc, and if we're
++   using the relocating allocator routines, then malloc could cause a
++   relocation, which might (if the strings being searched are in the
++   ralloc heap) shift the data out from underneath the regexp
++   routines.
++
++   Here's another reason to avoid allocation: Emacs
++   processes input from X in a signal handler; processing X input may
++   call malloc; if input arrives while a matching routine is calling
++   malloc, then we're scrod.  But Emacs can't just block input while
++   calling matching routines; then we don't notice interrupts when
++   they come in.  So, Emacs blocks input around all regexp calls
++   except the matching calls, which it leaves unprotected, in the
++   faith that they will not malloc.  */
++
++/* Normally, this is fine.  */
++# define MATCH_MAY_ALLOCATE
++
++/* When using GNU C, we are not REALLY using the C alloca, no matter
++   what config.h may say.  So don't take precautions for it.  */
++# ifdef __GNUC__
++#  undef C_ALLOCA
++# endif
++
++/* The match routines may not allocate if (1) they would do it with malloc
++   and (2) it's not safe for them to use malloc.
++   Note that if REL_ALLOC is defined, matching would not use malloc for the
++   failure stack, but we would still use it for the register vectors;
++   so REL_ALLOC should not affect this.  */
++# if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
++#  undef MATCH_MAY_ALLOCATE
++# endif
++#endif /* not DEFINED_ONCE */
++\f
++#ifdef INSIDE_RECURSION
++/* Failure stack declarations and macros; both re_compile_fastmap and
++   re_match_2 use a failure stack.  These have to be macros because of
++   REGEX_ALLOCATE_STACK.  */
++
++
++/* Number of failure points for which to initially allocate space
++   when matching.  If this number is exceeded, we allocate more
++   space, so it is not a hard limit.  */
++# ifndef INIT_FAILURE_ALLOC
++#  define INIT_FAILURE_ALLOC 5
++# endif
++
++/* Roughly the maximum number of failure points on the stack.  Would be
++   exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
++   This is a variable only so users of regex can assign to it; we never
++   change it ourselves.  */
++
++
++# ifndef DEFINED_ONCE
++
++#  ifdef INT_IS_16BIT
++#   define RE_M_F_TYPE long int
++#  else
++#   define RE_M_F_TYPE int
++#  endif /* INT_IS_16BIT */
++
++#  ifdef MATCH_MAY_ALLOCATE
++/* 4400 was enough to cause a crash on Alpha OSF/1,
++   whose default stack limit is 2mb.  */
++#   define RE_M_F_DEFAULT 4000
++#  else
++#   define RE_M_F_DEFAULT 2000
++#  endif /* MATCH_MAY_ALLOCATE */
++
++#  include <shlib-compat.h>
++
++#  if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
++link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
++RE_M_F_TYPE re_max_failures = RE_M_F_DEFAULT;
++#  else
++RE_M_F_TYPE re_max_failures attribute_hidden = RE_M_F_DEFAULT;
++#  endif /* SHLIB_COMPAT */
++
++#  undef RE_M_F_TYPE
++#  undef RE_M_F_DEFAULT
++
++# endif /* DEFINED_ONCE */
++
++# ifdef INT_IS_16BIT
++
++union PREFIX(fail_stack_elt)
++{
++  UCHAR_T *pointer;
++  long int integer;
++};
++
++typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
++
++typedef struct
++{
++  PREFIX(fail_stack_elt_t) *stack;
++  unsigned long int size;
++  unsigned long int avail;		/* Offset of next open position.  */
++} PREFIX(fail_stack_type);
++
++# else /* not INT_IS_16BIT */
++
++union PREFIX(fail_stack_elt)
++{
++  UCHAR_T *pointer;
++  int integer;
++};
++
++typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
++
++typedef struct
++{
++  PREFIX(fail_stack_elt_t) *stack;
++  unsigned size;
++  unsigned avail;			/* Offset of next open position.  */
++} PREFIX(fail_stack_type);
++
++# endif /* INT_IS_16BIT */
++
++# ifndef DEFINED_ONCE
++#  define FAIL_STACK_EMPTY()     (fail_stack.avail == 0)
++#  define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
++#  define FAIL_STACK_FULL()      (fail_stack.avail == fail_stack.size)
++# endif
++
++
++/* Define macros to initialize and free the failure stack.
++   Do `return -2' if the alloc fails.  */
++
++# ifdef MATCH_MAY_ALLOCATE
++#  define INIT_FAIL_STACK()						\
++  do {									\
++    fail_stack.stack = (PREFIX(fail_stack_elt_t) *)		\
++      REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (PREFIX(fail_stack_elt_t))); \
++									\
++    if (fail_stack.stack == NULL)				\
++      return -2;							\
++									\
++    fail_stack.size = INIT_FAILURE_ALLOC;			\
++    fail_stack.avail = 0;					\
++  } while (0)
++
++#  define RESET_FAIL_STACK()  REGEX_FREE_STACK (fail_stack.stack)
++# else
++#  define INIT_FAIL_STACK()						\
++  do {									\
++    fail_stack.avail = 0;					\
++  } while (0)
++
++#  define RESET_FAIL_STACK()
++# endif
++
++
++/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
++
++   Return 1 if succeeds, and 0 if either ran out of memory
++   allocating space for it or it was already too large.
++
++   REGEX_REALLOCATE_STACK requires `destination' be declared.   */
++
++# define DOUBLE_FAIL_STACK(fail_stack)					\
++  ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS)	\
++   ? 0									\
++   : ((fail_stack).stack = (PREFIX(fail_stack_elt_t) *)			\
++        REGEX_REALLOCATE_STACK ((fail_stack).stack, 			\
++          (fail_stack).size * sizeof (PREFIX(fail_stack_elt_t)),	\
++          ((fail_stack).size << 1) * sizeof (PREFIX(fail_stack_elt_t))),\
++									\
++      (fail_stack).stack == NULL					\
++      ? 0								\
++      : ((fail_stack).size <<= 1, 					\
++         1)))
++
++
++/* Push pointer POINTER on FAIL_STACK.
++   Return 1 if was able to do so and 0 if ran out of memory allocating
++   space to do so.  */
++# define PUSH_PATTERN_OP(POINTER, FAIL_STACK)				\
++  ((FAIL_STACK_FULL ()							\
++    && !DOUBLE_FAIL_STACK (FAIL_STACK))					\
++   ? 0									\
++   : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER,	\
++      1))
++
++/* Push a pointer value onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_POINTER(item)					\
++  fail_stack.stack[fail_stack.avail++].pointer = (UCHAR_T *) (item)
++
++/* This pushes an integer-valued item onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_INT(item)					\
++  fail_stack.stack[fail_stack.avail++].integer = (item)
++
++/* Push a fail_stack_elt_t value onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_ELT(item)					\
++  fail_stack.stack[fail_stack.avail++] =  (item)
++
++/* These three POP... operations complement the three PUSH... operations.
++   All assume that `fail_stack' is nonempty.  */
++# define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
++# define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
++# define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
++
++/* Used to omit pushing failure point id's when we're not debugging.  */
++# ifdef DEBUG
++#  define DEBUG_PUSH PUSH_FAILURE_INT
++#  define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
++# else
++#  define DEBUG_PUSH(item)
++#  define DEBUG_POP(item_addr)
++# endif
++
++
++/* Push the information about the state we will need
++   if we ever fail back to it.
++
++   Requires variables fail_stack, regstart, regend, reg_info, and
++   num_regs_pushed be declared.  DOUBLE_FAIL_STACK requires `destination'
++   be declared.
++
++   Does `return FAILURE_CODE' if runs out of memory.  */
++
++# define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code)	\
++  do {									\
++    char *destination;							\
++    /* Must be int, so when we don't save any registers, the arithmetic	\
++       of 0 + -1 isn't done as unsigned.  */				\
++    /* Can't be int, since there is not a shred of a guarantee that int	\
++       is wide enough to hold a value of something to which pointer can	\
++       be assigned */							\
++    active_reg_t this_reg;						\
++    									\
++    DEBUG_STATEMENT (failure_id++);					\
++    DEBUG_STATEMENT (nfailure_points_pushed++);				\
++    DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id);		\
++    DEBUG_PRINT2 ("  Before push, next avail: %d\n", (fail_stack).avail);\
++    DEBUG_PRINT2 ("                     size: %d\n", (fail_stack).size);\
++									\
++    DEBUG_PRINT2 ("  slots needed: %ld\n", NUM_FAILURE_ITEMS);		\
++    DEBUG_PRINT2 ("     available: %d\n", REMAINING_AVAIL_SLOTS);	\
++									\
++    /* Ensure we have enough space allocated for what we will push.  */	\
++    while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS)			\
++      {									\
++        if (!DOUBLE_FAIL_STACK (fail_stack))				\
++          return failure_code;						\
++									\
++        DEBUG_PRINT2 ("\n  Doubled stack; size now: %d\n",		\
++		       (fail_stack).size);				\
++        DEBUG_PRINT2 ("  slots available: %d\n", REMAINING_AVAIL_SLOTS);\
++      }									\
++									\
++    /* Push the info, starting with the registers.  */			\
++    DEBUG_PRINT1 ("\n");						\
++									\
++    if (1)								\
++      for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
++	   this_reg++)							\
++	{								\
++	  DEBUG_PRINT2 ("  Pushing reg: %lu\n", this_reg);		\
++	  DEBUG_STATEMENT (num_regs_pushed++);				\
++									\
++	  DEBUG_PRINT2 ("    start: %p\n", regstart[this_reg]);		\
++	  PUSH_FAILURE_POINTER (regstart[this_reg]);			\
++									\
++	  DEBUG_PRINT2 ("    end: %p\n", regend[this_reg]);		\
++	  PUSH_FAILURE_POINTER (regend[this_reg]);			\
++									\
++	  DEBUG_PRINT2 ("    info: %p\n      ",				\
++			reg_info[this_reg].word.pointer);		\
++	  DEBUG_PRINT2 (" match_null=%d",				\
++			REG_MATCH_NULL_STRING_P (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" matched_something=%d",			\
++			MATCHED_SOMETHING (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" ever_matched=%d",				\
++			EVER_MATCHED_SOMETHING (reg_info[this_reg]));	\
++	  DEBUG_PRINT1 ("\n");						\
++	  PUSH_FAILURE_ELT (reg_info[this_reg].word);			\
++	}								\
++									\
++    DEBUG_PRINT2 ("  Pushing  low active reg: %ld\n", lowest_active_reg);\
++    PUSH_FAILURE_INT (lowest_active_reg);				\
++									\
++    DEBUG_PRINT2 ("  Pushing high active reg: %ld\n", highest_active_reg);\
++    PUSH_FAILURE_INT (highest_active_reg);				\
++									\
++    DEBUG_PRINT2 ("  Pushing pattern %p:\n", pattern_place);		\
++    DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend);		\
++    PUSH_FAILURE_POINTER (pattern_place);				\
++									\
++    DEBUG_PRINT2 ("  Pushing string %p: `", string_place);		\
++    DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2,   \
++				 size2);				\
++    DEBUG_PRINT1 ("'\n");						\
++    PUSH_FAILURE_POINTER (string_place);				\
++									\
++    DEBUG_PRINT2 ("  Pushing failure id: %u\n", failure_id);		\
++    DEBUG_PUSH (failure_id);						\
++  } while (0)
++
++# ifndef DEFINED_ONCE
++/* This is the number of items that are pushed and popped on the stack
++   for each register.  */
++#  define NUM_REG_ITEMS  3
++
++/* Individual items aside from the registers.  */
++#  ifdef DEBUG
++#   define NUM_NONREG_ITEMS 5 /* Includes failure point id.  */
++#  else
++#   define NUM_NONREG_ITEMS 4
++#  endif
++
++/* We push at most this many items on the stack.  */
++/* We used to use (num_regs - 1), which is the number of registers
++   this regexp will save; but that was changed to 5
++   to avoid stack overflow for a regexp with lots of parens.  */
++#  define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
++
++/* We actually push this many items.  */
++#  define NUM_FAILURE_ITEMS				\
++  (((0							\
++     ? 0 : highest_active_reg - lowest_active_reg + 1)	\
++    * NUM_REG_ITEMS)					\
++   + NUM_NONREG_ITEMS)
++
++/* How many items can still be added to the stack without overflowing it.  */
++#  define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
++# endif /* not DEFINED_ONCE */
++
++
++/* Pops what PUSH_FAIL_STACK pushes.
++
++   We restore into the parameters, all of which should be lvalues:
++     STR -- the saved data position.
++     PAT -- the saved pattern position.
++     LOW_REG, HIGH_REG -- the highest and lowest active registers.
++     REGSTART, REGEND -- arrays of string positions.
++     REG_INFO -- array of information about each subexpression.
++
++   Also assumes the variables `fail_stack' and (if debugging), `bufp',
++   `pend', `string1', `size1', `string2', and `size2'.  */
++# define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
++{									\
++  DEBUG_STATEMENT (unsigned failure_id;)				\
++  active_reg_t this_reg;						\
++  const UCHAR_T *string_temp;						\
++									\
++  assert (!FAIL_STACK_EMPTY ());					\
++									\
++  /* Remove failure points and point to how many regs pushed.  */	\
++  DEBUG_PRINT1 ("POP_FAILURE_POINT:\n");				\
++  DEBUG_PRINT2 ("  Before pop, next avail: %d\n", fail_stack.avail);	\
++  DEBUG_PRINT2 ("                    size: %d\n", fail_stack.size);	\
++									\
++  assert (fail_stack.avail >= NUM_NONREG_ITEMS);			\
++									\
++  DEBUG_POP (&failure_id);						\
++  DEBUG_PRINT2 ("  Popping failure id: %u\n", failure_id);		\
++									\
++  /* If the saved string location is NULL, it came from an		\
++     on_failure_keep_string_jump opcode, and we want to throw away the	\
++     saved NULL, thus retaining our current position in the string.  */	\
++  string_temp = POP_FAILURE_POINTER ();					\
++  if (string_temp != NULL)						\
++    str = (const CHAR_T *) string_temp;					\
++									\
++  DEBUG_PRINT2 ("  Popping string %p: `", str);				\
++  DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2);	\
++  DEBUG_PRINT1 ("'\n");							\
++									\
++  pat = (UCHAR_T *) POP_FAILURE_POINTER ();				\
++  DEBUG_PRINT2 ("  Popping pattern %p:\n", pat);			\
++  DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend);			\
++									\
++  /* Restore register info.  */						\
++  high_reg = (active_reg_t) POP_FAILURE_INT ();				\
++  DEBUG_PRINT2 ("  Popping high active reg: %ld\n", high_reg);		\
++									\
++  low_reg = (active_reg_t) POP_FAILURE_INT ();				\
++  DEBUG_PRINT2 ("  Popping  low active reg: %ld\n", low_reg);		\
++									\
++  if (1)								\
++    for (this_reg = high_reg; this_reg >= low_reg; this_reg--)		\
++      {									\
++	DEBUG_PRINT2 ("    Popping reg: %ld\n", this_reg);		\
++									\
++	reg_info[this_reg].word = POP_FAILURE_ELT ();			\
++	DEBUG_PRINT2 ("      info: %p\n",				\
++		      reg_info[this_reg].word.pointer);			\
++									\
++	regend[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER ();	\
++	DEBUG_PRINT2 ("      end: %p\n", regend[this_reg]);		\
++									\
++	regstart[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER ();	\
++	DEBUG_PRINT2 ("      start: %p\n", regstart[this_reg]);		\
++      }									\
++  else									\
++    {									\
++      for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
++	{								\
++	  reg_info[this_reg].word.integer = 0;				\
++	  regend[this_reg] = 0;						\
++	  regstart[this_reg] = 0;					\
++	}								\
++      highest_active_reg = high_reg;					\
++    }									\
++									\
++  set_regs_matched_done = 0;						\
++  DEBUG_STATEMENT (nfailure_points_popped++);				\
++} /* POP_FAILURE_POINT */
++\f
++/* Structure for per-register (a.k.a. per-group) information.
++   Other register information, such as the
++   starting and ending positions (which are addresses), and the list of
++   inner groups (which is a bits list) are maintained in separate
++   variables.
++
++   We are making a (strictly speaking) nonportable assumption here: that
++   the compiler will pack our bit fields into something that fits into
++   the type of `word', i.e., is something that fits into one item on the
++   failure stack.  */
++
++
++/* Declarations and macros for re_match_2.  */
++
++typedef union
++{
++  PREFIX(fail_stack_elt_t) word;
++  struct
++  {
++      /* This field is one if this group can match the empty string,
++         zero if not.  If not yet determined,  `MATCH_NULL_UNSET_VALUE'.  */
++# define MATCH_NULL_UNSET_VALUE 3
++    unsigned match_null_string_p : 2;
++    unsigned is_active : 1;
++    unsigned matched_something : 1;
++    unsigned ever_matched_something : 1;
++  } bits;
++} PREFIX(register_info_type);
++
++# ifndef DEFINED_ONCE
++#  define REG_MATCH_NULL_STRING_P(R)  ((R).bits.match_null_string_p)
++#  define IS_ACTIVE(R)  ((R).bits.is_active)
++#  define MATCHED_SOMETHING(R)  ((R).bits.matched_something)
++#  define EVER_MATCHED_SOMETHING(R)  ((R).bits.ever_matched_something)
++
++
++/* Call this when have matched a real character; it sets `matched' flags
++   for the subexpressions which we are currently inside.  Also records
++   that those subexprs have matched.  */
++#  define SET_REGS_MATCHED()						\
++  do									\
++    {									\
++      if (!set_regs_matched_done)					\
++	{								\
++	  active_reg_t r;						\
++	  set_regs_matched_done = 1;					\
++	  for (r = lowest_active_reg; r <= highest_active_reg; r++)	\
++	    {								\
++	      MATCHED_SOMETHING (reg_info[r])				\
++		= EVER_MATCHED_SOMETHING (reg_info[r])			\
++		= 1;							\
++	    }								\
++	}								\
++    }									\
++  while (0)
++# endif /* not DEFINED_ONCE */
++
++/* Registers are set to a sentinel when they haven't yet matched.  */
++static CHAR_T PREFIX(reg_unset_dummy);
++# define REG_UNSET_VALUE (&PREFIX(reg_unset_dummy))
++# define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
++
++/* Subroutine declarations and macros for regex_compile.  */
++static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg);
++static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc,
++                               int arg1, int arg2);
++static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc,
++                                int arg, UCHAR_T *end);
++static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc,
++                                int arg1, int arg2, UCHAR_T *end);
++static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern,
++                                         const CHAR_T *p,
++                                         reg_syntax_t syntax);
++static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p,
++                                         const CHAR_T *pend,
++                                         reg_syntax_t syntax);
++# ifdef WCHAR
++static reg_errcode_t wcs_compile_range (CHAR_T range_start,
++                                        const CHAR_T **p_ptr,
++                                        const CHAR_T *pend,
++                                        char *translate,
++                                        reg_syntax_t syntax,
++                                        UCHAR_T *b,
++                                        CHAR_T *char_set);
++static void insert_space (int num, CHAR_T *loc, CHAR_T *end);
++# else /* BYTE */
++static reg_errcode_t byte_compile_range (unsigned int range_start,
++                                         const char **p_ptr,
++                                         const char *pend,
++                                         RE_TRANSLATE_TYPE translate,
++                                         reg_syntax_t syntax,
++                                         unsigned char *b);
++# endif /* WCHAR */
++
++/* Fetch the next character in the uncompiled pattern---translating it
++   if necessary.  Also cast from a signed character in the constant
++   string passed to us by the user to an unsigned char that we can use
++   as an array index (in, e.g., `translate').  */
++/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
++   because it is impossible to allocate 4GB array for some encodings
++   which have 4 byte character_set like UCS4.  */
++# ifndef PATFETCH
++#  ifdef WCHAR
++#   define PATFETCH(c)							\
++  do {if (p == pend) return REG_EEND;					\
++    c = (UCHAR_T) *p++;							\
++    if (translate && (c <= 0xff)) c = (UCHAR_T) translate[c];		\
++  } while (0)
++#  else /* BYTE */
++#   define PATFETCH(c)							\
++  do {if (p == pend) return REG_EEND;					\
++    c = (unsigned char) *p++;						\
++    if (translate) c = (unsigned char) translate[c];			\
++  } while (0)
++#  endif /* WCHAR */
++# endif
++
++/* Fetch the next character in the uncompiled pattern, with no
++   translation.  */
++# define PATFETCH_RAW(c)						\
++  do {if (p == pend) return REG_EEND;					\
++    c = (UCHAR_T) *p++; 	       					\
++  } while (0)
++
++/* Go backwards one character in the pattern.  */
++# define PATUNFETCH p--
++
++
++/* If `translate' is non-null, return translate[D], else just D.  We
++   cast the subscript to translate because some data is declared as
++   `char *', to avoid warnings when a string constant is passed.  But
++   when we use a character as a subscript we must make it unsigned.  */
++/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
++   because it is impossible to allocate 4GB array for some encodings
++   which have 4 byte character_set like UCS4.  */
++
++# ifndef TRANSLATE
++#  ifdef WCHAR
++#   define TRANSLATE(d) \
++  ((translate && ((UCHAR_T) (d)) <= 0xff) \
++   ? (char) translate[(unsigned char) (d)] : (d))
++# else /* BYTE */
++#   define TRANSLATE(d) \
++  (translate ? (char) translate[(unsigned char) (d)] : (char) (d))
++#  endif /* WCHAR */
++# endif
++
++
++/* Macros for outputting the compiled pattern into `buffer'.  */
++
++/* If the buffer isn't allocated when it comes in, use this.  */
++# define INIT_BUF_SIZE  (32 * sizeof(UCHAR_T))
++
++/* Make sure we have at least N more bytes of space in buffer.  */
++# ifdef WCHAR
++#  define GET_BUFFER_SPACE(n)						\
++    while (((unsigned long)b - (unsigned long)COMPILED_BUFFER_VAR	\
++            + (n)*sizeof(CHAR_T)) > bufp->allocated)			\
++      EXTEND_BUFFER ()
++# else /* BYTE */
++#  define GET_BUFFER_SPACE(n)						\
++    while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated)	\
++      EXTEND_BUFFER ()
++# endif /* WCHAR */
++
++/* Make sure we have one more byte of buffer space and then add C to it.  */
++# define BUF_PUSH(c)							\
++  do {									\
++    GET_BUFFER_SPACE (1);						\
++    *b++ = (UCHAR_T) (c);						\
++  } while (0)
++
++
++/* Ensure we have two more bytes of buffer space and then append C1 and C2.  */
++# define BUF_PUSH_2(c1, c2)						\
++  do {									\
++    GET_BUFFER_SPACE (2);						\
++    *b++ = (UCHAR_T) (c1);						\
++    *b++ = (UCHAR_T) (c2);						\
++  } while (0)
++
++
++/* As with BUF_PUSH_2, except for three bytes.  */
++# define BUF_PUSH_3(c1, c2, c3)						\
++  do {									\
++    GET_BUFFER_SPACE (3);						\
++    *b++ = (UCHAR_T) (c1);						\
++    *b++ = (UCHAR_T) (c2);						\
++    *b++ = (UCHAR_T) (c3);						\
++  } while (0)
++
++/* Store a jump with opcode OP at LOC to location TO.  We store a
++   relative address offset by the three bytes the jump itself occupies.  */
++# define STORE_JUMP(op, loc, to) \
++ PREFIX(store_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)))
++
++/* Likewise, for a two-argument jump.  */
++# define STORE_JUMP2(op, loc, to, arg) \
++  PREFIX(store_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), arg)
++
++/* Like `STORE_JUMP', but for inserting.  Assume `b' is the buffer end.  */
++# define INSERT_JUMP(op, loc, to) \
++  PREFIX(insert_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), b)
++
++/* Like `STORE_JUMP2', but for inserting.  Assume `b' is the buffer end.  */
++# define INSERT_JUMP2(op, loc, to, arg) \
++  PREFIX(insert_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)),\
++	      arg, b)
++
++/* This is not an arbitrary limit: the arguments which represent offsets
++   into the pattern are two bytes long.  So if 2^16 bytes turns out to
++   be too small, many things would have to change.  */
++/* Any other compiler which, like MSC, has allocation limit below 2^16
++   bytes will have to use approach similar to what was done below for
++   MSC and drop MAX_BUF_SIZE a bit.  Otherwise you may end up
++   reallocating to 0 bytes.  Such thing is not going to work too well.
++   You have been warned!!  */
++# ifndef DEFINED_ONCE
++#  if defined _MSC_VER  && !defined WIN32
++/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
++   The REALLOC define eliminates a flurry of conversion warnings,
++   but is not required. */
++#   define MAX_BUF_SIZE  65500L
++#   define REALLOC(p,s) realloc ((p), (size_t) (s))
++#  else
++#   define MAX_BUF_SIZE (1L << 16)
++#   define REALLOC(p,s) realloc ((p), (s))
++#  endif
++
++/* Extend the buffer by twice its current size via realloc and
++   reset the pointers that pointed into the old block to point to the
++   correct places in the new one.  If extending the buffer results in it
++   being larger than MAX_BUF_SIZE, then flag memory exhausted.  */
++#  ifndef __BOUNDED_POINTERS__
++#    define __BOUNDED_POINTERS__ 0
++#  endif
++#  if __BOUNDED_POINTERS__
++#   define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
++#   define MOVE_BUFFER_POINTER(P) \
++  (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
++#   define ELSE_EXTEND_BUFFER_HIGH_BOUND	\
++  else						\
++    {						\
++      SET_HIGH_BOUND (b);			\
++      SET_HIGH_BOUND (begalt);			\
++      if (fixup_alt_jump)			\
++	SET_HIGH_BOUND (fixup_alt_jump);	\
++      if (laststart)				\
++	SET_HIGH_BOUND (laststart);		\
++      if (pending_exact)			\
++	SET_HIGH_BOUND (pending_exact);		\
++    }
++#  else
++#   define MOVE_BUFFER_POINTER(P) (P) += incr
++#   define ELSE_EXTEND_BUFFER_HIGH_BOUND
++#  endif
++# endif /* not DEFINED_ONCE */
++
++# ifdef WCHAR
++#  define EXTEND_BUFFER()						\
++  do {									\
++    UCHAR_T *old_buffer = COMPILED_BUFFER_VAR;				\
++    int wchar_count;							\
++    if (bufp->allocated + sizeof(UCHAR_T) > MAX_BUF_SIZE)		\
++      return REG_ESIZE;							\
++    bufp->allocated <<= 1;						\
++    if (bufp->allocated > MAX_BUF_SIZE)					\
++      bufp->allocated = MAX_BUF_SIZE;					\
++    /* How many characters the new buffer can have?  */			\
++    wchar_count = bufp->allocated / sizeof(UCHAR_T);			\
++    if (wchar_count == 0) wchar_count = 1;				\
++    /* Truncate the buffer to CHAR_T align.  */			\
++    bufp->allocated = wchar_count * sizeof(UCHAR_T);			\
++    RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T);		\
++    bufp->buffer = (char*)COMPILED_BUFFER_VAR;				\
++    if (COMPILED_BUFFER_VAR == NULL)					\
++      return REG_ESPACE;						\
++    /* If the buffer moved, move all the pointers into it.  */		\
++    if (old_buffer != COMPILED_BUFFER_VAR)				\
++      {									\
++	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
++	MOVE_BUFFER_POINTER (b);					\
++	MOVE_BUFFER_POINTER (begalt);					\
++	if (fixup_alt_jump)						\
++	  MOVE_BUFFER_POINTER (fixup_alt_jump);				\
++	if (laststart)							\
++	  MOVE_BUFFER_POINTER (laststart);				\
++	if (pending_exact)						\
++	  MOVE_BUFFER_POINTER (pending_exact);				\
++      }									\
++    ELSE_EXTEND_BUFFER_HIGH_BOUND					\
++  } while (0)
++# else /* BYTE */
++#  define EXTEND_BUFFER()						\
++  do {									\
++    UCHAR_T *old_buffer = COMPILED_BUFFER_VAR;				\
++    if (bufp->allocated == MAX_BUF_SIZE)				\
++      return REG_ESIZE;							\
++    bufp->allocated <<= 1;						\
++    if (bufp->allocated > MAX_BUF_SIZE)					\
++      bufp->allocated = MAX_BUF_SIZE;					\
++    bufp->buffer = (UCHAR_T *) REALLOC (COMPILED_BUFFER_VAR,		\
++						bufp->allocated);	\
++    if (COMPILED_BUFFER_VAR == NULL)					\
++      return REG_ESPACE;						\
++    /* If the buffer moved, move all the pointers into it.  */		\
++    if (old_buffer != COMPILED_BUFFER_VAR)				\
++      {									\
++	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
++	MOVE_BUFFER_POINTER (b);					\
++	MOVE_BUFFER_POINTER (begalt);					\
++	if (fixup_alt_jump)						\
++	  MOVE_BUFFER_POINTER (fixup_alt_jump);				\
++	if (laststart)							\
++	  MOVE_BUFFER_POINTER (laststart);				\
++	if (pending_exact)						\
++	  MOVE_BUFFER_POINTER (pending_exact);				\
++      }									\
++    ELSE_EXTEND_BUFFER_HIGH_BOUND					\
++  } while (0)
++# endif /* WCHAR */
++
++# ifndef DEFINED_ONCE
++/* Since we have one byte reserved for the register number argument to
++   {start,stop}_memory, the maximum number of groups we can report
++   things about is what fits in that byte.  */
++#  define MAX_REGNUM 255
++
++/* But patterns can have more than `MAX_REGNUM' registers.  We just
++   ignore the excess.  */
++typedef unsigned regnum_t;
++
++
++/* Macros for the compile stack.  */
++
++/* Since offsets can go either forwards or backwards, this type needs to
++   be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1.  */
++/* int may be not enough when sizeof(int) == 2.  */
++typedef long pattern_offset_t;
++
++typedef struct
++{
++  pattern_offset_t begalt_offset;
++  pattern_offset_t fixup_alt_jump;
++  pattern_offset_t inner_group_offset;
++  pattern_offset_t laststart_offset;
++  regnum_t regnum;
++} compile_stack_elt_t;
++
++
++typedef struct
++{
++  compile_stack_elt_t *stack;
++  unsigned size;
++  unsigned avail;			/* Offset of next open position.  */
++} compile_stack_type;
++
++
++#  define INIT_COMPILE_STACK_SIZE 32
++
++#  define COMPILE_STACK_EMPTY  (compile_stack.avail == 0)
++#  define COMPILE_STACK_FULL  (compile_stack.avail == compile_stack.size)
++
++/* The next available element.  */
++#  define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
++
++# endif /* not DEFINED_ONCE */
++
++/* Set the bit for character C in a list.  */
++# ifndef DEFINED_ONCE
++#  define SET_LIST_BIT(c)                               \
++  (b[((unsigned char) (c)) / BYTEWIDTH]               \
++   |= 1 << (((unsigned char) c) % BYTEWIDTH))
++# endif /* DEFINED_ONCE */
++
++/* Get the next unsigned number in the uncompiled pattern.  */
++# define GET_UNSIGNED_NUMBER(num) \
++  {									\
++    while (p != pend)							\
++      {									\
++	PATFETCH (c);							\
++	if (c < '0' || c > '9')						\
++	  break;							\
++	if (num <= RE_DUP_MAX)						\
++	  {								\
++	    if (num < 0)						\
++	      num = 0;							\
++	    num = num * 10 + c - '0';					\
++	  }								\
++      }									\
++  }
++
++# ifndef DEFINED_ONCE
++#  if WIDE_CHAR_SUPPORT
++/* The GNU C library provides support for user-defined character classes
++   and the functions from ISO C amendement 1.  */
++#   ifdef CHARCLASS_NAME_MAX
++#    define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
++#   else
++/* This shouldn't happen but some implementation might still have this
++   problem.  Use a reasonable default value.  */
++#    define CHAR_CLASS_MAX_LENGTH 256
++#   endif
++
++#   ifdef _LIBC
++#    define IS_CHAR_CLASS(string) __wctype (string)
++#   else
++#    define IS_CHAR_CLASS(string) wctype (string)
++#   endif
++#  else
++#   define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
++
++#   define IS_CHAR_CLASS(string)					\
++   (STREQ (string, "alpha") || STREQ (string, "upper")			\
++    || STREQ (string, "lower") || STREQ (string, "digit")		\
++    || STREQ (string, "alnum") || STREQ (string, "xdigit")		\
++    || STREQ (string, "space") || STREQ (string, "print")		\
++    || STREQ (string, "punct") || STREQ (string, "graph")		\
++    || STREQ (string, "cntrl") || STREQ (string, "blank"))
++#  endif
++# endif /* DEFINED_ONCE */
++\f
++# ifndef MATCH_MAY_ALLOCATE
++
++/* If we cannot allocate large objects within re_match_2_internal,
++   we make the fail stack and register vectors global.
++   The fail stack, we grow to the maximum size when a regexp
++   is compiled.
++   The register vectors, we adjust in size each time we
++   compile a regexp, according to the number of registers it needs.  */
++
++static PREFIX(fail_stack_type) fail_stack;
++
++/* Size with which the following vectors are currently allocated.
++   That is so we can make them bigger as needed,
++   but never make them smaller.  */
++#  ifdef DEFINED_ONCE
++static int regs_allocated_size;
++
++static const char **     regstart, **     regend;
++static const char ** old_regstart, ** old_regend;
++static const char **best_regstart, **best_regend;
++static const char **reg_dummy;
++#  endif /* DEFINED_ONCE */
++
++static PREFIX(register_info_type) *PREFIX(reg_info);
++static PREFIX(register_info_type) *PREFIX(reg_info_dummy);
++
++/* Make the register vectors big enough for NUM_REGS registers,
++   but don't make them smaller.  */
++
++static void
++PREFIX(regex_grow_registers) (int num_regs)
++{
++  if (num_regs > regs_allocated_size)
++    {
++      RETALLOC_IF (regstart,	 num_regs, const char *);
++      RETALLOC_IF (regend,	 num_regs, const char *);
++      RETALLOC_IF (old_regstart, num_regs, const char *);
++      RETALLOC_IF (old_regend,	 num_regs, const char *);
++      RETALLOC_IF (best_regstart, num_regs, const char *);
++      RETALLOC_IF (best_regend,	 num_regs, const char *);
++      RETALLOC_IF (PREFIX(reg_info), num_regs, PREFIX(register_info_type));
++      RETALLOC_IF (reg_dummy,	 num_regs, const char *);
++      RETALLOC_IF (PREFIX(reg_info_dummy), num_regs, PREFIX(register_info_type));
++
++      regs_allocated_size = num_regs;
++    }
++}
++
++# endif /* not MATCH_MAY_ALLOCATE */
++\f
++# ifndef DEFINED_ONCE
++static boolean group_in_compile_stack (compile_stack_type compile_stack,
++                                       regnum_t regnum);
++# endif /* not DEFINED_ONCE */
++
++/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
++   Returns one of error codes defined in `regex.h', or zero for success.
++
++   Assumes the `allocated' (and perhaps `buffer') and `translate'
++   fields are set in BUFP on entry.
++
++   If it succeeds, results are put in BUFP (if it returns an error, the
++   contents of BUFP are undefined):
++     `buffer' is the compiled pattern;
++     `syntax' is set to SYNTAX;
++     `used' is set to the length of the compiled pattern;
++     `fastmap_accurate' is zero;
++     `re_nsub' is the number of subexpressions in PATTERN;
++     `not_bol' and `not_eol' are zero;
++
++   The `fastmap' and `newline_anchor' fields are neither
++   examined nor set.  */
++
++/* Return, freeing storage we allocated.  */
++# ifdef WCHAR
++#  define FREE_STACK_RETURN(value)		\
++  return (free(pattern), free(mbs_offset), free(is_binary), free (compile_stack.stack), value)
++# else
++#  define FREE_STACK_RETURN(value)		\
++  return (free (compile_stack.stack), value)
++# endif /* WCHAR */
++
++static reg_errcode_t
++PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
++                       size_t ARG_PREFIX(size), reg_syntax_t syntax,
++                       struct re_pattern_buffer *bufp)
++{
++  /* We fetch characters from PATTERN here.  Even though PATTERN is
++     `char *' (i.e., signed), we declare these variables as unsigned, so
++     they can be reliably used as array indices.  */
++  register UCHAR_T c, c1;
++
++#ifdef WCHAR
++  /* A temporary space to keep wchar_t pattern and compiled pattern.  */
++  CHAR_T *pattern, *COMPILED_BUFFER_VAR;
++  size_t size;
++  /* offset buffer for optimization. See convert_mbs_to_wc.  */
++  int *mbs_offset = NULL;
++  /* It hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++  /* A flag whether exactn is handling binary data or not.  */
++  char is_exactn_bin = FALSE;
++#endif /* WCHAR */
++
++  /* A random temporary spot in PATTERN.  */
++  const CHAR_T *p1;
++
++  /* Points to the end of the buffer, where we should append.  */
++  register UCHAR_T *b;
++
++  /* Keeps track of unclosed groups.  */
++  compile_stack_type compile_stack;
++
++  /* Points to the current (ending) position in the pattern.  */
++#ifdef WCHAR
++  const CHAR_T *p;
++  const CHAR_T *pend;
++#else /* BYTE */
++  const CHAR_T *p = pattern;
++  const CHAR_T *pend = pattern + size;
++#endif /* WCHAR */
++
++  /* How to translate the characters in the pattern.  */
++  RE_TRANSLATE_TYPE translate = bufp->translate;
++
++  /* Address of the count-byte of the most recently inserted `exactn'
++     command.  This makes it possible to tell if a new exact-match
++     character can be added to that command or if the character requires
++     a new `exactn' command.  */
++  UCHAR_T *pending_exact = 0;
++
++  /* Address of start of the most recently finished expression.
++     This tells, e.g., postfix * where to find the start of its
++     operand.  Reset at the beginning of groups and alternatives.  */
++  UCHAR_T *laststart = 0;
++
++  /* Address of beginning of regexp, or inside of last group.  */
++  UCHAR_T *begalt;
++
++  /* Address of the place where a forward jump should go to the end of
++     the containing expression.  Each alternative of an `or' -- except the
++     last -- ends with a forward jump of this sort.  */
++  UCHAR_T *fixup_alt_jump = 0;
++
++  /* Counts open-groups as they are encountered.  Remembered for the
++     matching close-group on the compile stack, so the same register
++     number is put in the stop_memory as the start_memory.  */
++  regnum_t regnum = 0;
++
++#ifdef WCHAR
++  /* Initialize the wchar_t PATTERN and offset_buffer.  */
++  p = pend = pattern = TALLOC(csize + 1, CHAR_T);
++  mbs_offset = TALLOC(csize + 1, int);
++  is_binary = TALLOC(csize + 1, char);
++  if (pattern == NULL || mbs_offset == NULL || is_binary == NULL)
++    {
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++      return REG_ESPACE;
++    }
++  pattern[csize] = L'\0';	/* sentinel */
++  size = convert_mbs_to_wcs(pattern, cpattern, csize, mbs_offset, is_binary);
++  pend = p + size;
++  if (size < 0)
++    {
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++      return REG_BADPAT;
++    }
++#endif
++
++#ifdef DEBUG
++  DEBUG_PRINT1 ("\nCompiling pattern: ");
++  if (debug)
++    {
++      unsigned debug_count;
++
++      for (debug_count = 0; debug_count < size; debug_count++)
++        PUT_CHAR (pattern[debug_count]);
++      putchar ('\n');
++    }
++#endif /* DEBUG */
++
++  /* Initialize the compile stack.  */
++  compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
++  if (compile_stack.stack == NULL)
++    {
++#ifdef WCHAR
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++#endif
++      return REG_ESPACE;
++    }
++
++  compile_stack.size = INIT_COMPILE_STACK_SIZE;
++  compile_stack.avail = 0;
++
++  /* Initialize the pattern buffer.  */
++  bufp->syntax = syntax;
++  bufp->fastmap_accurate = 0;
++  bufp->not_bol = bufp->not_eol = 0;
++
++  /* Set `used' to zero, so that if we return an error, the pattern
++     printer (for debugging) will think there's no pattern.  We reset it
++     at the end.  */
++  bufp->used = 0;
++
++  /* Always count groups, whether or not bufp->no_sub is set.  */
++  bufp->re_nsub = 0;
++
++#if !defined emacs && !defined SYNTAX_TABLE
++  /* Initialize the syntax table.  */
++   init_syntax_once ();
++#endif
++
++  if (bufp->allocated == 0)
++    {
++      if (bufp->buffer)
++	{ /* If zero allocated, but buffer is non-null, try to realloc
++             enough space.  This loses if buffer's address is bogus, but
++             that is the user's responsibility.  */
++#ifdef WCHAR
++	  /* Free bufp->buffer and allocate an array for wchar_t pattern
++	     buffer.  */
++          free(bufp->buffer);
++          COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE/sizeof(UCHAR_T),
++					UCHAR_T);
++#else
++          RETALLOC (COMPILED_BUFFER_VAR, INIT_BUF_SIZE, UCHAR_T);
++#endif /* WCHAR */
++        }
++      else
++        { /* Caller did not allocate a buffer.  Do it for them.  */
++          COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE / sizeof(UCHAR_T),
++					UCHAR_T);
++        }
++
++      if (!COMPILED_BUFFER_VAR) FREE_STACK_RETURN (REG_ESPACE);
++#ifdef WCHAR
++      bufp->buffer = (char*)COMPILED_BUFFER_VAR;
++#endif /* WCHAR */
++      bufp->allocated = INIT_BUF_SIZE;
++    }
++#ifdef WCHAR
++  else
++    COMPILED_BUFFER_VAR = (UCHAR_T*) bufp->buffer;
++#endif
++
++  begalt = b = COMPILED_BUFFER_VAR;
++
++  /* Loop through the uncompiled pattern until we're at the end.  */
++  while (p != pend)
++    {
++      PATFETCH (c);
++
++      switch (c)
++        {
++        case '^':
++          {
++            if (   /* If at start of pattern, it's an operator.  */
++                   p == pattern + 1
++                   /* If context independent, it's an operator.  */
++                || syntax & RE_CONTEXT_INDEP_ANCHORS
++                   /* Otherwise, depends on what's come before.  */
++                || PREFIX(at_begline_loc_p) (pattern, p, syntax))
++              BUF_PUSH (begline);
++            else
++              goto normal_char;
++          }
++          break;
++
++
++        case '$':
++          {
++            if (   /* If at end of pattern, it's an operator.  */
++                   p == pend
++                   /* If context independent, it's an operator.  */
++                || syntax & RE_CONTEXT_INDEP_ANCHORS
++                   /* Otherwise, depends on what's next.  */
++                || PREFIX(at_endline_loc_p) (p, pend, syntax))
++               BUF_PUSH (endline);
++             else
++               goto normal_char;
++           }
++           break;
++
++
++	case '+':
++        case '?':
++          if ((syntax & RE_BK_PLUS_QM)
++              || (syntax & RE_LIMITED_OPS))
++            goto normal_char;
++        handle_plus:
++        case '*':
++          /* If there is no previous pattern... */
++          if (!laststart)
++            {
++              if (syntax & RE_CONTEXT_INVALID_OPS)
++                FREE_STACK_RETURN (REG_BADRPT);
++              else if (!(syntax & RE_CONTEXT_INDEP_OPS))
++                goto normal_char;
++            }
++
++          {
++            /* Are we optimizing this jump?  */
++            boolean keep_string_p = false;
++
++            /* 1 means zero (many) matches is allowed.  */
++            char zero_times_ok = 0, many_times_ok = 0;
++
++            /* If there is a sequence of repetition chars, collapse it
++               down to just one (the right one).  We can't combine
++               interval operators with these because of, e.g., `a{2}*',
++               which should only match an even number of `a's.  */
++
++            for (;;)
++              {
++                zero_times_ok |= c != '+';
++                many_times_ok |= c != '?';
++
++                if (p == pend)
++                  break;
++
++                PATFETCH (c);
++
++                if (c == '*'
++                    || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
++                  ;
++
++                else if (syntax & RE_BK_PLUS_QM  &&  c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++                    if (!(c1 == '+' || c1 == '?'))
++                      {
++                        PATUNFETCH;
++                        PATUNFETCH;
++                        break;
++                      }
++
++                    c = c1;
++                  }
++                else
++                  {
++                    PATUNFETCH;
++                    break;
++                  }
++
++                /* If we get here, we found another repeat character.  */
++               }
++
++            /* Star, etc. applied to an empty pattern is equivalent
++               to an empty pattern.  */
++            if (!laststart)
++              break;
++
++            /* Now we know whether or not zero matches is allowed
++               and also whether or not two or more matches is allowed.  */
++            if (many_times_ok)
++              { /* More than one repetition is allowed, so put in at the
++                   end a backward relative jump from `b' to before the next
++                   jump we're going to put in below (which jumps from
++                   laststart to after this jump).
++
++                   But if we are at the `*' in the exact sequence `.*\n',
++                   insert an unconditional jump backwards to the .,
++                   instead of the beginning of the loop.  This way we only
++                   push a failure point once, instead of every time
++                   through the loop.  */
++                assert (p - 1 > pattern);
++
++                /* Allocate the space for the jump.  */
++                GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++
++                /* We know we are not at the first character of the pattern,
++                   because laststart was nonzero.  And we've already
++                   incremented `p', by the way, to be the character after
++                   the `*'.  Do we have to do something analogous here
++                   for null bytes, because of RE_DOT_NOT_NULL?  */
++                if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
++		    && zero_times_ok
++                    && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
++                    && !(syntax & RE_DOT_NEWLINE))
++                  { /* We have .*\n.  */
++                    STORE_JUMP (jump, b, laststart);
++                    keep_string_p = true;
++                  }
++                else
++                  /* Anything else.  */
++                  STORE_JUMP (maybe_pop_jump, b, laststart -
++			      (1 + OFFSET_ADDRESS_SIZE));
++
++                /* We've added more stuff to the buffer.  */
++                b += 1 + OFFSET_ADDRESS_SIZE;
++              }
++
++            /* On failure, jump from laststart to b + 3, which will be the
++               end of the buffer after this jump is inserted.  */
++	    /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' instead of
++	       'b + 3'.  */
++            GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++            INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
++                                       : on_failure_jump,
++                         laststart, b + 1 + OFFSET_ADDRESS_SIZE);
++            pending_exact = 0;
++            b += 1 + OFFSET_ADDRESS_SIZE;
++
++            if (!zero_times_ok)
++              {
++                /* At least one repetition is required, so insert a
++                   `dummy_failure_jump' before the initial
++                   `on_failure_jump' instruction of the loop. This
++                   effects a skip over that instruction the first time
++                   we hit that loop.  */
++                GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++                INSERT_JUMP (dummy_failure_jump, laststart, laststart +
++			     2 + 2 * OFFSET_ADDRESS_SIZE);
++                b += 1 + OFFSET_ADDRESS_SIZE;
++              }
++            }
++	  break;
++
++
++	case '.':
++          laststart = b;
++          BUF_PUSH (anychar);
++          break;
++
++
++        case '[':
++          {
++            boolean had_char_class = false;
++#ifdef WCHAR
++	    CHAR_T range_start = 0xffffffff;
++#else
++	    unsigned int range_start = 0xffffffff;
++#endif
++            if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++#ifdef WCHAR
++	    /* We assume a charset(_not) structure as a wchar_t array.
++	       charset[0] = (re_opcode_t) charset(_not)
++               charset[1] = l (= length of char_classes)
++               charset[2] = m (= length of collating_symbols)
++               charset[3] = n (= length of equivalence_classes)
++	       charset[4] = o (= length of char_ranges)
++	       charset[5] = p (= length of chars)
++
++               charset[6] = char_class (wctype_t)
++               charset[6+CHAR_CLASS_SIZE] = char_class (wctype_t)
++                         ...
++               charset[l+5]  = char_class (wctype_t)
++
++               charset[l+6]  = collating_symbol (wchar_t)
++                            ...
++               charset[l+m+5]  = collating_symbol (wchar_t)
++					ifdef _LIBC we use the index if
++					_NL_COLLATE_SYMB_EXTRAMB instead of
++					wchar_t string.
++
++               charset[l+m+6]  = equivalence_classes (wchar_t)
++                              ...
++               charset[l+m+n+5]  = equivalence_classes (wchar_t)
++					ifdef _LIBC we use the index in
++					_NL_COLLATE_WEIGHT instead of
++					wchar_t string.
++
++	       charset[l+m+n+6] = range_start
++	       charset[l+m+n+7] = range_end
++	                       ...
++	       charset[l+m+n+2o+4] = range_start
++	       charset[l+m+n+2o+5] = range_end
++					ifdef _LIBC we use the value looked up
++					in _NL_COLLATE_COLLSEQ instead of
++					wchar_t character.
++
++	       charset[l+m+n+2o+6] = char
++	                          ...
++	       charset[l+m+n+2o+p+5] = char
++
++	     */
++
++	    /* We need at least 6 spaces: the opcode, the length of
++               char_classes, the length of collating_symbols, the length of
++               equivalence_classes, the length of char_ranges, the length of
++               chars.  */
++	    GET_BUFFER_SPACE (6);
++
++	    /* Save b as laststart. And We use laststart as the pointer
++	       to the first element of the charset here.
++	       In other words, laststart[i] indicates charset[i].  */
++            laststart = b;
++
++            /* We test `*p == '^' twice, instead of using an if
++               statement, so we only need one BUF_PUSH.  */
++            BUF_PUSH (*p == '^' ? charset_not : charset);
++            if (*p == '^')
++              p++;
++
++            /* Push the length of char_classes, the length of
++               collating_symbols, the length of equivalence_classes, the
++               length of char_ranges and the length of chars.  */
++            BUF_PUSH_3 (0, 0, 0);
++            BUF_PUSH_2 (0, 0);
++
++            /* Remember the first position in the bracket expression.  */
++            p1 = p;
++
++            /* charset_not matches newline according to a syntax bit.  */
++            if ((re_opcode_t) b[-6] == charset_not
++                && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
++	      {
++		BUF_PUSH('\n');
++		laststart[5]++; /* Update the length of characters  */
++	      }
++
++            /* Read in characters and ranges, setting map bits.  */
++            for (;;)
++              {
++                if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                PATFETCH (c);
++
++                /* \ might escape characters inside [...] and [^...].  */
++                if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++		    BUF_PUSH(c1);
++		    laststart[5]++; /* Update the length of chars  */
++		    range_start = c1;
++                    continue;
++                  }
++
++                /* Could be the end of the bracket expression.  If it's
++                   not (i.e., when the bracket expression is `[]' so
++                   far), the ']' character bit gets set way below.  */
++                if (c == ']' && p != p1 + 1)
++                  break;
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character class.  */
++                if (had_char_class && c == '-' && *p != ']')
++                  FREE_STACK_RETURN (REG_ERANGE);
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character: if this is a hyphen not at the
++                   beginning or the end of a list, then it's the range
++                   operator.  */
++                if (c == '-'
++                    && !(p - 2 >= pattern && p[-2] == '[')
++                    && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
++                    && *p != ']')
++                  {
++                    reg_errcode_t ret;
++		    /* Allocate the space for range_start and range_end.  */
++		    GET_BUFFER_SPACE (2);
++		    /* Update the pointer to indicate end of buffer.  */
++                    b += 2;
++                    ret = wcs_compile_range (range_start, &p, pend, translate,
++                                         syntax, b, laststart);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++                    range_start = 0xffffffff;
++                  }
++                else if (p[0] == '-' && p[1] != ']')
++                  { /* This handles ranges made up of characters only.  */
++                    reg_errcode_t ret;
++
++		    /* Move past the `-'.  */
++                    PATFETCH (c1);
++		    /* Allocate the space for range_start and range_end.  */
++		    GET_BUFFER_SPACE (2);
++		    /* Update the pointer to indicate end of buffer.  */
++                    b += 2;
++                    ret = wcs_compile_range (c, &p, pend, translate, syntax, b,
++                                         laststart);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                /* See if we're at the beginning of a possible character
++                   class.  */
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
++                  { /* Leave room for the null.  */
++                    char str[CHAR_CLASS_MAX_LENGTH + 1];
++
++                    PATFETCH (c);
++                    c1 = 0;
++
++                    /* If pattern is `[[:'.  */
++                    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                    for (;;)
++                      {
++                        PATFETCH (c);
++                        if ((c == ':' && *p == ']') || p == pend)
++                          break;
++			if (c1 < CHAR_CLASS_MAX_LENGTH)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++                    str[c1] = '\0';
++
++                    /* If isn't a word bracketed by `[:' and `:]':
++                       undo the ending character, the letters, and leave
++                       the leading `:' and `[' (but store them as character).  */
++                    if (c == ':' && *p == ']')
++                      {
++			wctype_t wt;
++			uintptr_t alignedp;
++
++			/* Query the character class as wctype_t.  */
++			wt = IS_CHAR_CLASS (str);
++			if (wt == 0)
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++			/* Allocate the space for character class.  */
++                        GET_BUFFER_SPACE(CHAR_CLASS_SIZE);
++			/* Update the pointer to indicate end of buffer.  */
++                        b += CHAR_CLASS_SIZE;
++			/* Move data which follow character classes
++			    not to violate the data.  */
++                        insert_space(CHAR_CLASS_SIZE,
++				     laststart + 6 + laststart[1],
++				     b - 1);
++			alignedp = ((uintptr_t)(laststart + 6 + laststart[1])
++				    + __alignof__(wctype_t) - 1)
++			  	    & ~(uintptr_t)(__alignof__(wctype_t) - 1);
++			/* Store the character class.  */
++                        *((wctype_t*)alignedp) = wt;
++                        /* Update length of char_classes */
++                        laststart[1] += CHAR_CLASS_SIZE;
++
++                        had_char_class = true;
++                      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        BUF_PUSH ('[');
++                        BUF_PUSH (':');
++                        laststart[5] += 2; /* Update the length of characters  */
++			range_start = ':';
++                        had_char_class = false;
++                      }
++                  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && (*p == '='
++							  || *p == '.'))
++		  {
++		    CHAR_T str[128];	/* Should be large enough.  */
++		    CHAR_T delim = *p; /* '=' or '.'  */
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[=' or '[[.'.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == delim && *p == ']') || p == pend)
++			  break;
++			if (c1 < sizeof (str) - 1)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == delim && *p == ']' && str[0] != '\0')
++		      {
++                        unsigned int i, offset;
++			/* If we have no collation data we use the default
++			   collation in which each character is in a class
++			   by itself.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++
++                        /* If not defined _LIBC, we push the name and
++			   `\0' for the sake of matching performance.  */
++			int datasize = c1 + 1;
++
++# ifdef _LIBC
++			int32_t idx = 0;
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    const int32_t *table;
++			    const int32_t *weights;
++			    const int32_t *extra;
++			    const int32_t *indirect;
++			    wint_t *cp;
++
++			    if(delim == '=')
++			      {
++				/* We push the index for equivalence class.  */
++				cp = (wint_t*)str;
++
++				table = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_TABLEWC);
++				weights = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_WEIGHTWC);
++				extra = (const wint_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_EXTRAWC);
++				indirect = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_INDIRECTWC);
++
++				idx = FINDIDX (table, indirect, extra, &cp, 1);
++				if (idx == 0 || cp < (wint_t*) str + c1)
++				  /* This is no valid character.  */
++				  FREE_STACK_RETURN (REG_ECOLLATE);
++
++				str[0] = (wchar_t)idx;
++			      }
++			    else /* delim == '.' */
++			      {
++				/* We push collation sequence value
++				   for collating symbol.  */
++				int32_t table_size;
++				const int32_t *symb_table;
++				const unsigned char *extra;
++				int32_t idx;
++				int32_t elem;
++				int32_t second;
++				int32_t hash;
++				char char_str[c1];
++
++				/* We have to convert the name to a single-byte
++				   string.  This is possible since the names
++				   consist of ASCII characters and the internal
++				   representation is UCS4.  */
++				for (i = 0; i < c1; ++i)
++				  char_str[i] = str[i];
++
++				table_size =
++				  _NL_CURRENT_WORD (LC_COLLATE,
++						    _NL_COLLATE_SYMB_HASH_SIZEMB);
++				symb_table = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_SYMB_TABLEMB);
++				extra = (const unsigned char *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_SYMB_EXTRAMB);
++
++				/* Locate the character in the hashing table.  */
++				hash = elem_hash (char_str, c1);
++
++				idx = 0;
++				elem = hash % table_size;
++				second = hash % (table_size - 2);
++				while (symb_table[2 * elem] != 0)
++				  {
++				    /* First compare the hashing value.  */
++				    if (symb_table[2 * elem] == hash
++					&& c1 == extra[symb_table[2 * elem + 1]]
++					&& memcmp (char_str,
++						   &extra[symb_table[2 * elem + 1]
++							 + 1], c1) == 0)
++				      {
++					/* Yep, this is the entry.  */
++					idx = symb_table[2 * elem + 1];
++					idx += 1 + extra[idx];
++					break;
++				      }
++
++				    /* Next entry.  */
++				    elem += second;
++				  }
++
++				if (symb_table[2 * elem] != 0)
++				  {
++				    /* Compute the index of the byte sequence
++				       in the table.  */
++				    idx += 1 + extra[idx];
++				    /* Adjust for the alignment.  */
++				    idx = (idx + 3) & ~3;
++
++				    str[0] = (wchar_t) idx + 4;
++				  }
++				else if (symb_table[2 * elem] == 0 && c1 == 1)
++				  {
++				    /* No valid character.  Match it as a
++				       single byte character.  */
++				    had_char_class = false;
++				    BUF_PUSH(str[0]);
++				    /* Update the length of characters  */
++				    laststart[5]++;
++				    range_start = str[0];
++
++				    /* Throw away the ] at the end of the
++				       collating symbol.  */
++				    PATFETCH (c);
++				    /* exit from the switch block.  */
++				    continue;
++				  }
++				else
++				  FREE_STACK_RETURN (REG_ECOLLATE);
++			      }
++			    datasize = 1;
++			  }
++# endif
++                        /* Throw away the ] at the end of the equivalence
++                           class (or collating symbol).  */
++                        PATFETCH (c);
++
++			/* Allocate the space for the equivalence class
++			   (or collating symbol) (and '\0' if needed).  */
++                        GET_BUFFER_SPACE(datasize);
++			/* Update the pointer to indicate end of buffer.  */
++                        b += datasize;
++
++			if (delim == '=')
++			  { /* equivalence class  */
++			    /* Calculate the offset of char_ranges,
++			       which is next to equivalence_classes.  */
++			    offset = laststart[1] + laststart[2]
++			      + laststart[3] +6;
++			    /* Insert space.  */
++			    insert_space(datasize, laststart + offset, b - 1);
++
++			    /* Write the equivalence_class and \0.  */
++			    for (i = 0 ; i < datasize ; i++)
++			      laststart[offset + i] = str[i];
++
++			    /* Update the length of equivalence_classes.  */
++			    laststart[3] += datasize;
++			    had_char_class = true;
++			  }
++			else /* delim == '.' */
++			  { /* collating symbol  */
++			    /* Calculate the offset of the equivalence_classes,
++			       which is next to collating_symbols.  */
++			    offset = laststart[1] + laststart[2] + 6;
++			    /* Insert space and write the collationg_symbol
++			       and \0.  */
++			    insert_space(datasize, laststart + offset, b-1);
++			    for (i = 0 ; i < datasize ; i++)
++			      laststart[offset + i] = str[i];
++
++			    /* In re_match_2_internal if range_start < -1, we
++			       assume -range_start is the offset of the
++			       collating symbol which is specified as
++			       the character of the range start.  So we assign
++			       -(laststart[1] + laststart[2] + 6) to
++			       range_start.  */
++			    range_start = -(laststart[1] + laststart[2] + 6);
++			    /* Update the length of collating_symbol.  */
++			    laststart[2] += datasize;
++			    had_char_class = false;
++			  }
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        BUF_PUSH ('[');
++                        BUF_PUSH (delim);
++                        laststart[5] += 2; /* Update the length of characters  */
++			range_start = delim;
++                        had_char_class = false;
++                      }
++		  }
++                else
++                  {
++                    had_char_class = false;
++		    BUF_PUSH(c);
++		    laststart[5]++;  /* Update the length of characters  */
++		    range_start = c;
++                  }
++	      }
++
++#else /* BYTE */
++            /* Ensure that we have enough space to push a charset: the
++               opcode, the length count, and the bitset; 34 bytes in all.  */
++	    GET_BUFFER_SPACE (34);
++
++            laststart = b;
++
++            /* We test `*p == '^' twice, instead of using an if
++               statement, so we only need one BUF_PUSH.  */
++            BUF_PUSH (*p == '^' ? charset_not : charset);
++            if (*p == '^')
++              p++;
++
++            /* Remember the first position in the bracket expression.  */
++            p1 = p;
++
++            /* Push the number of bytes in the bitmap.  */
++            BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
++
++            /* Clear the whole map.  */
++            bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
++
++            /* charset_not matches newline according to a syntax bit.  */
++            if ((re_opcode_t) b[-2] == charset_not
++                && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
++              SET_LIST_BIT ('\n');
++
++            /* Read in characters and ranges, setting map bits.  */
++            for (;;)
++              {
++                if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                PATFETCH (c);
++
++                /* \ might escape characters inside [...] and [^...].  */
++                if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++                    SET_LIST_BIT (c1);
++		    range_start = c1;
++                    continue;
++                  }
++
++                /* Could be the end of the bracket expression.  If it's
++                   not (i.e., when the bracket expression is `[]' so
++                   far), the ']' character bit gets set way below.  */
++                if (c == ']' && p != p1 + 1)
++                  break;
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character class.  */
++                if (had_char_class && c == '-' && *p != ']')
++                  FREE_STACK_RETURN (REG_ERANGE);
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character: if this is a hyphen not at the
++                   beginning or the end of a list, then it's the range
++                   operator.  */
++                if (c == '-'
++                    && !(p - 2 >= pattern && p[-2] == '[')
++                    && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
++                    && *p != ']')
++                  {
++                    reg_errcode_t ret
++                      = byte_compile_range (range_start, &p, pend, translate,
++					    syntax, b);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                else if (p[0] == '-' && p[1] != ']')
++                  { /* This handles ranges made up of characters only.  */
++                    reg_errcode_t ret;
++
++		    /* Move past the `-'.  */
++                    PATFETCH (c1);
++
++                    ret = byte_compile_range (c, &p, pend, translate, syntax, b);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                /* See if we're at the beginning of a possible character
++                   class.  */
++
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
++                  { /* Leave room for the null.  */
++                    char str[CHAR_CLASS_MAX_LENGTH + 1];
++
++                    PATFETCH (c);
++                    c1 = 0;
++
++                    /* If pattern is `[[:'.  */
++                    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                    for (;;)
++                      {
++                        PATFETCH (c);
++                        if ((c == ':' && *p == ']') || p == pend)
++                          break;
++			if (((int) c1) < CHAR_CLASS_MAX_LENGTH)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++                    str[c1] = '\0';
++
++                    /* If isn't a word bracketed by `[:' and `:]':
++                       undo the ending character, the letters, and leave
++                       the leading `:' and `[' (but set bits for them).  */
++                    if (c == ':' && *p == ']')
++                      {
++# if WIDE_CHAR_SUPPORT
++                        boolean is_lower = STREQ (str, "lower");
++                        boolean is_upper = STREQ (str, "upper");
++			wctype_t wt;
++                        int ch;
++
++			wt = IS_CHAR_CLASS (str);
++			if (wt == 0)
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                        for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
++			  {
++#  ifdef _LIBC
++			    if (__iswctype (__btowc (ch), wt))
++			      SET_LIST_BIT (ch);
++#  else
++			    if (iswctype (btowc (ch), wt))
++			      SET_LIST_BIT (ch);
++#  endif
++
++			    if (translate && (is_upper || is_lower)
++				&& (ISUPPER (ch) || ISLOWER (ch)))
++			      SET_LIST_BIT (ch);
++			  }
++
++                        had_char_class = true;
++# else
++                        int ch;
++                        boolean is_alnum = STREQ (str, "alnum");
++                        boolean is_alpha = STREQ (str, "alpha");
++                        boolean is_blank = STREQ (str, "blank");
++                        boolean is_cntrl = STREQ (str, "cntrl");
++                        boolean is_digit = STREQ (str, "digit");
++                        boolean is_graph = STREQ (str, "graph");
++                        boolean is_lower = STREQ (str, "lower");
++                        boolean is_print = STREQ (str, "print");
++                        boolean is_punct = STREQ (str, "punct");
++                        boolean is_space = STREQ (str, "space");
++                        boolean is_upper = STREQ (str, "upper");
++                        boolean is_xdigit = STREQ (str, "xdigit");
++
++                        if (!IS_CHAR_CLASS (str))
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                        for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
++                          {
++			    /* This was split into 3 if's to
++			       avoid an arbitrary limit in some compiler.  */
++                            if (   (is_alnum  && ISALNUM (ch))
++                                || (is_alpha  && ISALPHA (ch))
++                                || (is_blank  && ISBLANK (ch))
++                                || (is_cntrl  && ISCNTRL (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   (is_digit  && ISDIGIT (ch))
++                                || (is_graph  && ISGRAPH (ch))
++                                || (is_lower  && ISLOWER (ch))
++                                || (is_print  && ISPRINT (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   (is_punct  && ISPUNCT (ch))
++                                || (is_space  && ISSPACE (ch))
++                                || (is_upper  && ISUPPER (ch))
++                                || (is_xdigit && ISXDIGIT (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   translate && (is_upper || is_lower)
++				&& (ISUPPER (ch) || ISLOWER (ch)))
++			      SET_LIST_BIT (ch);
++                          }
++                        had_char_class = true;
++# endif	/* libc || wctype.h */
++                      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT (':');
++			range_start = ':';
++                        had_char_class = false;
++                      }
++                  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '=')
++		  {
++		    unsigned char str[MB_LEN_MAX + 1];
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[='.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == '=' && *p == ']') || p == pend)
++			  break;
++			if (c1 < MB_LEN_MAX)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == '=' && *p == ']' && str[0] != '\0')
++		      {
++			/* If we have no collation data we use the default
++			   collation in which each character is in a class
++			   by itself.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++# ifdef _LIBC
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Set the bit for the character.  */
++			    SET_LIST_BIT (str[0]);
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    /* Try to match the byte sequence in `str' against
++			       those known to the collate implementation.
++			       First find out whether the bytes in `str' are
++			       actually from exactly one character.  */
++			    const int32_t *table;
++			    const unsigned char *weights;
++			    const unsigned char *extra;
++			    const int32_t *indirect;
++			    int32_t idx;
++			    const unsigned char *cp = str;
++			    int ch;
++
++			    table = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
++			    weights = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
++			    extra = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
++			    indirect = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
++			    idx = FINDIDX (table, indirect, extra, &cp, 1);
++			    if (idx == 0 || cp < str + c1)
++			      /* This is no valid character.  */
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Now we have to go throught the whole table
++			       and find all characters which have the same
++			       first level weight.
++
++			       XXX Note that this is not entirely correct.
++			       we would have to match multibyte sequences
++			       but this is not possible with the current
++			       implementation.  */
++			    for (ch = 1; ch < 256; ++ch)
++			      /* XXX This test would have to be changed if we
++				 would allow matching multibyte sequences.  */
++			      if (table[ch] > 0)
++				{
++				  int32_t idx2 = table[ch];
++				  size_t len = weights[idx2];
++
++				  /* Test whether the lenghts match.  */
++				  if (weights[idx] == len)
++				    {
++				      /* They do.  New compare the bytes of
++					 the weight.  */
++				      size_t cnt = 0;
++
++				      while (cnt < len
++					     && (weights[idx + 1 + cnt]
++						 == weights[idx2 + 1 + cnt]))
++					++cnt;
++
++				      if (cnt == len)
++					/* They match.  Mark the character as
++					   acceptable.  */
++					SET_LIST_BIT (ch);
++				    }
++				}
++			  }
++# endif
++			had_char_class = true;
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT ('=');
++			range_start = '=';
++                        had_char_class = false;
++                      }
++		  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '.')
++		  {
++		    unsigned char str[128];	/* Should be large enough.  */
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[.'.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == '.' && *p == ']') || p == pend)
++			  break;
++			if (c1 < sizeof (str))
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == '.' && *p == ']' && str[0] != '\0')
++		      {
++			/* If we have no collation data we use the default
++			   collation in which each character is the name
++			   for its own class which contains only the one
++			   character.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++# ifdef _LIBC
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Set the bit for the character.  */
++			    SET_LIST_BIT (str[0]);
++			    range_start = ((const unsigned char *) str)[0];
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    /* Try to match the byte sequence in `str' against
++			       those known to the collate implementation.
++			       First find out whether the bytes in `str' are
++			       actually from exactly one character.  */
++			    int32_t table_size;
++			    const int32_t *symb_table;
++			    const unsigned char *extra;
++			    int32_t idx;
++			    int32_t elem;
++			    int32_t second;
++			    int32_t hash;
++
++			    table_size =
++			      _NL_CURRENT_WORD (LC_COLLATE,
++						_NL_COLLATE_SYMB_HASH_SIZEMB);
++			    symb_table = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE,
++					   _NL_COLLATE_SYMB_TABLEMB);
++			    extra = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE,
++					   _NL_COLLATE_SYMB_EXTRAMB);
++
++			    /* Locate the character in the hashing table.  */
++			    hash = elem_hash ((const char *) str, c1);
++
++			    idx = 0;
++			    elem = hash % table_size;
++			    second = hash % (table_size - 2);
++			    while (symb_table[2 * elem] != 0)
++			      {
++				/* First compare the hashing value.  */
++				if (symb_table[2 * elem] == hash
++				    && c1 == extra[symb_table[2 * elem + 1]]
++				    && memcmp (str,
++					       &extra[symb_table[2 * elem + 1]
++						     + 1],
++					       c1) == 0)
++				  {
++				    /* Yep, this is the entry.  */
++				    idx = symb_table[2 * elem + 1];
++				    idx += 1 + extra[idx];
++				    break;
++				  }
++
++				/* Next entry.  */
++				elem += second;
++			      }
++
++			    if (symb_table[2 * elem] == 0)
++			      /* This is no valid character.  */
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Now add the multibyte character(s) we found
++			       to the accept list.
++
++			       XXX Note that this is not entirely correct.
++			       we would have to match multibyte sequences
++			       but this is not possible with the current
++			       implementation.  Also, we have to match
++			       collating symbols, which expand to more than
++			       one file, as a whole and not allow the
++			       individual bytes.  */
++			    c1 = extra[idx++];
++			    if (c1 == 1)
++			      range_start = extra[idx];
++			    while (c1-- > 0)
++			      {
++				SET_LIST_BIT (extra[idx]);
++				++idx;
++			      }
++			  }
++# endif
++			had_char_class = false;
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT ('.');
++			range_start = '.';
++                        had_char_class = false;
++                      }
++		  }
++                else
++                  {
++                    had_char_class = false;
++                    SET_LIST_BIT (c);
++		    range_start = c;
++                  }
++              }
++
++            /* Discard any (non)matching list bytes that are all 0 at the
++               end of the map.  Decrease the map-length byte too.  */
++            while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
++              b[-1]--;
++            b += b[-1];
++#endif /* WCHAR */
++          }
++          break;
++
++
++	case '(':
++          if (syntax & RE_NO_BK_PARENS)
++            goto handle_open;
++          else
++            goto normal_char;
++
++
++        case ')':
++          if (syntax & RE_NO_BK_PARENS)
++            goto handle_close;
++          else
++            goto normal_char;
++
++
++        case '\n':
++          if (syntax & RE_NEWLINE_ALT)
++            goto handle_alt;
++          else
++            goto normal_char;
++
++
++	case '|':
++          if (syntax & RE_NO_BK_VBAR)
++            goto handle_alt;
++          else
++            goto normal_char;
++
++
++        case '{':
++           if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
++             goto handle_interval;
++           else
++             goto normal_char;
++
++
++        case '\\':
++          if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++          /* Do not translate the character after the \, so that we can
++             distinguish, e.g., \B from \b, even if we normally would
++             translate, e.g., B to b.  */
++          PATFETCH_RAW (c);
++
++          switch (c)
++            {
++            case '(':
++              if (syntax & RE_NO_BK_PARENS)
++                goto normal_backslash;
++
++            handle_open:
++              bufp->re_nsub++;
++              regnum++;
++
++              if (COMPILE_STACK_FULL)
++                {
++                  RETALLOC (compile_stack.stack, compile_stack.size << 1,
++                            compile_stack_elt_t);
++                  if (compile_stack.stack == NULL) return REG_ESPACE;
++
++                  compile_stack.size <<= 1;
++                }
++
++              /* These are the values to restore when we hit end of this
++                 group.  They are all relative offsets, so that if the
++                 whole pattern moves because of realloc, they will still
++                 be valid.  */
++              COMPILE_STACK_TOP.begalt_offset = begalt - COMPILED_BUFFER_VAR;
++              COMPILE_STACK_TOP.fixup_alt_jump
++                = fixup_alt_jump ? fixup_alt_jump - COMPILED_BUFFER_VAR + 1 : 0;
++              COMPILE_STACK_TOP.laststart_offset = b - COMPILED_BUFFER_VAR;
++              COMPILE_STACK_TOP.regnum = regnum;
++
++              /* We will eventually replace the 0 with the number of
++                 groups inner to this one.  But do not push a
++                 start_memory for groups beyond the last one we can
++                 represent in the compiled pattern.  */
++              if (regnum <= MAX_REGNUM)
++                {
++                  COMPILE_STACK_TOP.inner_group_offset = b
++		    - COMPILED_BUFFER_VAR + 2;
++                  BUF_PUSH_3 (start_memory, regnum, 0);
++                }
++
++              compile_stack.avail++;
++
++              fixup_alt_jump = 0;
++              laststart = 0;
++              begalt = b;
++	      /* If we've reached MAX_REGNUM groups, then this open
++		 won't actually generate any code, so we'll have to
++		 clear pending_exact explicitly.  */
++	      pending_exact = 0;
++              break;
++
++
++            case ')':
++              if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
++
++              if (COMPILE_STACK_EMPTY)
++		{
++		  if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
++		    goto normal_backslash;
++		  else
++		    FREE_STACK_RETURN (REG_ERPAREN);
++		}
++
++            handle_close:
++              if (fixup_alt_jump)
++                { /* Push a dummy failure point at the end of the
++                     alternative for a possible future
++                     `pop_failure_jump' to pop.  See comments at
++                     `push_dummy_failure' in `re_match_2'.  */
++                  BUF_PUSH (push_dummy_failure);
++
++                  /* We allocated space for this jump when we assigned
++                     to `fixup_alt_jump', in the `handle_alt' case below.  */
++                  STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
++                }
++
++              /* See similar code for backslashed left paren above.  */
++              if (COMPILE_STACK_EMPTY)
++		{
++		  if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
++		    goto normal_char;
++		  else
++		    FREE_STACK_RETURN (REG_ERPAREN);
++		}
++
++              /* Since we just checked for an empty stack above, this
++                 ``can't happen''.  */
++              assert (compile_stack.avail != 0);
++              {
++                /* We don't just want to restore into `regnum', because
++                   later groups should continue to be numbered higher,
++                   as in `(ab)c(de)' -- the second group is #2.  */
++                regnum_t this_group_regnum;
++
++                compile_stack.avail--;
++                begalt = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.begalt_offset;
++                fixup_alt_jump
++                  = COMPILE_STACK_TOP.fixup_alt_jump
++                    ? COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.fixup_alt_jump - 1
++                    : 0;
++                laststart = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.laststart_offset;
++                this_group_regnum = COMPILE_STACK_TOP.regnum;
++		/* If we've reached MAX_REGNUM groups, then this open
++		   won't actually generate any code, so we'll have to
++		   clear pending_exact explicitly.  */
++		pending_exact = 0;
++
++                /* We're at the end of the group, so now we know how many
++                   groups were inside this one.  */
++                if (this_group_regnum <= MAX_REGNUM)
++                  {
++		    UCHAR_T *inner_group_loc
++                      = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.inner_group_offset;
++
++                    *inner_group_loc = regnum - this_group_regnum;
++                    BUF_PUSH_3 (stop_memory, this_group_regnum,
++                                regnum - this_group_regnum);
++                  }
++              }
++              break;
++
++
++            case '|':					/* `\|'.  */
++              if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
++                goto normal_backslash;
++            handle_alt:
++              if (syntax & RE_LIMITED_OPS)
++                goto normal_char;
++
++              /* Insert before the previous alternative a jump which
++                 jumps to this alternative if the former fails.  */
++              GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++              INSERT_JUMP (on_failure_jump, begalt,
++			   b + 2 + 2 * OFFSET_ADDRESS_SIZE);
++              pending_exact = 0;
++              b += 1 + OFFSET_ADDRESS_SIZE;
++
++              /* The alternative before this one has a jump after it
++                 which gets executed if it gets matched.  Adjust that
++                 jump so it will jump to this alternative's analogous
++                 jump (put in below, which in turn will jump to the next
++                 (if any) alternative's such jump, etc.).  The last such
++                 jump jumps to the correct final destination.  A picture:
++                          _____ _____
++                          |   | |   |
++                          |   v |   v
++                         a | b   | c
++
++                 If we are at `b', then fixup_alt_jump right now points to a
++                 three-byte space after `a'.  We'll put in the jump, set
++                 fixup_alt_jump to right after `b', and leave behind three
++                 bytes which we'll fill in when we get to after `c'.  */
++
++              if (fixup_alt_jump)
++                STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
++
++              /* Mark and leave space for a jump after this alternative,
++                 to be filled in later either by next alternative or
++                 when know we're at the end of a series of alternatives.  */
++              fixup_alt_jump = b;
++              GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++              b += 1 + OFFSET_ADDRESS_SIZE;
++
++              laststart = 0;
++              begalt = b;
++              break;
++
++
++            case '{':
++              /* If \{ is a literal.  */
++              if (!(syntax & RE_INTERVALS)
++                     /* If we're at `\{' and it's not the open-interval
++                        operator.  */
++		  || (syntax & RE_NO_BK_BRACES))
++                goto normal_backslash;
++
++            handle_interval:
++              {
++                /* If got here, then the syntax allows intervals.  */
++
++                /* At least (most) this many matches must be made.  */
++                int lower_bound = -1, upper_bound = -1;
++
++		/* Place in the uncompiled pattern (i.e., just after
++		   the '{') to go back to if the interval is invalid.  */
++		const CHAR_T *beg_interval = p;
++
++                if (p == pend)
++		  goto invalid_interval;
++
++                GET_UNSIGNED_NUMBER (lower_bound);
++
++                if (c == ',')
++                  {
++                    GET_UNSIGNED_NUMBER (upper_bound);
++		    if (upper_bound < 0)
++		      upper_bound = RE_DUP_MAX;
++                  }
++                else
++                  /* Interval such as `{1}' => match exactly once. */
++                  upper_bound = lower_bound;
++
++                if (! (0 <= lower_bound && lower_bound <= upper_bound))
++		  goto invalid_interval;
++
++                if (!(syntax & RE_NO_BK_BRACES))
++                  {
++		    if (c != '\\' || p == pend)
++		      goto invalid_interval;
++                    PATFETCH (c);
++                  }
++
++                if (c != '}')
++		  goto invalid_interval;
++
++                /* If it's invalid to have no preceding re.  */
++                if (!laststart)
++                  {
++		    if (syntax & RE_CONTEXT_INVALID_OPS
++			&& !(syntax & RE_INVALID_INTERVAL_ORD))
++                      FREE_STACK_RETURN (REG_BADRPT);
++                    else if (syntax & RE_CONTEXT_INDEP_OPS)
++                      laststart = b;
++                    else
++                      goto unfetch_interval;
++                  }
++
++                /* We just parsed a valid interval.  */
++
++                if (RE_DUP_MAX < upper_bound)
++		  FREE_STACK_RETURN (REG_BADBR);
++
++                /* If the upper bound is zero, don't want to succeed at
++                   all; jump from `laststart' to `b + 3', which will be
++		   the end of the buffer after we insert the jump.  */
++		/* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE'
++		   instead of 'b + 3'.  */
++                 if (upper_bound == 0)
++                   {
++                     GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++                     INSERT_JUMP (jump, laststart, b + 1
++				  + OFFSET_ADDRESS_SIZE);
++                     b += 1 + OFFSET_ADDRESS_SIZE;
++                   }
++
++                 /* Otherwise, we have a nontrivial interval.  When
++                    we're all done, the pattern will look like:
++                      set_number_at <jump count> <upper bound>
++                      set_number_at <succeed_n count> <lower bound>
++                      succeed_n <after jump addr> <succeed_n count>
++                      <body of loop>
++                      jump_n <succeed_n addr> <jump count>
++                    (The upper bound and `jump_n' are omitted if
++                    `upper_bound' is 1, though.)  */
++                 else
++                   { /* If the upper bound is > 1, we need to insert
++                        more at the end of the loop.  */
++                     unsigned nbytes = 2 + 4 * OFFSET_ADDRESS_SIZE +
++		       (upper_bound > 1) * (2 + 4 * OFFSET_ADDRESS_SIZE);
++
++                     GET_BUFFER_SPACE (nbytes);
++
++                     /* Initialize lower bound of the `succeed_n', even
++                        though it will be set during matching by its
++                        attendant `set_number_at' (inserted next),
++                        because `re_compile_fastmap' needs to know.
++                        Jump to the `jump_n' we might insert below.  */
++                     INSERT_JUMP2 (succeed_n, laststart,
++                                   b + 1 + 2 * OFFSET_ADDRESS_SIZE
++				   + (upper_bound > 1) * (1 + 2 * OFFSET_ADDRESS_SIZE)
++				   , lower_bound);
++                     b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                     /* Code to initialize the lower bound.  Insert
++                        before the `succeed_n'.  The `5' is the last two
++                        bytes of this `set_number_at', plus 3 bytes of
++                        the following `succeed_n'.  */
++		     /* ifdef WCHAR, The '1+2*OFFSET_ADDRESS_SIZE'
++			is the 'set_number_at', plus '1+OFFSET_ADDRESS_SIZE'
++			of the following `succeed_n'.  */
++                     PREFIX(insert_op2) (set_number_at, laststart, 1
++				 + 2 * OFFSET_ADDRESS_SIZE, lower_bound, b);
++                     b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                     if (upper_bound > 1)
++                       { /* More than one repetition is allowed, so
++                            append a backward jump to the `succeed_n'
++                            that starts this interval.
++
++                            When we've reached this during matching,
++                            we'll have matched the interval once, so
++                            jump back only `upper_bound - 1' times.  */
++                         STORE_JUMP2 (jump_n, b, laststart
++				      + 2 * OFFSET_ADDRESS_SIZE + 1,
++                                      upper_bound - 1);
++                         b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                         /* The location we want to set is the second
++                            parameter of the `jump_n'; that is `b-2' as
++                            an absolute address.  `laststart' will be
++                            the `set_number_at' we're about to insert;
++                            `laststart+3' the number to set, the source
++                            for the relative address.  But we are
++                            inserting into the middle of the pattern --
++                            so everything is getting moved up by 5.
++                            Conclusion: (b - 2) - (laststart + 3) + 5,
++                            i.e., b - laststart.
++
++                            We insert this at the beginning of the loop
++                            so that if we fail during matching, we'll
++                            reinitialize the bounds.  */
++                         PREFIX(insert_op2) (set_number_at, laststart,
++					     b - laststart,
++					     upper_bound - 1, b);
++                         b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++                       }
++                   }
++                pending_exact = 0;
++		break;
++
++	      invalid_interval:
++		if (!(syntax & RE_INVALID_INTERVAL_ORD))
++		  FREE_STACK_RETURN (p == pend ? REG_EBRACE : REG_BADBR);
++	      unfetch_interval:
++		/* Match the characters as literals.  */
++		p = beg_interval;
++		c = '{';
++		if (syntax & RE_NO_BK_BRACES)
++		  goto normal_char;
++		else
++		  goto normal_backslash;
++	      }
++
++#ifdef emacs
++            /* There is no way to specify the before_dot and after_dot
++               operators.  rms says this is ok.  --karl  */
++            case '=':
++              BUF_PUSH (at_dot);
++              break;
++
++            case 's':
++              laststart = b;
++              PATFETCH (c);
++              BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
++              break;
++
++            case 'S':
++              laststart = b;
++              PATFETCH (c);
++              BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
++              break;
++#endif /* emacs */
++
++
++            case 'w':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              laststart = b;
++              BUF_PUSH (wordchar);
++              break;
++
++
++            case 'W':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              laststart = b;
++              BUF_PUSH (notwordchar);
++              break;
++
++
++            case '<':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordbeg);
++              break;
++
++            case '>':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordend);
++              break;
++
++            case 'b':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordbound);
++              break;
++
++            case 'B':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (notwordbound);
++              break;
++
++            case '`':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (begbuf);
++              break;
++
++            case '\'':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (endbuf);
++              break;
++
++            case '1': case '2': case '3': case '4': case '5':
++            case '6': case '7': case '8': case '9':
++              if (syntax & RE_NO_BK_REFS)
++                goto normal_char;
++
++              c1 = c - '0';
++
++              if (c1 > regnum)
++                FREE_STACK_RETURN (REG_ESUBREG);
++
++              /* Can't back reference to a subexpression if inside of it.  */
++              if (group_in_compile_stack (compile_stack, (regnum_t) c1))
++                goto normal_char;
++
++              laststart = b;
++              BUF_PUSH_2 (duplicate, c1);
++              break;
++
++
++            case '+':
++            case '?':
++              if (syntax & RE_BK_PLUS_QM)
++                goto handle_plus;
++              else
++                goto normal_backslash;
++
++            default:
++            normal_backslash:
++              /* You might think it would be useful for \ to mean
++                 not to translate; but if we don't translate it
++                 it will never match anything.  */
++              c = TRANSLATE (c);
++              goto normal_char;
++            }
++          break;
++
++
++	default:
++        /* Expects the character in `c'.  */
++	normal_char:
++	      /* If no exactn currently being built.  */
++          if (!pending_exact
++#ifdef WCHAR
++	      /* If last exactn handle binary(or character) and
++		 new exactn handle character(or binary).  */
++	      || is_exactn_bin != is_binary[p - 1 - pattern]
++#endif /* WCHAR */
++
++              /* If last exactn not at current position.  */
++              || pending_exact + *pending_exact + 1 != b
++
++              /* We have only one byte following the exactn for the count.  */
++	      || *pending_exact == (1 << BYTEWIDTH) - 1
++
++              /* If followed by a repetition operator.  */
++              || *p == '*' || *p == '^'
++	      || ((syntax & RE_BK_PLUS_QM)
++		  ? *p == '\\' && (p[1] == '+' || p[1] == '?')
++		  : (*p == '+' || *p == '?'))
++	      || ((syntax & RE_INTERVALS)
++                  && ((syntax & RE_NO_BK_BRACES)
++		      ? *p == '{'
++                      : (p[0] == '\\' && p[1] == '{'))))
++	    {
++	      /* Start building a new exactn.  */
++
++              laststart = b;
++
++#ifdef WCHAR
++	      /* Is this exactn binary data or character? */
++	      is_exactn_bin = is_binary[p - 1 - pattern];
++	      if (is_exactn_bin)
++		  BUF_PUSH_2 (exactn_bin, 0);
++	      else
++		  BUF_PUSH_2 (exactn, 0);
++#else
++	      BUF_PUSH_2 (exactn, 0);
++#endif /* WCHAR */
++	      pending_exact = b - 1;
++            }
++
++	  BUF_PUSH (c);
++          (*pending_exact)++;
++	  break;
++        } /* switch (c) */
++    } /* while p != pend */
++
++
++  /* Through the pattern now.  */
++
++  if (fixup_alt_jump)
++    STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
++
++  if (!COMPILE_STACK_EMPTY)
++    FREE_STACK_RETURN (REG_EPAREN);
++
++  /* If we don't want backtracking, force success
++     the first time we reach the end of the compiled pattern.  */
++  if (syntax & RE_NO_POSIX_BACKTRACKING)
++    BUF_PUSH (succeed);
++
++#ifdef WCHAR
++  free (pattern);
++  free (mbs_offset);
++  free (is_binary);
++#endif
++  free (compile_stack.stack);
++
++  /* We have succeeded; set the length of the buffer.  */
++#ifdef WCHAR
++  bufp->used = (uintptr_t) b - (uintptr_t) COMPILED_BUFFER_VAR;
++#else
++  bufp->used = b - bufp->buffer;
++#endif
++
++#ifdef DEBUG
++  if (debug)
++    {
++      DEBUG_PRINT1 ("\nCompiled pattern: \n");
++      PREFIX(print_compiled_pattern) (bufp);
++    }
++#endif /* DEBUG */
++
++#ifndef MATCH_MAY_ALLOCATE
++  /* Initialize the failure stack to the largest possible stack.  This
++     isn't necessary unless we're trying to avoid calling alloca in
++     the search and match routines.  */
++  {
++    int num_regs = bufp->re_nsub + 1;
++
++    /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
++       is strictly greater than re_max_failures, the largest possible stack
++       is 2 * re_max_failures failure points.  */
++    if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
++      {
++	fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
++
++# ifdef emacs
++	if (! fail_stack.stack)
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) xmalloc (fail_stack.size
++				    * sizeof (PREFIX(fail_stack_elt_t)));
++	else
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) xrealloc (fail_stack.stack,
++				     (fail_stack.size
++				      * sizeof (PREFIX(fail_stack_elt_t))));
++# else /* not emacs */
++	if (! fail_stack.stack)
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) malloc (fail_stack.size
++				   * sizeof (PREFIX(fail_stack_elt_t)));
++	else
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) realloc (fail_stack.stack,
++					    (fail_stack.size
++				     * sizeof (PREFIX(fail_stack_elt_t))));
++# endif /* not emacs */
++      }
++
++   PREFIX(regex_grow_registers) (num_regs);
++  }
++#endif /* not MATCH_MAY_ALLOCATE */
++
++  return REG_NOERROR;
++} /* regex_compile */
++
++/* Subroutines for `regex_compile'.  */
++
++/* Store OP at LOC followed by two-byte integer parameter ARG.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg)
++{
++  *loc = (UCHAR_T) op;
++  STORE_NUMBER (loc + 1, arg);
++}
++
++
++/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2)
++{
++  *loc = (UCHAR_T) op;
++  STORE_NUMBER (loc + 1, arg1);
++  STORE_NUMBER (loc + 1 + OFFSET_ADDRESS_SIZE, arg2);
++}
++
++
++/* Copy the bytes from LOC to END to open up three bytes of space at LOC
++   for OP followed by two-byte integer parameter ARG.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end)
++{
++  register UCHAR_T *pfrom = end;
++  register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE;
++
++  while (pfrom != loc)
++    *--pto = *--pfrom;
++
++  PREFIX(store_op1) (op, loc, arg);
++}
++
++
++/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1,
++                    int arg2, UCHAR_T *end)
++{
++  register UCHAR_T *pfrom = end;
++  register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++  while (pfrom != loc)
++    *--pto = *--pfrom;
++
++  PREFIX(store_op2) (op, loc, arg1, arg2);
++}
++
++
++/* P points to just after a ^ in PATTERN.  Return true if that ^ comes
++   after an alternative or a begin-subexpression.  We assume there is at
++   least one character before the ^.  */
++
++static boolean
++PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p,
++                          reg_syntax_t syntax)
++{
++  const CHAR_T *prev = p - 2;
++  boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
++
++  return
++       /* After a subexpression?  */
++       (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
++       /* After an alternative?  */
++    || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
++}
++
++
++/* The dual of at_begline_loc_p.  This one is for $.  We assume there is
++   at least one character after the $, i.e., `P < PEND'.  */
++
++static boolean
++PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend,
++                          reg_syntax_t syntax)
++{
++  const CHAR_T *next = p;
++  boolean next_backslash = *next == '\\';
++  const CHAR_T *next_next = p + 1 < pend ? p + 1 : 0;
++
++  return
++       /* Before a subexpression?  */
++       (syntax & RE_NO_BK_PARENS ? *next == ')'
++        : next_backslash && next_next && *next_next == ')')
++       /* Before an alternative?  */
++    || (syntax & RE_NO_BK_VBAR ? *next == '|'
++        : next_backslash && next_next && *next_next == '|');
++}
++
++#else /* not INSIDE_RECURSION */
++
++/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
++   false if it's not.  */
++
++static boolean
++group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
++{
++  int this_element;
++
++  for (this_element = compile_stack.avail - 1;
++       this_element >= 0;
++       this_element--)
++    if (compile_stack.stack[this_element].regnum == regnum)
++      return true;
++
++  return false;
++}
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef WCHAR
++/* This insert space, which size is "num", into the pattern at "loc".
++   "end" must point the end of the allocated buffer.  */
++static void
++insert_space (int num, CHAR_T *loc, CHAR_T *end)
++{
++  register CHAR_T *pto = end;
++  register CHAR_T *pfrom = end - num;
++
++  while (pfrom >= loc)
++    *pto-- = *pfrom--;
++}
++#endif /* WCHAR */
++
++#ifdef WCHAR
++static reg_errcode_t
++wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr,
++                   const CHAR_T *pend, RE_TRANSLATE_TYPE translate,
++                   reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set)
++{
++  const CHAR_T *p = *p_ptr;
++  CHAR_T range_start, range_end;
++  reg_errcode_t ret;
++# ifdef _LIBC
++  uint32_t nrules;
++  uint32_t start_val, end_val;
++# endif
++  if (p == pend)
++    return REG_ERANGE;
++
++# ifdef _LIBC
++  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++  if (nrules != 0)
++    {
++      const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE,
++						       _NL_COLLATE_COLLSEQWC);
++      const unsigned char *extra = (const unsigned char *)
++	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
++
++      if (range_start_char < -1)
++	{
++	  /* range_start is a collating symbol.  */
++	  int32_t *wextra;
++	  /* Retreive the index and get collation sequence value.  */
++	  wextra = (int32_t*)(extra + char_set[-range_start_char]);
++	  start_val = wextra[1 + *wextra];
++	}
++      else
++	start_val = collseq_table_lookup(collseq, TRANSLATE(range_start_char));
++
++      end_val = collseq_table_lookup (collseq, TRANSLATE (p[0]));
++
++      /* Report an error if the range is empty and the syntax prohibits
++	 this.  */
++      ret = ((syntax & RE_NO_EMPTY_RANGES)
++	     && (start_val > end_val))? REG_ERANGE : REG_NOERROR;
++
++      /* Insert space to the end of the char_ranges.  */
++      insert_space(2, b - char_set[5] - 2, b - 1);
++      *(b - char_set[5] - 2) = (wchar_t)start_val;
++      *(b - char_set[5] - 1) = (wchar_t)end_val;
++      char_set[4]++; /* ranges_index */
++    }
++  else
++# endif
++    {
++      range_start = (range_start_char >= 0)? TRANSLATE (range_start_char):
++	range_start_char;
++      range_end = TRANSLATE (p[0]);
++      /* Report an error if the range is empty and the syntax prohibits
++	 this.  */
++      ret = ((syntax & RE_NO_EMPTY_RANGES)
++	     && (range_start > range_end))? REG_ERANGE : REG_NOERROR;
++
++      /* Insert space to the end of the char_ranges.  */
++      insert_space(2, b - char_set[5] - 2, b - 1);
++      *(b - char_set[5] - 2) = range_start;
++      *(b - char_set[5] - 1) = range_end;
++      char_set[4]++; /* ranges_index */
++    }
++  /* Have to increment the pointer into the pattern string, so the
++     caller isn't still at the ending character.  */
++  (*p_ptr)++;
++
++  return ret;
++}
++#else /* BYTE */
++/* Read the ending character of a range (in a bracket expression) from the
++   uncompiled pattern *P_PTR (which ends at PEND).  We assume the
++   starting character is in `P[-2]'.  (`P[-1]' is the character `-'.)
++   Then we set the translation of all bits between the starting and
++   ending characters (inclusive) in the compiled pattern B.
++
++   Return an error code.
++
++   We use these short variable names so we can use the same macros as
++   `regex_compile' itself.  */
++
++static reg_errcode_t
++byte_compile_range (unsigned int range_start_char, const char **p_ptr,
++                    const char *pend, RE_TRANSLATE_TYPE translate,
++                    reg_syntax_t syntax, unsigned char *b)
++{
++  unsigned this_char;
++  const char *p = *p_ptr;
++  reg_errcode_t ret;
++# if _LIBC
++  const unsigned char *collseq;
++  unsigned int start_colseq;
++  unsigned int end_colseq;
++# else
++  unsigned end_char;
++# endif
++
++  if (p == pend)
++    return REG_ERANGE;
++
++  /* Have to increment the pointer into the pattern string, so the
++     caller isn't still at the ending character.  */
++  (*p_ptr)++;
++
++  /* Report an error if the range is empty and the syntax prohibits this.  */
++  ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
++
++# if _LIBC
++  collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
++						 _NL_COLLATE_COLLSEQMB);
++
++  start_colseq = collseq[(unsigned char) TRANSLATE (range_start_char)];
++  end_colseq = collseq[(unsigned char) TRANSLATE (p[0])];
++  for (this_char = 0; this_char <= (unsigned char) -1; ++this_char)
++    {
++      unsigned int this_colseq = collseq[(unsigned char) TRANSLATE (this_char)];
++
++      if (start_colseq <= this_colseq && this_colseq <= end_colseq)
++	{
++	  SET_LIST_BIT (TRANSLATE (this_char));
++	  ret = REG_NOERROR;
++	}
++    }
++# else
++  /* Here we see why `this_char' has to be larger than an `unsigned
++     char' -- we would otherwise go into an infinite loop, since all
++     characters <= 0xff.  */
++  range_start_char = TRANSLATE (range_start_char);
++  /* TRANSLATE(p[0]) is casted to char (not unsigned char) in TRANSLATE,
++     and some compilers cast it to int implicitly, so following for_loop
++     may fall to (almost) infinite loop.
++     e.g. If translate[p[0]] = 0xff, end_char may equals to 0xffffffff.
++     To avoid this, we cast p[0] to unsigned int and truncate it.  */
++  end_char = ((unsigned)TRANSLATE(p[0]) & ((1 << BYTEWIDTH) - 1));
++
++  for (this_char = range_start_char; this_char <= end_char; ++this_char)
++    {
++      SET_LIST_BIT (TRANSLATE (this_char));
++      ret = REG_NOERROR;
++    }
++# endif
++
++  return ret;
++}
++#endif /* WCHAR */
++\f
++/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
++   BUFP.  A fastmap records which of the (1 << BYTEWIDTH) possible
++   characters can start a string that matches the pattern.  This fastmap
++   is used by re_search to skip quickly over impossible starting points.
++
++   The caller must supply the address of a (1 << BYTEWIDTH)-byte data
++   area as BUFP->fastmap.
++
++   We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
++   the pattern buffer.
++
++   Returns 0 if we succeed, -2 if an internal error.   */
++
++#ifdef WCHAR
++/* local function for re_compile_fastmap.
++   truncate wchar_t character to char.  */
++static unsigned char truncate_wchar (CHAR_T c);
++
++static unsigned char
++truncate_wchar (CHAR_T c)
++{
++  unsigned char buf[MB_CUR_MAX];
++  mbstate_t state;
++  int retval;
++  memset (&state, '\0', sizeof (state));
++# ifdef _LIBC
++  retval = __wcrtomb (buf, c, &state);
++# else
++  retval = wcrtomb (buf, c, &state);
++# endif
++  return retval > 0 ? buf[0] : (unsigned char) c;
++}
++#endif /* WCHAR */
++
++static int
++PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp)
++{
++  int j, k;
++#ifdef MATCH_MAY_ALLOCATE
++  PREFIX(fail_stack_type) fail_stack;
++#endif
++#ifndef REGEX_MALLOC
++  char *destination;
++#endif
++
++  register char *fastmap = bufp->fastmap;
++
++#ifdef WCHAR
++  /* We need to cast pattern to (wchar_t*), because we casted this compiled
++     pattern to (char*) in regex_compile.  */
++  UCHAR_T *pattern = (UCHAR_T*)bufp->buffer;
++  register UCHAR_T *pend = (UCHAR_T*) (bufp->buffer + bufp->used);
++#else /* BYTE */
++  UCHAR_T *pattern = bufp->buffer;
++  register UCHAR_T *pend = pattern + bufp->used;
++#endif /* WCHAR */
++  UCHAR_T *p = pattern;
++
++#ifdef REL_ALLOC
++  /* This holds the pointer to the failure stack, when
++     it is allocated relocatably.  */
++  fail_stack_elt_t *failure_stack_ptr;
++#endif
++
++  /* Assume that each path through the pattern can be null until
++     proven otherwise.  We set this false at the bottom of switch
++     statement, to which we get only if a particular path doesn't
++     match the empty string.  */
++  boolean path_can_be_null = true;
++
++  /* We aren't doing a `succeed_n' to begin with.  */
++  boolean succeed_n_p = false;
++
++  assert (fastmap != NULL && p != NULL);
++
++  INIT_FAIL_STACK ();
++  bzero (fastmap, 1 << BYTEWIDTH);  /* Assume nothing's valid.  */
++  bufp->fastmap_accurate = 1;	    /* It will be when we're done.  */
++  bufp->can_be_null = 0;
++
++  while (1)
++    {
++      if (p == pend || *p == (UCHAR_T) succeed)
++	{
++	  /* We have reached the (effective) end of pattern.  */
++	  if (!FAIL_STACK_EMPTY ())
++	    {
++	      bufp->can_be_null |= path_can_be_null;
++
++	      /* Reset for next path.  */
++	      path_can_be_null = true;
++
++	      p = fail_stack.stack[--fail_stack.avail].pointer;
++
++	      continue;
++	    }
++	  else
++	    break;
++	}
++
++      /* We should never be about to go beyond the end of the pattern.  */
++      assert (p < pend);
++
++      switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
++	{
++
++        /* I guess the idea here is to simply not bother with a fastmap
++           if a backreference is used, since it's too hard to figure out
++           the fastmap for the corresponding group.  Setting
++           `can_be_null' stops `re_search_2' from using the fastmap, so
++           that is all we do.  */
++	case duplicate:
++	  bufp->can_be_null = 1;
++          goto done;
++
++
++      /* Following are the cases which match a character.  These end
++         with `break'.  */
++
++#ifdef WCHAR
++	case exactn:
++          fastmap[truncate_wchar(p[1])] = 1;
++	  break;
++#else /* BYTE */
++	case exactn:
++          fastmap[p[1]] = 1;
++	  break;
++#endif /* WCHAR */
++#ifdef MBS_SUPPORT
++	case exactn_bin:
++	  fastmap[p[1]] = 1;
++	  break;
++#endif
++
++#ifdef WCHAR
++        /* It is hard to distinguish fastmap from (multi byte) characters
++           which depends on current locale.  */
++        case charset:
++	case charset_not:
++	case wordchar:
++	case notwordchar:
++          bufp->can_be_null = 1;
++          goto done;
++#else /* BYTE */
++        case charset:
++          for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
++	    if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
++              fastmap[j] = 1;
++	  break;
++
++
++	case charset_not:
++	  /* Chars beyond end of map must be allowed.  */
++	  for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
++            fastmap[j] = 1;
++
++	  for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
++	    if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
++              fastmap[j] = 1;
++          break;
++
++
++	case wordchar:
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) == Sword)
++	      fastmap[j] = 1;
++	  break;
++
++
++	case notwordchar:
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) != Sword)
++	      fastmap[j] = 1;
++	  break;
++#endif /* WCHAR */
++
++        case anychar:
++	  {
++	    int fastmap_newline = fastmap['\n'];
++
++	    /* `.' matches anything ...  */
++	    for (j = 0; j < (1 << BYTEWIDTH); j++)
++	      fastmap[j] = 1;
++
++	    /* ... except perhaps newline.  */
++	    if (!(bufp->syntax & RE_DOT_NEWLINE))
++	      fastmap['\n'] = fastmap_newline;
++
++	    /* Return if we have already set `can_be_null'; if we have,
++	       then the fastmap is irrelevant.  Something's wrong here.  */
++	    else if (bufp->can_be_null)
++	      goto done;
++
++	    /* Otherwise, have to check alternative paths.  */
++	    break;
++	  }
++
++#ifdef emacs
++        case syntaxspec:
++	  k = *p++;
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) == (enum syntaxcode) k)
++	      fastmap[j] = 1;
++	  break;
++
++
++	case notsyntaxspec:
++	  k = *p++;
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) != (enum syntaxcode) k)
++	      fastmap[j] = 1;
++	  break;
++
++
++      /* All cases after this match the empty string.  These end with
++         `continue'.  */
++
++
++	case before_dot:
++	case at_dot:
++	case after_dot:
++          continue;
++#endif /* emacs */
++
++
++        case no_op:
++        case begline:
++        case endline:
++	case begbuf:
++	case endbuf:
++	case wordbound:
++	case notwordbound:
++	case wordbeg:
++	case wordend:
++        case push_dummy_failure:
++          continue;
++
++
++	case jump_n:
++        case pop_failure_jump:
++	case maybe_pop_jump:
++	case jump:
++        case jump_past_alt:
++	case dummy_failure_jump:
++          EXTRACT_NUMBER_AND_INCR (j, p);
++	  p += j;
++	  if (j > 0)
++	    continue;
++
++          /* Jump backward implies we just went through the body of a
++             loop and matched nothing.  Opcode jumped to should be
++             `on_failure_jump' or `succeed_n'.  Just treat it like an
++             ordinary jump.  For a * loop, it has pushed its failure
++             point already; if so, discard that as redundant.  */
++          if ((re_opcode_t) *p != on_failure_jump
++	      && (re_opcode_t) *p != succeed_n)
++	    continue;
++
++          p++;
++          EXTRACT_NUMBER_AND_INCR (j, p);
++          p += j;
++
++          /* If what's on the stack is where we are now, pop it.  */
++          if (!FAIL_STACK_EMPTY ()
++	      && fail_stack.stack[fail_stack.avail - 1].pointer == p)
++            fail_stack.avail--;
++
++          continue;
++
++
++        case on_failure_jump:
++        case on_failure_keep_string_jump:
++	handle_on_failure_jump:
++          EXTRACT_NUMBER_AND_INCR (j, p);
++
++          /* For some patterns, e.g., `(a?)?', `p+j' here points to the
++             end of the pattern.  We don't want to push such a point,
++             since when we restore it above, entering the switch will
++             increment `p' past the end of the pattern.  We don't need
++             to push such a point since we obviously won't find any more
++             fastmap entries beyond `pend'.  Such a pattern can match
++             the null string, though.  */
++          if (p + j < pend)
++            {
++              if (!PUSH_PATTERN_OP (p + j, fail_stack))
++		{
++		  RESET_FAIL_STACK ();
++		  return -2;
++		}
++            }
++          else
++            bufp->can_be_null = 1;
++
++          if (succeed_n_p)
++            {
++              EXTRACT_NUMBER_AND_INCR (k, p);	/* Skip the n.  */
++              succeed_n_p = false;
++	    }
++
++          continue;
++
++
++	case succeed_n:
++          /* Get to the number of times to succeed.  */
++          p += OFFSET_ADDRESS_SIZE;
++
++          /* Increment p past the n for when k != 0.  */
++          EXTRACT_NUMBER_AND_INCR (k, p);
++          if (k == 0)
++	    {
++              p -= 2 * OFFSET_ADDRESS_SIZE;
++  	      succeed_n_p = true;  /* Spaghetti code alert.  */
++              goto handle_on_failure_jump;
++            }
++          continue;
++
++
++	case set_number_at:
++          p += 2 * OFFSET_ADDRESS_SIZE;
++          continue;
++
++
++	case start_memory:
++        case stop_memory:
++	  p += 2;
++	  continue;
++
++
++	default:
++          abort (); /* We have listed all the cases.  */
++        } /* switch *p++ */
++
++      /* Getting here means we have found the possible starting
++         characters for one path of the pattern -- and that the empty
++         string does not match.  We need not follow this path further.
++         Instead, look at the next alternative (remembered on the
++         stack), or quit if no more.  The test at the top of the loop
++         does these things.  */
++      path_can_be_null = false;
++      p = pend;
++    } /* while p */
++
++  /* Set `can_be_null' for the last path (also the first path, if the
++     pattern is empty).  */
++  bufp->can_be_null |= path_can_be_null;
++
++ done:
++  RESET_FAIL_STACK ();
++  return 0;
++}
++
++#else /* not INSIDE_RECURSION */
++
++int
++re_compile_fastmap (struct re_pattern_buffer *bufp)
++{
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    return wcs_re_compile_fastmap(bufp);
++  else
++# endif
++    return byte_re_compile_fastmap(bufp);
++} /* re_compile_fastmap */
++#ifdef _LIBC
++weak_alias (__re_compile_fastmap, re_compile_fastmap)
++#endif
++\f
++
++/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
++   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
++   this memory for recording register information.  STARTS and ENDS
++   must be allocated using the malloc library routine, and must each
++   be at least NUM_REGS * sizeof (regoff_t) bytes long.
++
++   If NUM_REGS == 0, then subsequent matches should allocate their own
++   register data.
++
++   Unless this function is called, the first search or match using
++   PATTERN_BUFFER will allocate its own register data, without
++   freeing the old data.  */
++
++void
++re_set_registers (struct re_pattern_buffer *bufp,
++                  struct re_registers *regs, unsigned num_regs,
++                  regoff_t *starts, regoff_t *ends)
++{
++  if (num_regs)
++    {
++      bufp->regs_allocated = REGS_REALLOCATE;
++      regs->num_regs = num_regs;
++      regs->start = starts;
++      regs->end = ends;
++    }
++  else
++    {
++      bufp->regs_allocated = REGS_UNALLOCATED;
++      regs->num_regs = 0;
++      regs->start = regs->end = (regoff_t *) 0;
++    }
++}
++#ifdef _LIBC
++weak_alias (__re_set_registers, re_set_registers)
++#endif
++\f
++/* Searching routines.  */
++
++/* Like re_search_2, below, but only one string is specified, and
++   doesn't let you say where to stop matching.  */
++
++int
++re_search (struct re_pattern_buffer *bufp, const char *string, int size,
++           int startpos, int range, struct re_registers *regs)
++{
++  return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
++		      regs, size);
++}
++#ifdef _LIBC
++weak_alias (__re_search, re_search)
++#endif
++
++
++/* Using the compiled pattern in BUFP->buffer, first tries to match the
++   virtual concatenation of STRING1 and STRING2, starting first at index
++   STARTPOS, then at STARTPOS + 1, and so on.
++
++   STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
++
++   RANGE is how far to scan while trying to match.  RANGE = 0 means try
++   only at STARTPOS; in general, the last start tried is STARTPOS +
++   RANGE.
++
++   In REGS, return the indices of the virtual concatenation of STRING1
++   and STRING2 that matched the entire BUFP->buffer and its contained
++   subexpressions.
++
++   Do not consider matching one past the index STOP in the virtual
++   concatenation of STRING1 and STRING2.
++
++   We return either the position in the strings at which the match was
++   found, -1 if no match, or -2 if error (such as failure
++   stack overflow).  */
++
++int
++re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
++             const char *string2, int size2, int startpos, int range,
++             struct re_registers *regs, int stop)
++{
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos,
++			    range, regs, stop);
++  else
++# endif
++    return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
++			     range, regs, stop);
++} /* re_search_2 */
++#ifdef _LIBC
++weak_alias (__re_search_2, re_search_2)
++#endif
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef MATCH_MAY_ALLOCATE
++# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
++#else
++# define FREE_VAR(var) if (var) free (var); var = NULL
++#endif
++
++#ifdef WCHAR
++# define MAX_ALLOCA_SIZE	2000
++
++# define FREE_WCS_BUFFERS() \
++  do {									      \
++    if (size1 > MAX_ALLOCA_SIZE)					      \
++      {									      \
++	free (wcs_string1);						      \
++	free (mbs_offset1);						      \
++      }									      \
++    else								      \
++      {									      \
++	FREE_VAR (wcs_string1);						      \
++	FREE_VAR (mbs_offset1);						      \
++      }									      \
++    if (size2 > MAX_ALLOCA_SIZE) 					      \
++      {									      \
++	free (wcs_string2);						      \
++	free (mbs_offset2);						      \
++      }									      \
++    else								      \
++      {									      \
++	FREE_VAR (wcs_string2);						      \
++	FREE_VAR (mbs_offset2);						      \
++      }									      \
++  } while (0)
++
++#endif
++
++
++static int
++PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1,
++                     int size1, const char *string2, int size2,
++                     int startpos, int range,
++                     struct re_registers *regs, int stop)
++{
++  int val;
++  register char *fastmap = bufp->fastmap;
++  register RE_TRANSLATE_TYPE translate = bufp->translate;
++  int total_size = size1 + size2;
++  int endpos = startpos + range;
++#ifdef WCHAR
++  /* We need wchar_t* buffers correspond to cstring1, cstring2.  */
++  wchar_t *wcs_string1 = NULL, *wcs_string2 = NULL;
++  /* We need the size of wchar_t buffers correspond to csize1, csize2.  */
++  int wcs_size1 = 0, wcs_size2 = 0;
++  /* offset buffer for optimizatoin. See convert_mbs_to_wc.  */
++  int *mbs_offset1 = NULL, *mbs_offset2 = NULL;
++  /* They hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++#endif /* WCHAR */
++
++  /* Check for out-of-range STARTPOS.  */
++  if (startpos < 0 || startpos > total_size)
++    return -1;
++
++  /* Fix up RANGE if it might eventually take us outside
++     the virtual concatenation of STRING1 and STRING2.
++     Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE.  */
++  if (endpos < 0)
++    range = 0 - startpos;
++  else if (endpos > total_size)
++    range = total_size - startpos;
++
++  /* If the search isn't to be a backwards one, don't waste time in a
++     search for a pattern that must be anchored.  */
++  if (bufp->used > 0 && range > 0
++      && ((re_opcode_t) bufp->buffer[0] == begbuf
++	  /* `begline' is like `begbuf' if it cannot match at newlines.  */
++	  || ((re_opcode_t) bufp->buffer[0] == begline
++	      && !bufp->newline_anchor)))
++    {
++      if (startpos > 0)
++	return -1;
++      else
++	range = 1;
++    }
++
++#ifdef emacs
++  /* In a forward search for something that starts with \=.
++     don't keep searching past point.  */
++  if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
++    {
++      range = PT - startpos;
++      if (range <= 0)
++	return -1;
++    }
++#endif /* emacs */
++
++  /* Update the fastmap now if not correct already.  */
++  if (fastmap && !bufp->fastmap_accurate)
++    if (re_compile_fastmap (bufp) == -2)
++      return -2;
++
++#ifdef WCHAR
++  /* Allocate wchar_t array for wcs_string1 and wcs_string2 and
++     fill them with converted string.  */
++  if (size1 != 0)
++    {
++      if (size1 > MAX_ALLOCA_SIZE)
++	{
++	  wcs_string1 = TALLOC (size1 + 1, CHAR_T);
++	  mbs_offset1 = TALLOC (size1 + 1, int);
++	  is_binary = TALLOC (size1 + 1, char);
++	}
++      else
++	{
++	  wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
++	  mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
++	  is_binary = REGEX_TALLOC (size1 + 1, char);
++	}
++      if (!wcs_string1 || !mbs_offset1 || !is_binary)
++	{
++	  if (size1 > MAX_ALLOCA_SIZE)
++	    {
++	      free (wcs_string1);
++	      free (mbs_offset1);
++	      free (is_binary);
++	    }
++	  else
++	    {
++	      FREE_VAR (wcs_string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (is_binary);
++	    }
++	  return -2;
++	}
++      wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1,
++				     mbs_offset1, is_binary);
++      wcs_string1[wcs_size1] = L'\0'; /* for a sentinel  */
++      if (size1 > MAX_ALLOCA_SIZE)
++	free (is_binary);
++      else
++	FREE_VAR (is_binary);
++    }
++  if (size2 != 0)
++    {
++      if (size2 > MAX_ALLOCA_SIZE)
++	{
++	  wcs_string2 = TALLOC (size2 + 1, CHAR_T);
++	  mbs_offset2 = TALLOC (size2 + 1, int);
++	  is_binary = TALLOC (size2 + 1, char);
++	}
++      else
++	{
++	  wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
++	  mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
++	  is_binary = REGEX_TALLOC (size2 + 1, char);
++	}
++      if (!wcs_string2 || !mbs_offset2 || !is_binary)
++	{
++	  FREE_WCS_BUFFERS ();
++	  if (size2 > MAX_ALLOCA_SIZE)
++	    free (is_binary);
++	  else
++	    FREE_VAR (is_binary);
++	  return -2;
++	}
++      wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2,
++				     mbs_offset2, is_binary);
++      wcs_string2[wcs_size2] = L'\0'; /* for a sentinel  */
++      if (size2 > MAX_ALLOCA_SIZE)
++	free (is_binary);
++      else
++	FREE_VAR (is_binary);
++    }
++#endif /* WCHAR */
++
++
++  /* Loop through the string, looking for a place to start matching.  */
++  for (;;)
++    {
++      /* If a fastmap is supplied, skip quickly over characters that
++         cannot be the start of a match.  If the pattern can match the
++         null string, however, we don't need to skip characters; we want
++         the first null string.  */
++      if (fastmap && startpos < total_size && !bufp->can_be_null)
++	{
++	  if (range > 0)	/* Searching forwards.  */
++	    {
++	      register const char *d;
++	      register int lim = 0;
++	      int irange = range;
++
++              if (startpos < size1 && startpos + range >= size1)
++                lim = range - (size1 - startpos);
++
++	      d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
++
++              /* Written out as an if-else to avoid testing `translate'
++                 inside the loop.  */
++	      if (translate)
++                while (range > lim
++                       && !fastmap[(unsigned char)
++				   translate[(unsigned char) *d++]])
++                  range--;
++	      else
++                while (range > lim && !fastmap[(unsigned char) *d++])
++                  range--;
++
++	      startpos += irange - range;
++	    }
++	  else				/* Searching backwards.  */
++	    {
++	      register CHAR_T c = (size1 == 0 || startpos >= size1
++				      ? string2[startpos - size1]
++				      : string1[startpos]);
++
++	      if (!fastmap[(unsigned char) TRANSLATE (c)])
++		goto advance;
++	    }
++	}
++
++      /* If can't match the null string, and that's all we have left, fail.  */
++      if (range >= 0 && startpos == total_size && fastmap
++          && !bufp->can_be_null)
++       {
++#ifdef WCHAR
++         FREE_WCS_BUFFERS ();
++#endif
++         return -1;
++       }
++
++#ifdef WCHAR
++      val = wcs_re_match_2_internal (bufp, string1, size1, string2,
++				     size2, startpos, regs, stop,
++				     wcs_string1, wcs_size1,
++				     wcs_string2, wcs_size2,
++				     mbs_offset1, mbs_offset2);
++#else /* BYTE */
++      val = byte_re_match_2_internal (bufp, string1, size1, string2,
++				      size2, startpos, regs, stop);
++#endif /* BYTE */
++
++#ifndef REGEX_MALLOC
++# ifdef C_ALLOCA
++      alloca (0);
++# endif
++#endif
++
++      if (val >= 0)
++	{
++#ifdef WCHAR
++	  FREE_WCS_BUFFERS ();
++#endif
++	  return startpos;
++	}
++
++      if (val == -2)
++	{
++#ifdef WCHAR
++	  FREE_WCS_BUFFERS ();
++#endif
++	  return -2;
++	}
++
++    advance:
++      if (!range)
++        break;
++      else if (range > 0)
++        {
++          range--;
++          startpos++;
++        }
++      else
++        {
++          range++;
++          startpos--;
++        }
++    }
++#ifdef WCHAR
++  FREE_WCS_BUFFERS ();
++#endif
++  return -1;
++}
++
++#ifdef WCHAR
++/* This converts PTR, a pointer into one of the search wchar_t strings
++   `string1' and `string2' into an multibyte string offset from the
++   beginning of that string. We use mbs_offset to optimize.
++   See convert_mbs_to_wcs.  */
++# define POINTER_TO_OFFSET(ptr)						\
++  (FIRST_STRING_P (ptr)							\
++   ? ((regoff_t)(mbs_offset1 != NULL? mbs_offset1[(ptr)-string1] : 0))	\
++   : ((regoff_t)((mbs_offset2 != NULL? mbs_offset2[(ptr)-string2] : 0)	\
++		 + csize1)))
++#else /* BYTE */
++/* This converts PTR, a pointer into one of the search strings `string1'
++   and `string2' into an offset from the beginning of that string.  */
++# define POINTER_TO_OFFSET(ptr)			\
++  (FIRST_STRING_P (ptr)				\
++   ? ((regoff_t) ((ptr) - string1))		\
++   : ((regoff_t) ((ptr) - string2 + size1)))
++#endif /* WCHAR */
++
++/* Macros for dealing with the split strings in re_match_2.  */
++
++#define MATCHING_IN_FIRST_STRING  (dend == end_match_1)
++
++/* Call before fetching a character with *d.  This switches over to
++   string2 if necessary.  */
++#define PREFETCH()							\
++  while (d == dend)						    	\
++    {									\
++      /* End of string2 => fail.  */					\
++      if (dend == end_match_2) 						\
++        goto fail;							\
++      /* End of string1 => advance to string2.  */ 			\
++      d = string2;						        \
++      dend = end_match_2;						\
++    }
++
++/* Test if at very beginning or at very end of the virtual concatenation
++   of `string1' and `string2'.  If only one string, it's `string2'.  */
++#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
++#define AT_STRINGS_END(d) ((d) == end2)
++
++
++/* Test if D points to a character which is word-constituent.  We have
++   two special cases to check for: if past the end of string1, look at
++   the first character in string2; and if before the beginning of
++   string2, look at the last character in string1.  */
++#ifdef WCHAR
++/* Use internationalized API instead of SYNTAX.  */
++# define WORDCHAR_P(d)							\
++  (iswalnum ((wint_t)((d) == end1 ? *string2				\
++           : (d) == string2 - 1 ? *(end1 - 1) : *(d))) != 0		\
++   || ((d) == end1 ? *string2						\
++       : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == L'_')
++#else /* BYTE */
++# define WORDCHAR_P(d)							\
++  (SYNTAX ((d) == end1 ? *string2					\
++           : (d) == string2 - 1 ? *(end1 - 1) : *(d))			\
++   == Sword)
++#endif /* WCHAR */
++
++/* Disabled due to a compiler bug -- see comment at case wordbound */
++#if 0
++/* Test if the character before D and the one at D differ with respect
++   to being word-constituent.  */
++#define AT_WORD_BOUNDARY(d)						\
++  (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)				\
++   || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
++#endif
++
++/* Free everything we malloc.  */
++#ifdef MATCH_MAY_ALLOCATE
++# ifdef WCHAR
++#  define FREE_VARIABLES()						\
++  do {									\
++    REGEX_FREE_STACK (fail_stack.stack);				\
++    FREE_VAR (regstart);						\
++    FREE_VAR (regend);							\
++    FREE_VAR (old_regstart);						\
++    FREE_VAR (old_regend);						\
++    FREE_VAR (best_regstart);						\
++    FREE_VAR (best_regend);						\
++    FREE_VAR (reg_info);						\
++    FREE_VAR (reg_dummy);						\
++    FREE_VAR (reg_info_dummy);						\
++    if (!cant_free_wcs_buf)						\
++      {									\
++        FREE_VAR (string1);						\
++        FREE_VAR (string2);						\
++        FREE_VAR (mbs_offset1);						\
++        FREE_VAR (mbs_offset2);						\
++      }									\
++  } while (0)
++# else /* BYTE */
++#  define FREE_VARIABLES()						\
++  do {									\
++    REGEX_FREE_STACK (fail_stack.stack);				\
++    FREE_VAR (regstart);						\
++    FREE_VAR (regend);							\
++    FREE_VAR (old_regstart);						\
++    FREE_VAR (old_regend);						\
++    FREE_VAR (best_regstart);						\
++    FREE_VAR (best_regend);						\
++    FREE_VAR (reg_info);						\
++    FREE_VAR (reg_dummy);						\
++    FREE_VAR (reg_info_dummy);						\
++  } while (0)
++# endif /* WCHAR */
++#else
++# ifdef WCHAR
++#  define FREE_VARIABLES()						\
++  do {									\
++    if (!cant_free_wcs_buf)						\
++      {									\
++        FREE_VAR (string1);						\
++        FREE_VAR (string2);						\
++        FREE_VAR (mbs_offset1);						\
++        FREE_VAR (mbs_offset2);						\
++      }									\
++  } while (0)
++# else /* BYTE */
++#  define FREE_VARIABLES() ((void)0) /* Do nothing!  But inhibit gcc warning. */
++# endif /* WCHAR */
++#endif /* not MATCH_MAY_ALLOCATE */
++
++/* These values must meet several constraints.  They must not be valid
++   register values; since we have a limit of 255 registers (because
++   we use only one byte in the pattern for the register number), we can
++   use numbers larger than 255.  They must differ by 1, because of
++   NUM_FAILURE_ITEMS above.  And the value for the lowest register must
++   be larger than the value for the highest register, so we do not try
++   to actually save any registers when none are active.  */
++#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
++#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
++\f
++#else /* not INSIDE_RECURSION */
++/* Matching routines.  */
++
++#ifndef emacs   /* Emacs never uses this.  */
++/* re_match is like re_match_2 except it takes only a single string.  */
++
++int
++re_match (struct re_pattern_buffer *bufp, const char *string,
++          int size, int pos, struct re_registers *regs)
++{
++  int result;
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    result = wcs_re_match_2_internal (bufp, NULL, 0, string, size,
++				      pos, regs, size,
++				      NULL, 0, NULL, 0, NULL, NULL);
++  else
++# endif
++    result = byte_re_match_2_internal (bufp, NULL, 0, string, size,
++				  pos, regs, size);
++# ifndef REGEX_MALLOC
++#  ifdef C_ALLOCA
++  alloca (0);
++#  endif
++# endif
++  return result;
++}
++# ifdef _LIBC
++weak_alias (__re_match, re_match)
++# endif
++#endif /* not emacs */
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p,
++                                                  UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p,
++                                                UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p,
++                                                      UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2,
++                                   register int len,
++				   RE_TRANSLATE_TYPE translate);
++#else /* not INSIDE_RECURSION */
++
++/* re_match_2 matches the compiled pattern in BUFP against the
++   the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
++   and SIZE2, respectively).  We start matching at POS, and stop
++   matching at STOP.
++
++   If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
++   store offsets for the substring each group matched in REGS.  See the
++   documentation for exactly how many groups we fill.
++
++   We return -1 if no match, -2 if an internal error (such as the
++   failure stack overflowing).  Otherwise, we return the length of the
++   matched substring.  */
++
++int
++re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
++            const char *string2, int size2, int pos,
++            struct re_registers *regs, int stop)
++{
++  int result;
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    result = wcs_re_match_2_internal (bufp, string1, size1, string2, size2,
++				      pos, regs, stop,
++				      NULL, 0, NULL, 0, NULL, NULL);
++  else
++# endif
++    result = byte_re_match_2_internal (bufp, string1, size1, string2, size2,
++				  pos, regs, stop);
++
++#ifndef REGEX_MALLOC
++# ifdef C_ALLOCA
++  alloca (0);
++# endif
++#endif
++  return result;
++}
++#ifdef _LIBC
++weak_alias (__re_match_2, re_match_2)
++#endif
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef WCHAR
++static int count_mbs_length (int *, int);
++
++/* This check the substring (from 0, to length) of the multibyte string,
++   to which offset_buffer correspond. And count how many wchar_t_characters
++   the substring occupy. We use offset_buffer to optimization.
++   See convert_mbs_to_wcs.  */
++
++static int
++count_mbs_length(int *offset_buffer, int length)
++{
++  int upper, lower;
++
++  /* Check whether the size is valid.  */
++  if (length < 0)
++    return -1;
++
++  if (offset_buffer == NULL)
++    return 0;
++
++  /* If there are no multibyte character, offset_buffer[i] == i.
++   Optmize for this case.  */
++  if (offset_buffer[length] == length)
++    return length;
++
++  /* Set up upper with length. (because for all i, offset_buffer[i] >= i)  */
++  upper = length;
++  lower = 0;
++
++  while (true)
++    {
++      int middle = (lower + upper) / 2;
++      if (middle == lower || middle == upper)
++	break;
++      if (offset_buffer[middle] > length)
++	upper = middle;
++      else if (offset_buffer[middle] < length)
++	lower = middle;
++      else
++	return middle;
++    }
++
++  return -1;
++}
++#endif /* WCHAR */
++
++/* This is a separate function so that we can force an alloca cleanup
++   afterwards.  */
++#ifdef WCHAR
++static int
++wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
++                         const char *cstring1, int csize1,
++                         const char *cstring2, int csize2,
++                         int pos,
++			 struct re_registers *regs,
++                         int stop,
++     /* string1 == string2 == NULL means string1/2, size1/2 and
++	mbs_offset1/2 need seting up in this function.  */
++     /* We need wchar_t* buffers correspond to cstring1, cstring2.  */
++                         wchar_t *string1, int size1,
++                         wchar_t *string2, int size2,
++     /* offset buffer for optimizatoin. See convert_mbs_to_wc.  */
++			 int *mbs_offset1, int *mbs_offset2)
++#else /* BYTE */
++static int
++byte_re_match_2_internal (struct re_pattern_buffer *bufp,
++                          const char *string1, int size1,
++                          const char *string2, int size2,
++                          int pos,
++			  struct re_registers *regs, int stop)
++#endif /* BYTE */
++{
++  /* General temporaries.  */
++  int mcnt;
++  UCHAR_T *p1;
++#ifdef WCHAR
++  /* They hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++  /* If true, we can't free string1/2, mbs_offset1/2.  */
++  int cant_free_wcs_buf = 1;
++#endif /* WCHAR */
++
++  /* Just past the end of the corresponding string.  */
++  const CHAR_T *end1, *end2;
++
++  /* Pointers into string1 and string2, just past the last characters in
++     each to consider matching.  */
++  const CHAR_T *end_match_1, *end_match_2;
++
++  /* Where we are in the data, and the end of the current string.  */
++  const CHAR_T *d, *dend;
++
++  /* Where we are in the pattern, and the end of the pattern.  */
++#ifdef WCHAR
++  UCHAR_T *pattern, *p;
++  register UCHAR_T *pend;
++#else /* BYTE */
++  UCHAR_T *p = bufp->buffer;
++  register UCHAR_T *pend = p + bufp->used;
++#endif /* WCHAR */
++
++  /* Mark the opcode just after a start_memory, so we can test for an
++     empty subpattern when we get to the stop_memory.  */
++  UCHAR_T *just_past_start_mem = 0;
++
++  /* We use this to map every character in the string.  */
++  RE_TRANSLATE_TYPE translate = bufp->translate;
++
++  /* Failure point stack.  Each place that can handle a failure further
++     down the line pushes a failure point on this stack.  It consists of
++     restart, regend, and reg_info for all registers corresponding to
++     the subexpressions we're currently inside, plus the number of such
++     registers, and, finally, two char *'s.  The first char * is where
++     to resume scanning the pattern; the second one is where to resume
++     scanning the strings.  If the latter is zero, the failure point is
++     a ``dummy''; if a failure happens and the failure point is a dummy,
++     it gets discarded and the next next one is tried.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
++  PREFIX(fail_stack_type) fail_stack;
++#endif
++#ifdef DEBUG
++  static unsigned failure_id;
++  unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
++#endif
++
++#ifdef REL_ALLOC
++  /* This holds the pointer to the failure stack, when
++     it is allocated relocatably.  */
++  fail_stack_elt_t *failure_stack_ptr;
++#endif
++
++  /* We fill all the registers internally, independent of what we
++     return, for use in backreferences.  The number here includes
++     an element for register zero.  */
++  size_t num_regs = bufp->re_nsub + 1;
++
++  /* The currently active registers.  */
++  active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++  active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++
++  /* Information on the contents of registers. These are pointers into
++     the input strings; they record just what was matched (on this
++     attempt) by a subexpression part of the pattern, that is, the
++     regnum-th regstart pointer points to where in the pattern we began
++     matching and the regnum-th regend points to right after where we
++     stopped matching the regnum-th subexpression.  (The zeroth register
++     keeps track of what the whole pattern matches.)  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **regstart, **regend;
++#endif
++
++  /* If a group that's operated upon by a repetition operator fails to
++     match anything, then the register for its start will need to be
++     restored because it will have been set to wherever in the string we
++     are when we last see its open-group operator.  Similarly for a
++     register's end.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **old_regstart, **old_regend;
++#endif
++
++  /* The is_active field of reg_info helps us keep track of which (possibly
++     nested) subexpressions we are currently in. The matched_something
++     field of reg_info[reg_num] helps us tell whether or not we have
++     matched any of the pattern so far this time through the reg_num-th
++     subexpression.  These two fields get reset each time through any
++     loop their register is in.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
++  PREFIX(register_info_type) *reg_info;
++#endif
++
++  /* The following record the register info as found in the above
++     variables when we find a match better than any we've seen before.
++     This happens as we backtrack through the failure points, which in
++     turn happens only if we have not yet matched the entire string. */
++  unsigned best_regs_set = false;
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **best_regstart, **best_regend;
++#endif
++
++  /* Logically, this is `best_regend[0]'.  But we don't want to have to
++     allocate space for that if we're not allocating space for anything
++     else (see below).  Also, we never need info about register 0 for
++     any of the other register vectors, and it seems rather a kludge to
++     treat `best_regend' differently than the rest.  So we keep track of
++     the end of the best match so far in a separate variable.  We
++     initialize this to NULL so that when we backtrack the first time
++     and need to test it, it's not garbage.  */
++  const CHAR_T *match_end = NULL;
++
++  /* This helps SET_REGS_MATCHED avoid doing redundant work.  */
++  int set_regs_matched_done = 0;
++
++  /* Used when we pop values we don't care about.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **reg_dummy;
++  PREFIX(register_info_type) *reg_info_dummy;
++#endif
++
++#ifdef DEBUG
++  /* Counts the total number of registers pushed.  */
++  unsigned num_regs_pushed = 0;
++#endif
++
++  DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
++
++  INIT_FAIL_STACK ();
++
++#ifdef MATCH_MAY_ALLOCATE
++  /* Do not bother to initialize all the register variables if there are
++     no groups in the pattern, as it takes a fair amount of time.  If
++     there are groups, we include space for register 0 (the whole
++     pattern), even though we never use it, since it simplifies the
++     array indexing.  We should fix this.  */
++  if (bufp->re_nsub)
++    {
++      regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      old_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      old_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      best_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      best_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      reg_info = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
++      reg_dummy = REGEX_TALLOC (num_regs, const CHAR_T *);
++      reg_info_dummy = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
++
++      if (!(regstart && regend && old_regstart && old_regend && reg_info
++            && best_regstart && best_regend && reg_dummy && reg_info_dummy))
++        {
++          FREE_VARIABLES ();
++          return -2;
++        }
++    }
++  else
++    {
++      /* We must initialize all our variables to NULL, so that
++         `FREE_VARIABLES' doesn't try to free them.  */
++      regstart = regend = old_regstart = old_regend = best_regstart
++        = best_regend = reg_dummy = NULL;
++      reg_info = reg_info_dummy = (PREFIX(register_info_type) *) NULL;
++    }
++#endif /* MATCH_MAY_ALLOCATE */
++
++  /* The starting position is bogus.  */
++#ifdef WCHAR
++  if (pos < 0 || pos > csize1 + csize2)
++#else /* BYTE */
++  if (pos < 0 || pos > size1 + size2)
++#endif
++    {
++      FREE_VARIABLES ();
++      return -1;
++    }
++
++#ifdef WCHAR
++  /* Allocate wchar_t array for string1 and string2 and
++     fill them with converted string.  */
++  if (string1 == NULL && string2 == NULL)
++    {
++      /* We need seting up buffers here.  */
++
++      /* We must free wcs buffers in this function.  */
++      cant_free_wcs_buf = 0;
++
++      if (csize1 != 0)
++	{
++	  string1 = REGEX_TALLOC (csize1 + 1, CHAR_T);
++	  mbs_offset1 = REGEX_TALLOC (csize1 + 1, int);
++	  is_binary = REGEX_TALLOC (csize1 + 1, char);
++	  if (!string1 || !mbs_offset1 || !is_binary)
++	    {
++	      FREE_VAR (string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (is_binary);
++	      return -2;
++	    }
++	}
++      if (csize2 != 0)
++	{
++	  string2 = REGEX_TALLOC (csize2 + 1, CHAR_T);
++	  mbs_offset2 = REGEX_TALLOC (csize2 + 1, int);
++	  is_binary = REGEX_TALLOC (csize2 + 1, char);
++	  if (!string2 || !mbs_offset2 || !is_binary)
++	    {
++	      FREE_VAR (string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (string2);
++	      FREE_VAR (mbs_offset2);
++	      FREE_VAR (is_binary);
++	      return -2;
++	    }
++	  size2 = convert_mbs_to_wcs(string2, cstring2, csize2,
++				     mbs_offset2, is_binary);
++	  string2[size2] = L'\0'; /* for a sentinel  */
++	  FREE_VAR (is_binary);
++	}
++    }
++
++  /* We need to cast pattern to (wchar_t*), because we casted this compiled
++     pattern to (char*) in regex_compile.  */
++  p = pattern = (CHAR_T*)bufp->buffer;
++  pend = (CHAR_T*)(bufp->buffer + bufp->used);
++
++#endif /* WCHAR */
++
++  /* Initialize subexpression text positions to -1 to mark ones that no
++     start_memory/stop_memory has been seen for. Also initialize the
++     register information struct.  */
++  for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++    {
++      regstart[mcnt] = regend[mcnt]
++        = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
++
++      REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
++      IS_ACTIVE (reg_info[mcnt]) = 0;
++      MATCHED_SOMETHING (reg_info[mcnt]) = 0;
++      EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
++    }
++
++  /* We move `string1' into `string2' if the latter's empty -- but not if
++     `string1' is null.  */
++  if (size2 == 0 && string1 != NULL)
++    {
++      string2 = string1;
++      size2 = size1;
++      string1 = 0;
++      size1 = 0;
++#ifdef WCHAR
++      mbs_offset2 = mbs_offset1;
++      csize2 = csize1;
++      mbs_offset1 = NULL;
++      csize1 = 0;
++#endif
++    }
++  end1 = string1 + size1;
++  end2 = string2 + size2;
++
++  /* Compute where to stop matching, within the two strings.  */
++#ifdef WCHAR
++  if (stop <= csize1)
++    {
++      mcnt = count_mbs_length(mbs_offset1, stop);
++      end_match_1 = string1 + mcnt;
++      end_match_2 = string2;
++    }
++  else
++    {
++      if (stop > csize1 + csize2)
++	stop = csize1 + csize2;
++      end_match_1 = end1;
++      mcnt = count_mbs_length(mbs_offset2, stop-csize1);
++      end_match_2 = string2 + mcnt;
++    }
++  if (mcnt < 0)
++    { /* count_mbs_length return error.  */
++      FREE_VARIABLES ();
++      return -1;
++    }
++#else
++  if (stop <= size1)
++    {
++      end_match_1 = string1 + stop;
++      end_match_2 = string2;
++    }
++  else
++    {
++      end_match_1 = end1;
++      end_match_2 = string2 + stop - size1;
++    }
++#endif /* WCHAR */
++
++  /* `p' scans through the pattern as `d' scans through the data.
++     `dend' is the end of the input string that `d' points within.  `d'
++     is advanced into the following input string whenever necessary, but
++     this happens before fetching; therefore, at the beginning of the
++     loop, `d' can be pointing at the end of a string, but it cannot
++     equal `string2'.  */
++#ifdef WCHAR
++  if (size1 > 0 && pos <= csize1)
++    {
++      mcnt = count_mbs_length(mbs_offset1, pos);
++      d = string1 + mcnt;
++      dend = end_match_1;
++    }
++  else
++    {
++      mcnt = count_mbs_length(mbs_offset2, pos-csize1);
++      d = string2 + mcnt;
++      dend = end_match_2;
++    }
++
++  if (mcnt < 0)
++    { /* count_mbs_length return error.  */
++      FREE_VARIABLES ();
++      return -1;
++    }
++#else
++  if (size1 > 0 && pos <= size1)
++    {
++      d = string1 + pos;
++      dend = end_match_1;
++    }
++  else
++    {
++      d = string2 + pos - size1;
++      dend = end_match_2;
++    }
++#endif /* WCHAR */
++
++  DEBUG_PRINT1 ("The compiled pattern is:\n");
++  DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
++  DEBUG_PRINT1 ("The string to match is: `");
++  DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
++  DEBUG_PRINT1 ("'\n");
++
++  /* This loops over pattern commands.  It exits by returning from the
++     function if the match is complete, or it drops through if the match
++     fails at this starting point in the input data.  */
++  for (;;)
++    {
++#ifdef _LIBC
++      DEBUG_PRINT2 ("\n%p: ", p);
++#else
++      DEBUG_PRINT2 ("\n0x%x: ", p);
++#endif
++
++      if (p == pend)
++	{ /* End of pattern means we might have succeeded.  */
++          DEBUG_PRINT1 ("end of pattern ... ");
++
++	  /* If we haven't matched the entire string, and we want the
++             longest match, try backtracking.  */
++          if (d != end_match_2)
++	    {
++	      /* 1 if this match ends in the same string (string1 or string2)
++		 as the best previous match.  */
++	      boolean same_str_p = (FIRST_STRING_P (match_end)
++				    == MATCHING_IN_FIRST_STRING);
++	      /* 1 if this match is the best seen so far.  */
++	      boolean best_match_p;
++
++	      /* AIX compiler got confused when this was combined
++		 with the previous declaration.  */
++	      if (same_str_p)
++		best_match_p = d > match_end;
++	      else
++		best_match_p = !MATCHING_IN_FIRST_STRING;
++
++              DEBUG_PRINT1 ("backtracking.\n");
++
++              if (!FAIL_STACK_EMPTY ())
++                { /* More failure points to try.  */
++
++                  /* If exceeds best match so far, save it.  */
++                  if (!best_regs_set || best_match_p)
++                    {
++                      best_regs_set = true;
++                      match_end = d;
++
++                      DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
++
++                      for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++                        {
++                          best_regstart[mcnt] = regstart[mcnt];
++                          best_regend[mcnt] = regend[mcnt];
++                        }
++                    }
++                  goto fail;
++                }
++
++              /* If no failure points, don't restore garbage.  And if
++                 last match is real best match, don't restore second
++                 best one. */
++              else if (best_regs_set && !best_match_p)
++                {
++  	        restore_best_regs:
++                  /* Restore best match.  It may happen that `dend ==
++                     end_match_1' while the restored d is in string2.
++                     For example, the pattern `x.*y.*z' against the
++                     strings `x-' and `y-z-', if the two strings are
++                     not consecutive in memory.  */
++                  DEBUG_PRINT1 ("Restoring best registers.\n");
++
++                  d = match_end;
++                  dend = ((d >= string1 && d <= end1)
++		           ? end_match_1 : end_match_2);
++
++		  for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++		    {
++		      regstart[mcnt] = best_regstart[mcnt];
++		      regend[mcnt] = best_regend[mcnt];
++		    }
++                }
++            } /* d != end_match_2 */
++
++	succeed_label:
++          DEBUG_PRINT1 ("Accepting match.\n");
++          /* If caller wants register contents data back, do it.  */
++          if (regs && !bufp->no_sub)
++	    {
++	      /* Have the register data arrays been allocated?  */
++              if (bufp->regs_allocated == REGS_UNALLOCATED)
++                { /* No.  So allocate them with malloc.  We need one
++                     extra element beyond `num_regs' for the `-1' marker
++                     GNU code uses.  */
++                  regs->num_regs = MAX (RE_NREGS, num_regs + 1);
++                  regs->start = TALLOC (regs->num_regs, regoff_t);
++                  regs->end = TALLOC (regs->num_regs, regoff_t);
++                  if (regs->start == NULL || regs->end == NULL)
++		    {
++		      FREE_VARIABLES ();
++		      return -2;
++		    }
++                  bufp->regs_allocated = REGS_REALLOCATE;
++                }
++              else if (bufp->regs_allocated == REGS_REALLOCATE)
++                { /* Yes.  If we need more elements than were already
++                     allocated, reallocate them.  If we need fewer, just
++                     leave it alone.  */
++                  if (regs->num_regs < num_regs + 1)
++                    {
++                      regs->num_regs = num_regs + 1;
++                      RETALLOC (regs->start, regs->num_regs, regoff_t);
++                      RETALLOC (regs->end, regs->num_regs, regoff_t);
++                      if (regs->start == NULL || regs->end == NULL)
++			{
++			  FREE_VARIABLES ();
++			  return -2;
++			}
++                    }
++                }
++              else
++		{
++		  /* These braces fend off a "empty body in an else-statement"
++		     warning under GCC when assert expands to nothing.  */
++		  assert (bufp->regs_allocated == REGS_FIXED);
++		}
++
++              /* Convert the pointer data in `regstart' and `regend' to
++                 indices.  Register zero has to be set differently,
++                 since we haven't kept track of any info for it.  */
++              if (regs->num_regs > 0)
++                {
++                  regs->start[0] = pos;
++#ifdef WCHAR
++		  if (MATCHING_IN_FIRST_STRING)
++		    regs->end[0] = mbs_offset1 != NULL ?
++					mbs_offset1[d-string1] : 0;
++		  else
++		    regs->end[0] = csize1 + (mbs_offset2 != NULL ?
++					     mbs_offset2[d-string2] : 0);
++#else
++                  regs->end[0] = (MATCHING_IN_FIRST_STRING
++				  ? ((regoff_t) (d - string1))
++			          : ((regoff_t) (d - string2 + size1)));
++#endif /* WCHAR */
++                }
++
++              /* Go through the first `min (num_regs, regs->num_regs)'
++                 registers, since that is all we initialized.  */
++	      for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
++		   mcnt++)
++		{
++                  if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
++                    regs->start[mcnt] = regs->end[mcnt] = -1;
++                  else
++                    {
++		      regs->start[mcnt]
++			= (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
++                      regs->end[mcnt]
++			= (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
++                    }
++		}
++
++              /* If the regs structure we return has more elements than
++                 were in the pattern, set the extra elements to -1.  If
++                 we (re)allocated the registers, this is the case,
++                 because we always allocate enough to have at least one
++                 -1 at the end.  */
++              for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
++                regs->start[mcnt] = regs->end[mcnt] = -1;
++	    } /* regs && !bufp->no_sub */
++
++          DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
++                        nfailure_points_pushed, nfailure_points_popped,
++                        nfailure_points_pushed - nfailure_points_popped);
++          DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
++
++#ifdef WCHAR
++	  if (MATCHING_IN_FIRST_STRING)
++	    mcnt = mbs_offset1 != NULL ? mbs_offset1[d-string1] : 0;
++	  else
++	    mcnt = (mbs_offset2 != NULL ? mbs_offset2[d-string2] : 0) +
++			csize1;
++          mcnt -= pos;
++#else
++          mcnt = d - pos - (MATCHING_IN_FIRST_STRING
++			    ? string1
++			    : string2 - size1);
++#endif /* WCHAR */
++
++          DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
++
++          FREE_VARIABLES ();
++          return mcnt;
++        }
++
++      /* Otherwise match next pattern command.  */
++      switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
++	{
++        /* Ignore these.  Used to ignore the n of succeed_n's which
++           currently have n == 0.  */
++        case no_op:
++          DEBUG_PRINT1 ("EXECUTING no_op.\n");
++          break;
++
++	case succeed:
++          DEBUG_PRINT1 ("EXECUTING succeed.\n");
++	  goto succeed_label;
++
++        /* Match the next n pattern characters exactly.  The following
++           byte in the pattern defines n, and the n bytes after that
++           are the characters to match.  */
++	case exactn:
++#ifdef MBS_SUPPORT
++	case exactn_bin:
++#endif
++	  mcnt = *p++;
++          DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
++
++          /* This is written out as an if-else so we don't waste time
++             testing `translate' inside the loop.  */
++          if (translate)
++	    {
++	      do
++		{
++		  PREFETCH ();
++#ifdef WCHAR
++		  if (*d <= 0xff)
++		    {
++		      if ((UCHAR_T) translate[(unsigned char) *d++]
++			  != (UCHAR_T) *p++)
++			goto fail;
++		    }
++		  else
++		    {
++		      if (*d++ != (CHAR_T) *p++)
++			goto fail;
++		    }
++#else
++		  if ((UCHAR_T) translate[(unsigned char) *d++]
++		      != (UCHAR_T) *p++)
++                    goto fail;
++#endif /* WCHAR */
++		}
++	      while (--mcnt);
++	    }
++	  else
++	    {
++	      do
++		{
++		  PREFETCH ();
++		  if (*d++ != (CHAR_T) *p++) goto fail;
++		}
++	      while (--mcnt);
++	    }
++	  SET_REGS_MATCHED ();
++          break;
++
++
++        /* Match any character except possibly a newline or a null.  */
++	case anychar:
++          DEBUG_PRINT1 ("EXECUTING anychar.\n");
++
++          PREFETCH ();
++
++          if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
++              || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
++	    goto fail;
++
++          SET_REGS_MATCHED ();
++          DEBUG_PRINT2 ("  Matched `%ld'.\n", (long int) *d);
++          d++;
++	  break;
++
++
++	case charset:
++	case charset_not:
++	  {
++	    register UCHAR_T c;
++#ifdef WCHAR
++	    unsigned int i, char_class_length, coll_symbol_length,
++              equiv_class_length, ranges_length, chars_length, length;
++	    CHAR_T *workp, *workp2, *charset_top;
++#define WORK_BUFFER_SIZE 128
++            CHAR_T str_buf[WORK_BUFFER_SIZE];
++# ifdef _LIBC
++	    uint32_t nrules;
++# endif /* _LIBC */
++#endif /* WCHAR */
++	    boolean negate = (re_opcode_t) *(p - 1) == charset_not;
++
++            DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : "");
++	    PREFETCH ();
++	    c = TRANSLATE (*d); /* The character to match.  */
++#ifdef WCHAR
++# ifdef _LIBC
++	    nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif /* _LIBC */
++	    charset_top = p - 1;
++	    char_class_length = *p++;
++	    coll_symbol_length = *p++;
++	    equiv_class_length = *p++;
++	    ranges_length = *p++;
++	    chars_length = *p++;
++	    /* p points charset[6], so the address of the next instruction
++	       (charset[l+m+n+2o+k+p']) equals p[l+m+n+2*o+p'],
++	       where l=length of char_classes, m=length of collating_symbol,
++	       n=equivalence_class, o=length of char_range,
++	       p'=length of character.  */
++	    workp = p;
++	    /* Update p to indicate the next instruction.  */
++	    p += char_class_length + coll_symbol_length+ equiv_class_length +
++              2*ranges_length + chars_length;
++
++            /* match with char_class?  */
++	    for (i = 0; i < char_class_length ; i += CHAR_CLASS_SIZE)
++	      {
++		wctype_t wctype;
++		uintptr_t alignedp = ((uintptr_t)workp
++				      + __alignof__(wctype_t) - 1)
++		  		      & ~(uintptr_t)(__alignof__(wctype_t) - 1);
++		wctype = *((wctype_t*)alignedp);
++		workp += CHAR_CLASS_SIZE;
++# ifdef _LIBC
++		if (__iswctype((wint_t)c, wctype))
++		  goto char_set_matched;
++# else
++		if (iswctype((wint_t)c, wctype))
++		  goto char_set_matched;
++# endif
++	      }
++
++            /* match with collating_symbol?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++		const unsigned char *extra = (const unsigned char *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
++
++		for (workp2 = workp + coll_symbol_length ; workp < workp2 ;
++		     workp++)
++		  {
++		    int32_t *wextra;
++		    wextra = (int32_t*)(extra + *workp++);
++		    for (i = 0; i < *wextra; ++i)
++		      if (TRANSLATE(d[i]) != wextra[1 + i])
++			break;
++
++		    if (i == *wextra)
++		      {
++			/* Update d, however d will be incremented at
++			   char_set_matched:, we decrement d here.  */
++			d += i - 1;
++			goto char_set_matched;
++		      }
++		  }
++	      }
++	    else /* (nrules == 0) */
++# endif
++	      /* If we can't look up collation data, we use wcscoll
++		 instead.  */
++	      {
++		for (workp2 = workp + coll_symbol_length ; workp < workp2 ;)
++		  {
++		    const CHAR_T *backup_d = d, *backup_dend = dend;
++# ifdef _LIBC
++		    length = __wcslen (workp);
++# else
++		    length = wcslen (workp);
++# endif
++
++		    /* If wcscoll(the collating symbol, whole string) > 0,
++		       any substring of the string never match with the
++		       collating symbol.  */
++# ifdef _LIBC
++		    if (__wcscoll (workp, d) > 0)
++# else
++		    if (wcscoll (workp, d) > 0)
++# endif
++		      {
++			workp += length + 1;
++			continue;
++		      }
++
++		    /* First, we compare the collating symbol with
++		       the first character of the string.
++		       If it don't match, we add the next character to
++		       the compare buffer in turn.  */
++		    for (i = 0 ; i < WORK_BUFFER_SIZE-1 ; i++, d++)
++		      {
++			int match;
++			if (d == dend)
++			  {
++			    if (dend == end_match_2)
++			      break;
++			    d = string2;
++			    dend = end_match_2;
++			  }
++
++			/* add next character to the compare buffer.  */
++			str_buf[i] = TRANSLATE(*d);
++			str_buf[i+1] = '\0';
++
++# ifdef _LIBC
++			match = __wcscoll (workp, str_buf);
++# else
++			match = wcscoll (workp, str_buf);
++# endif
++			if (match == 0)
++			  goto char_set_matched;
++
++			if (match < 0)
++			  /* (str_buf > workp) indicate (str_buf + X > workp),
++			     because for all X (str_buf + X > str_buf).
++			     So we don't need continue this loop.  */
++			  break;
++
++			/* Otherwise(str_buf < workp),
++			   (str_buf+next_character) may equals (workp).
++			   So we continue this loop.  */
++		      }
++		    /* not matched */
++		    d = backup_d;
++		    dend = backup_dend;
++		    workp += length + 1;
++		  }
++              }
++            /* match with equivalence_class?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++                const CHAR_T *backup_d = d, *backup_dend = dend;
++		/* Try to match the equivalence class against
++		   those known to the collate implementation.  */
++		const int32_t *table;
++		const int32_t *weights;
++		const int32_t *extra;
++		const int32_t *indirect;
++		int32_t idx, idx2;
++		wint_t *cp;
++		size_t len;
++
++		table = (const int32_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
++		weights = (const wint_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
++		extra = (const wint_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
++		indirect = (const int32_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
++
++		/* Write 1 collating element to str_buf, and
++		   get its index.  */
++		idx2 = 0;
++
++		for (i = 0 ; idx2 == 0 && i < WORK_BUFFER_SIZE - 1; i++)
++		  {
++		    cp = (wint_t*)str_buf;
++		    if (d == dend)
++		      {
++			if (dend == end_match_2)
++			  break;
++			d = string2;
++			dend = end_match_2;
++		      }
++		    str_buf[i] = TRANSLATE(*(d+i));
++		    str_buf[i+1] = '\0'; /* sentinel */
++		    idx2 = FINDIDX (table, indirect, extra, &cp, 1);
++		  }
++
++		/* Update d, however d will be incremented at
++		   char_set_matched:, we decrement d here.  */
++		d = backup_d + ((wchar_t*)cp - (wchar_t*)str_buf - 1);
++		if (d >= dend)
++		  {
++		    if (dend == end_match_2)
++			d = dend;
++		    else
++		      {
++			d = string2;
++			dend = end_match_2;
++		      }
++		  }
++
++		len = weights[idx2];
++
++		for (workp2 = workp + equiv_class_length ; workp < workp2 ;
++		     workp++)
++		  {
++		    idx = (int32_t)*workp;
++		    /* We already checked idx != 0 in regex_compile. */
++
++		    if (idx2 != 0 && len == weights[idx])
++		      {
++			int cnt = 0;
++			while (cnt < len && (weights[idx + 1 + cnt]
++					     == weights[idx2 + 1 + cnt]))
++			  ++cnt;
++
++			if (cnt == len)
++			  goto char_set_matched;
++		      }
++		  }
++		/* not matched */
++                d = backup_d;
++                dend = backup_dend;
++	      }
++	    else /* (nrules == 0) */
++# endif
++	      /* If we can't look up collation data, we use wcscoll
++		 instead.  */
++	      {
++		for (workp2 = workp + equiv_class_length ; workp < workp2 ;)
++		  {
++		    const CHAR_T *backup_d = d, *backup_dend = dend;
++# ifdef _LIBC
++		    length = __wcslen (workp);
++# else
++		    length = wcslen (workp);
++# endif
++
++		    /* If wcscoll(the collating symbol, whole string) > 0,
++		       any substring of the string never match with the
++		       collating symbol.  */
++# ifdef _LIBC
++		    if (__wcscoll (workp, d) > 0)
++# else
++		    if (wcscoll (workp, d) > 0)
++# endif
++		      {
++			workp += length + 1;
++			break;
++		      }
++
++		    /* First, we compare the equivalence class with
++		       the first character of the string.
++		       If it don't match, we add the next character to
++		       the compare buffer in turn.  */
++		    for (i = 0 ; i < WORK_BUFFER_SIZE - 1 ; i++, d++)
++		      {
++			int match;
++			if (d == dend)
++			  {
++			    if (dend == end_match_2)
++			      break;
++			    d = string2;
++			    dend = end_match_2;
++			  }
++
++			/* add next character to the compare buffer.  */
++			str_buf[i] = TRANSLATE(*d);
++			str_buf[i+1] = '\0';
++
++# ifdef _LIBC
++			match = __wcscoll (workp, str_buf);
++# else
++			match = wcscoll (workp, str_buf);
++# endif
++
++			if (match == 0)
++			  goto char_set_matched;
++
++			if (match < 0)
++			/* (str_buf > workp) indicate (str_buf + X > workp),
++			   because for all X (str_buf + X > str_buf).
++			   So we don't need continue this loop.  */
++			  break;
++
++			/* Otherwise(str_buf < workp),
++			   (str_buf+next_character) may equals (workp).
++			   So we continue this loop.  */
++		      }
++		    /* not matched */
++		    d = backup_d;
++		    dend = backup_dend;
++		    workp += length + 1;
++		  }
++	      }
++
++            /* match with char_range?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++		uint32_t collseqval;
++		const char *collseq = (const char *)
++		  _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
++
++		collseqval = collseq_table_lookup (collseq, c);
++
++		for (; workp < p - chars_length ;)
++		  {
++		    uint32_t start_val, end_val;
++
++		    /* We already compute the collation sequence value
++		       of the characters (or collating symbols).  */
++		    start_val = (uint32_t) *workp++; /* range_start */
++		    end_val = (uint32_t) *workp++; /* range_end */
++
++		    if (start_val <= collseqval && collseqval <= end_val)
++		      goto char_set_matched;
++		  }
++	      }
++	    else
++# endif
++	      {
++		/* We set range_start_char at str_buf[0], range_end_char
++		   at str_buf[4], and compared char at str_buf[2].  */
++		str_buf[1] = 0;
++		str_buf[2] = c;
++		str_buf[3] = 0;
++		str_buf[5] = 0;
++		for (; workp < p - chars_length ;)
++		  {
++		    wchar_t *range_start_char, *range_end_char;
++
++		    /* match if (range_start_char <= c <= range_end_char).  */
++
++		    /* If range_start(or end) < 0, we assume -range_start(end)
++		       is the offset of the collating symbol which is specified
++		       as the character of the range start(end).  */
++
++		    /* range_start */
++		    if (*workp < 0)
++		      range_start_char = charset_top - (*workp++);
++		    else
++		      {
++			str_buf[0] = *workp++;
++			range_start_char = str_buf;
++		      }
++
++		    /* range_end */
++		    if (*workp < 0)
++		      range_end_char = charset_top - (*workp++);
++		    else
++		      {
++			str_buf[4] = *workp++;
++			range_end_char = str_buf + 4;
++		      }
++
++# ifdef _LIBC
++		    if (__wcscoll (range_start_char, str_buf+2) <= 0
++			&& __wcscoll (str_buf+2, range_end_char) <= 0)
++# else
++		    if (wcscoll (range_start_char, str_buf+2) <= 0
++			&& wcscoll (str_buf+2, range_end_char) <= 0)
++# endif
++		      goto char_set_matched;
++		  }
++	      }
++
++            /* match with char?  */
++	    for (; workp < p ; workp++)
++	      if (c == *workp)
++		goto char_set_matched;
++
++	    negate = !negate;
++
++	  char_set_matched:
++	    if (negate) goto fail;
++#else
++            /* Cast to `unsigned' instead of `unsigned char' in case the
++               bit list is a full 32 bytes long.  */
++	    if (c < (unsigned) (*p * BYTEWIDTH)
++		&& p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
++	      negate = !negate;
++
++	    p += 1 + *p;
++
++	    if (!negate) goto fail;
++#undef WORK_BUFFER_SIZE
++#endif /* WCHAR */
++	    SET_REGS_MATCHED ();
++            d++;
++	    break;
++	  }
++
++
++        /* The beginning of a group is represented by start_memory.
++           The arguments are the register number in the next byte, and the
++           number of groups inner to this one in the next.  The text
++           matched within the group is recorded (in the internal
++           registers data structure) under the register number.  */
++        case start_memory:
++	  DEBUG_PRINT3 ("EXECUTING start_memory %ld (%ld):\n",
++			(long int) *p, (long int) p[1]);
++
++          /* Find out if this group can match the empty string.  */
++	  p1 = p;		/* To send to group_match_null_string_p.  */
++
++          if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
++            REG_MATCH_NULL_STRING_P (reg_info[*p])
++              = PREFIX(group_match_null_string_p) (&p1, pend, reg_info);
++
++          /* Save the position in the string where we were the last time
++             we were at this open-group operator in case the group is
++             operated upon by a repetition operator, e.g., with `(a*)*b'
++             against `ab'; then we want to ignore where we are now in
++             the string in case this attempt to match fails.  */
++          old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
++                             ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
++                             : regstart[*p];
++	  DEBUG_PRINT2 ("  old_regstart: %d\n",
++			 POINTER_TO_OFFSET (old_regstart[*p]));
++
++          regstart[*p] = d;
++	  DEBUG_PRINT2 ("  regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
++
++          IS_ACTIVE (reg_info[*p]) = 1;
++          MATCHED_SOMETHING (reg_info[*p]) = 0;
++
++	  /* Clear this whenever we change the register activity status.  */
++	  set_regs_matched_done = 0;
++
++          /* This is the new highest active register.  */
++          highest_active_reg = *p;
++
++          /* If nothing was active before, this is the new lowest active
++             register.  */
++          if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
++            lowest_active_reg = *p;
++
++          /* Move past the register number and inner group count.  */
++          p += 2;
++	  just_past_start_mem = p;
++
++          break;
++
++
++        /* The stop_memory opcode represents the end of a group.  Its
++           arguments are the same as start_memory's: the register
++           number, and the number of inner groups.  */
++	case stop_memory:
++	  DEBUG_PRINT3 ("EXECUTING stop_memory %ld (%ld):\n",
++			(long int) *p, (long int) p[1]);
++
++          /* We need to save the string position the last time we were at
++             this close-group operator in case the group is operated
++             upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
++             against `aba'; then we want to ignore where we are now in
++             the string in case this attempt to match fails.  */
++          old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
++                           ? REG_UNSET (regend[*p]) ? d : regend[*p]
++			   : regend[*p];
++	  DEBUG_PRINT2 ("      old_regend: %d\n",
++			 POINTER_TO_OFFSET (old_regend[*p]));
++
++          regend[*p] = d;
++	  DEBUG_PRINT2 ("      regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
++
++          /* This register isn't active anymore.  */
++          IS_ACTIVE (reg_info[*p]) = 0;
++
++	  /* Clear this whenever we change the register activity status.  */
++	  set_regs_matched_done = 0;
++
++          /* If this was the only register active, nothing is active
++             anymore.  */
++          if (lowest_active_reg == highest_active_reg)
++            {
++              lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++              highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++            }
++          else
++            { /* We must scan for the new highest active register, since
++                 it isn't necessarily one less than now: consider
++                 (a(b)c(d(e)f)g).  When group 3 ends, after the f), the
++                 new highest active register is 1.  */
++              UCHAR_T r = *p - 1;
++              while (r > 0 && !IS_ACTIVE (reg_info[r]))
++                r--;
++
++              /* If we end up at register zero, that means that we saved
++                 the registers as the result of an `on_failure_jump', not
++                 a `start_memory', and we jumped to past the innermost
++                 `stop_memory'.  For example, in ((.)*) we save
++                 registers 1 and 2 as a result of the *, but when we pop
++                 back to the second ), we are at the stop_memory 1.
++                 Thus, nothing is active.  */
++	      if (r == 0)
++                {
++                  lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++                  highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++                }
++              else
++                highest_active_reg = r;
++            }
++
++          /* If just failed to match something this time around with a
++             group that's operated on by a repetition operator, try to
++             force exit from the ``loop'', and restore the register
++             information for this group that we had before trying this
++             last match.  */
++          if ((!MATCHED_SOMETHING (reg_info[*p])
++               || just_past_start_mem == p - 1)
++	      && (p + 2) < pend)
++            {
++              boolean is_a_jump_n = false;
++
++              p1 = p + 2;
++              mcnt = 0;
++              switch ((re_opcode_t) *p1++)
++                {
++                  case jump_n:
++		    is_a_jump_n = true;
++                  case pop_failure_jump:
++		  case maybe_pop_jump:
++		  case jump:
++		  case dummy_failure_jump:
++                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++		    if (is_a_jump_n)
++		      p1 += OFFSET_ADDRESS_SIZE;
++                    break;
++
++                  default:
++                    /* do nothing */ ;
++                }
++	      p1 += mcnt;
++
++              /* If the next operation is a jump backwards in the pattern
++	         to an on_failure_jump right before the start_memory
++                 corresponding to this stop_memory, exit from the loop
++                 by forcing a failure after pushing on the stack the
++                 on_failure_jump's jump in the pattern, and d.  */
++              if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
++                  && (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == start_memory
++		  && p1[2+OFFSET_ADDRESS_SIZE] == *p)
++		{
++                  /* If this group ever matched anything, then restore
++                     what its registers were before trying this last
++                     failed match, e.g., with `(a*)*b' against `ab' for
++                     regstart[1], and, e.g., with `((a*)*(b*)*)*'
++                     against `aba' for regend[3].
++
++                     Also restore the registers for inner groups for,
++                     e.g., `((a*)(b*))*' against `aba' (register 3 would
++                     otherwise get trashed).  */
++
++                  if (EVER_MATCHED_SOMETHING (reg_info[*p]))
++		    {
++		      unsigned r;
++
++                      EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
++
++		      /* Restore this and inner groups' (if any) registers.  */
++                      for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
++			   r++)
++                        {
++                          regstart[r] = old_regstart[r];
++
++                          /* xx why this test?  */
++                          if (old_regend[r] >= regstart[r])
++                            regend[r] = old_regend[r];
++                        }
++                    }
++		  p1++;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
++
++                  goto fail;
++                }
++            }
++
++          /* Move past the register number and the inner group count.  */
++          p += 2;
++          break;
++
++
++	/* \<digit> has been turned into a `duplicate' command which is
++           followed by the numeric value of <digit> as the register number.  */
++        case duplicate:
++	  {
++	    register const CHAR_T *d2, *dend2;
++	    int regno = *p++;   /* Get which register to match against.  */
++	    DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
++
++	    /* Can't back reference a group which we've never matched.  */
++            if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
++              goto fail;
++
++            /* Where in input to try to start matching.  */
++            d2 = regstart[regno];
++
++            /* Where to stop matching; if both the place to start and
++               the place to stop matching are in the same string, then
++               set to the place to stop, otherwise, for now have to use
++               the end of the first string.  */
++
++            dend2 = ((FIRST_STRING_P (regstart[regno])
++		      == FIRST_STRING_P (regend[regno]))
++		     ? regend[regno] : end_match_1);
++	    for (;;)
++	      {
++		/* If necessary, advance to next segment in register
++                   contents.  */
++		while (d2 == dend2)
++		  {
++		    if (dend2 == end_match_2) break;
++		    if (dend2 == regend[regno]) break;
++
++                    /* End of string1 => advance to string2. */
++                    d2 = string2;
++                    dend2 = regend[regno];
++		  }
++		/* At end of register contents => success */
++		if (d2 == dend2) break;
++
++		/* If necessary, advance to next segment in data.  */
++		PREFETCH ();
++
++		/* How many characters left in this segment to match.  */
++		mcnt = dend - d;
++
++		/* Want how many consecutive characters we can match in
++                   one shot, so, if necessary, adjust the count.  */
++                if (mcnt > dend2 - d2)
++		  mcnt = dend2 - d2;
++
++		/* Compare that many; failure if mismatch, else move
++                   past them.  */
++		if (translate
++                    ? PREFIX(bcmp_translate) (d, d2, mcnt, translate)
++                    : memcmp (d, d2, mcnt*sizeof(UCHAR_T)))
++		  goto fail;
++		d += mcnt, d2 += mcnt;
++
++		/* Do this because we've match some characters.  */
++		SET_REGS_MATCHED ();
++	      }
++	  }
++	  break;
++
++
++        /* begline matches the empty string at the beginning of the string
++           (unless `not_bol' is set in `bufp'), and, if
++           `newline_anchor' is set, after newlines.  */
++	case begline:
++          DEBUG_PRINT1 ("EXECUTING begline.\n");
++
++          if (AT_STRINGS_BEG (d))
++            {
++              if (!bufp->not_bol) break;
++            }
++          else if (d[-1] == '\n' && bufp->newline_anchor)
++            {
++              break;
++            }
++          /* In all other cases, we fail.  */
++          goto fail;
++
++
++        /* endline is the dual of begline.  */
++	case endline:
++          DEBUG_PRINT1 ("EXECUTING endline.\n");
++
++          if (AT_STRINGS_END (d))
++            {
++              if (!bufp->not_eol) break;
++            }
++
++          /* We have to ``prefetch'' the next character.  */
++          else if ((d == end1 ? *string2 : *d) == '\n'
++                   && bufp->newline_anchor)
++            {
++              break;
++            }
++          goto fail;
++
++
++	/* Match at the very beginning of the data.  */
++        case begbuf:
++          DEBUG_PRINT1 ("EXECUTING begbuf.\n");
++          if (AT_STRINGS_BEG (d))
++            break;
++          goto fail;
++
++
++	/* Match at the very end of the data.  */
++        case endbuf:
++          DEBUG_PRINT1 ("EXECUTING endbuf.\n");
++	  if (AT_STRINGS_END (d))
++	    break;
++          goto fail;
++
++
++        /* on_failure_keep_string_jump is used to optimize `.*\n'.  It
++           pushes NULL as the value for the string on the stack.  Then
++           `pop_failure_point' will keep the current value for the
++           string, instead of restoring it.  To see why, consider
++           matching `foo\nbar' against `.*\n'.  The .* matches the foo;
++           then the . fails against the \n.  But the next thing we want
++           to do is match the \n against the \n; if we restored the
++           string value, we would be back at the foo.
++
++           Because this is used only in specific cases, we don't need to
++           check all the things that `on_failure_jump' does, to make
++           sure the right things get saved on the stack.  Hence we don't
++           share its code.  The only reason to push anything on the
++           stack at all is that otherwise we would have to change
++           `anychar's code to do something besides goto fail in this
++           case; that seems worse than this.  */
++        case on_failure_keep_string_jump:
++          DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
++
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++          DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
++#else
++          DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
++#endif
++
++          PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
++          break;
++
++
++	/* Uses of on_failure_jump:
++
++           Each alternative starts with an on_failure_jump that points
++           to the beginning of the next alternative.  Each alternative
++           except the last ends with a jump that in effect jumps past
++           the rest of the alternatives.  (They really jump to the
++           ending jump of the following alternative, because tensioning
++           these jumps is a hassle.)
++
++           Repeats start with an on_failure_jump that points past both
++           the repetition text and either the following jump or
++           pop_failure_jump back to this on_failure_jump.  */
++	case on_failure_jump:
++        on_failure:
++          DEBUG_PRINT1 ("EXECUTING on_failure_jump");
++
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++          DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
++#else
++          DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
++#endif
++
++          /* If this on_failure_jump comes right before a group (i.e.,
++             the original * applied to a group), save the information
++             for that group and all inner ones, so that if we fail back
++             to this point, the group's information will be correct.
++             For example, in \(a*\)*\1, we need the preceding group,
++             and in \(zz\(a*\)b*\)\2, we need the inner group.  */
++
++          /* We can't use `p' to check ahead because we push
++             a failure point to `p + mcnt' after we do this.  */
++          p1 = p;
++
++          /* We need to skip no_op's before we look for the
++             start_memory in case this on_failure_jump is happening as
++             the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
++             against aba.  */
++          while (p1 < pend && (re_opcode_t) *p1 == no_op)
++            p1++;
++
++          if (p1 < pend && (re_opcode_t) *p1 == start_memory)
++            {
++              /* We have a new highest active register now.  This will
++                 get reset at the start_memory we are about to get to,
++                 but we will have saved all the registers relevant to
++                 this repetition op, as described above.  */
++              highest_active_reg = *(p1 + 1) + *(p1 + 2);
++              if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
++                lowest_active_reg = *(p1 + 1);
++            }
++
++          DEBUG_PRINT1 (":\n");
++          PUSH_FAILURE_POINT (p + mcnt, d, -2);
++          break;
++
++
++        /* A smart repeat ends with `maybe_pop_jump'.
++	   We change it to either `pop_failure_jump' or `jump'.  */
++        case maybe_pop_jump:
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++          DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
++          {
++	    register UCHAR_T *p2 = p;
++
++            /* Compare the beginning of the repeat with what in the
++               pattern follows its end. If we can establish that there
++               is nothing that they would both match, i.e., that we
++               would have to backtrack because of (as in, e.g., `a*a')
++               then we can change to pop_failure_jump, because we'll
++               never have to backtrack.
++
++               This is not true in the case of alternatives: in
++               `(a|ab)*' we do need to backtrack to the `ab' alternative
++               (e.g., if the string was `ab').  But instead of trying to
++               detect that here, the alternative has put on a dummy
++               failure point which is what we will end up popping.  */
++
++	    /* Skip over open/close-group commands.
++	       If what follows this loop is a ...+ construct,
++	       look at what begins its body, since we will have to
++	       match at least one of that.  */
++	    while (1)
++	      {
++		if (p2 + 2 < pend
++		    && ((re_opcode_t) *p2 == stop_memory
++			|| (re_opcode_t) *p2 == start_memory))
++		  p2 += 3;
++		else if (p2 + 2 + 2 * OFFSET_ADDRESS_SIZE < pend
++			 && (re_opcode_t) *p2 == dummy_failure_jump)
++		  p2 += 2 + 2 * OFFSET_ADDRESS_SIZE;
++		else
++		  break;
++	      }
++
++	    p1 = p + mcnt;
++	    /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
++	       to the `maybe_finalize_jump' of this case.  Examine what
++	       follows.  */
++
++            /* If we're at the end of the pattern, we can change.  */
++            if (p2 == pend)
++	      {
++		/* Consider what happens when matching ":\(.*\)"
++		   against ":/".  I don't really understand this code
++		   yet.  */
++  	        p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
++		  pop_failure_jump;
++                DEBUG_PRINT1
++                  ("  End of pattern: change to `pop_failure_jump'.\n");
++              }
++
++            else if ((re_opcode_t) *p2 == exactn
++#ifdef MBS_SUPPORT
++		     || (re_opcode_t) *p2 == exactn_bin
++#endif
++		     || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
++	      {
++		register UCHAR_T c
++                  = *p2 == (UCHAR_T) endline ? '\n' : p2[2];
++
++                if (((re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn
++#ifdef MBS_SUPPORT
++		     || (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn_bin
++#endif
++		    ) && p1[3+OFFSET_ADDRESS_SIZE] != c)
++                  {
++  		    p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
++		      pop_failure_jump;
++#ifdef WCHAR
++		      DEBUG_PRINT3 ("  %C != %C => pop_failure_jump.\n",
++				    (wint_t) c,
++				    (wint_t) p1[3+OFFSET_ADDRESS_SIZE]);
++#else
++		      DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",
++				    (char) c,
++				    (char) p1[3+OFFSET_ADDRESS_SIZE]);
++#endif
++                  }
++
++#ifndef WCHAR
++		else if ((re_opcode_t) p1[3] == charset
++			 || (re_opcode_t) p1[3] == charset_not)
++		  {
++		    int negate = (re_opcode_t) p1[3] == charset_not;
++
++		    if (c < (unsigned) (p1[4] * BYTEWIDTH)
++			&& p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
++		      negate = !negate;
++
++                    /* `negate' is equal to 1 if c would match, which means
++                        that we can't change to pop_failure_jump.  */
++		    if (!negate)
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++#endif /* not WCHAR */
++	      }
++#ifndef WCHAR
++            else if ((re_opcode_t) *p2 == charset)
++	      {
++		/* We win if the first character of the loop is not part
++                   of the charset.  */
++                if ((re_opcode_t) p1[3] == exactn
++ 		    && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
++ 			  && (p2[2 + p1[5] / BYTEWIDTH]
++ 			      & (1 << (p1[5] % BYTEWIDTH)))))
++		  {
++		    p[-3] = (unsigned char) pop_failure_jump;
++		    DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                  }
++
++		else if ((re_opcode_t) p1[3] == charset_not)
++		  {
++		    int idx;
++		    /* We win if the charset_not inside the loop
++		       lists every character listed in the charset after.  */
++		    for (idx = 0; idx < (int) p2[1]; idx++)
++		      if (! (p2[2 + idx] == 0
++			     || (idx < (int) p1[4]
++				 && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
++			break;
++
++		    if (idx == p2[1])
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++		else if ((re_opcode_t) p1[3] == charset)
++		  {
++		    int idx;
++		    /* We win if the charset inside the loop
++		       has no overlap with the one after the loop.  */
++		    for (idx = 0;
++			 idx < (int) p2[1] && idx < (int) p1[4];
++			 idx++)
++		      if ((p2[2 + idx] & p1[5 + idx]) != 0)
++			break;
++
++		    if (idx == p2[1] || idx == p1[4])
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++	      }
++#endif /* not WCHAR */
++	  }
++	  p -= OFFSET_ADDRESS_SIZE;	/* Point at relative address again.  */
++	  if ((re_opcode_t) p[-1] != pop_failure_jump)
++	    {
++	      p[-1] = (UCHAR_T) jump;
++              DEBUG_PRINT1 ("  Match => jump.\n");
++	      goto unconditional_jump;
++	    }
++        /* Note fall through.  */
++
++
++	/* The end of a simple repeat has a pop_failure_jump back to
++           its matching on_failure_jump, where the latter will push a
++           failure point.  The pop_failure_jump takes off failure
++           points put on by this pop_failure_jump's matching
++           on_failure_jump; we got through the pattern to here from the
++           matching on_failure_jump, so didn't fail.  */
++        case pop_failure_jump:
++          {
++            /* We need to pass separate storage for the lowest and
++               highest registers, even though we don't care about the
++               actual values.  Otherwise, we will restore only one
++               register from the stack, since lowest will == highest in
++               `pop_failure_point'.  */
++            active_reg_t dummy_low_reg, dummy_high_reg;
++            UCHAR_T *pdummy __attribute__ ((unused)) = NULL;
++            const CHAR_T *sdummy __attribute__ ((unused)) = NULL;
++
++            DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
++            POP_FAILURE_POINT (sdummy, pdummy,
++                               dummy_low_reg, dummy_high_reg,
++                               reg_dummy, reg_dummy, reg_info_dummy);
++          }
++	  /* Note fall through.  */
++
++	unconditional_jump:
++#ifdef _LIBC
++	  DEBUG_PRINT2 ("\n%p: ", p);
++#else
++	  DEBUG_PRINT2 ("\n0x%x: ", p);
++#endif
++          /* Note fall through.  */
++
++        /* Unconditionally jump (without popping any failure points).  */
++        case jump:
++	  EXTRACT_NUMBER_AND_INCR (mcnt, p);	/* Get the amount to jump.  */
++          DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
++	  p += mcnt;				/* Do the jump.  */
++#ifdef _LIBC
++          DEBUG_PRINT2 ("(to %p).\n", p);
++#else
++          DEBUG_PRINT2 ("(to 0x%x).\n", p);
++#endif
++	  break;
++
++
++        /* We need this opcode so we can detect where alternatives end
++           in `group_match_null_string_p' et al.  */
++        case jump_past_alt:
++          DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
++          goto unconditional_jump;
++
++
++        /* Normally, the on_failure_jump pushes a failure point, which
++           then gets popped at pop_failure_jump.  We will end up at
++           pop_failure_jump, also, and with a pattern of, say, `a+', we
++           are skipping over the on_failure_jump, so we have to push
++           something meaningless for pop_failure_jump to pop.  */
++        case dummy_failure_jump:
++          DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
++          /* It doesn't matter what we push for the string here.  What
++             the code at `fail' tests is the value for the pattern.  */
++          PUSH_FAILURE_POINT (NULL, NULL, -2);
++          goto unconditional_jump;
++
++
++        /* At the end of an alternative, we need to push a dummy failure
++           point in case we are followed by a `pop_failure_jump', because
++           we don't want the failure point for the alternative to be
++           popped.  For example, matching `(a|ab)*' against `aab'
++           requires that we match the `ab' alternative.  */
++        case push_dummy_failure:
++          DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
++          /* See comments just above at `dummy_failure_jump' about the
++             two zeroes.  */
++          PUSH_FAILURE_POINT (NULL, NULL, -2);
++          break;
++
++        /* Have to succeed matching what follows at least n times.
++           After that, handle like `on_failure_jump'.  */
++        case succeed_n:
++          EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
++          DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
++
++          assert (mcnt >= 0);
++          /* Originally, this is how many times we HAVE to succeed.  */
++          if (mcnt > 0)
++            {
++               mcnt--;
++	       p += OFFSET_ADDRESS_SIZE;
++               STORE_NUMBER_AND_INCR (p, mcnt);
++#ifdef _LIBC
++               DEBUG_PRINT3 ("  Setting %p to %d.\n", p - OFFSET_ADDRESS_SIZE
++			     , mcnt);
++#else
++               DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p - OFFSET_ADDRESS_SIZE
++			     , mcnt);
++#endif
++            }
++	  else if (mcnt == 0)
++            {
++#ifdef _LIBC
++              DEBUG_PRINT2 ("  Setting two bytes from %p to no_op.\n",
++			    p + OFFSET_ADDRESS_SIZE);
++#else
++              DEBUG_PRINT2 ("  Setting two bytes from 0x%x to no_op.\n",
++			    p + OFFSET_ADDRESS_SIZE);
++#endif /* _LIBC */
++
++#ifdef WCHAR
++	      p[1] = (UCHAR_T) no_op;
++#else
++	      p[2] = (UCHAR_T) no_op;
++              p[3] = (UCHAR_T) no_op;
++#endif /* WCHAR */
++              goto on_failure;
++            }
++          break;
++
++        case jump_n:
++          EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
++          DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
++
++          /* Originally, this is how many times we CAN jump.  */
++          if (mcnt)
++            {
++               mcnt--;
++               STORE_NUMBER (p + OFFSET_ADDRESS_SIZE, mcnt);
++
++#ifdef _LIBC
++               DEBUG_PRINT3 ("  Setting %p to %d.\n", p + OFFSET_ADDRESS_SIZE,
++			     mcnt);
++#else
++               DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p + OFFSET_ADDRESS_SIZE,
++			     mcnt);
++#endif /* _LIBC */
++	       goto unconditional_jump;
++            }
++          /* If don't have to jump any more, skip over the rest of command.  */
++	  else
++	    p += 2 * OFFSET_ADDRESS_SIZE;
++          break;
++
++	case set_number_at:
++	  {
++            DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
++
++            EXTRACT_NUMBER_AND_INCR (mcnt, p);
++            p1 = p + mcnt;
++            EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++            DEBUG_PRINT3 ("  Setting %p to %d.\n", p1, mcnt);
++#else
++            DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p1, mcnt);
++#endif
++	    STORE_NUMBER (p1, mcnt);
++            break;
++          }
++
++#if 0
++	/* The DEC Alpha C compiler 3.x generates incorrect code for the
++	   test  WORDCHAR_P (d - 1) != WORDCHAR_P (d)  in the expansion of
++	   AT_WORD_BOUNDARY, so this code is disabled.  Expanding the
++	   macro and introducing temporary variables works around the bug.  */
++
++	case wordbound:
++	  DEBUG_PRINT1 ("EXECUTING wordbound.\n");
++	  if (AT_WORD_BOUNDARY (d))
++	    break;
++	  goto fail;
++
++	case notwordbound:
++	  DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
++	  if (AT_WORD_BOUNDARY (d))
++	    goto fail;
++	  break;
++#else
++	case wordbound:
++	{
++	  boolean prevchar, thischar;
++
++	  DEBUG_PRINT1 ("EXECUTING wordbound.\n");
++	  if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
++	    break;
++
++	  prevchar = WORDCHAR_P (d - 1);
++	  thischar = WORDCHAR_P (d);
++	  if (prevchar != thischar)
++	    break;
++	  goto fail;
++	}
++
++      case notwordbound:
++	{
++	  boolean prevchar, thischar;
++
++	  DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
++	  if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
++	    goto fail;
++
++	  prevchar = WORDCHAR_P (d - 1);
++	  thischar = WORDCHAR_P (d);
++	  if (prevchar != thischar)
++	    goto fail;
++	  break;
++	}
++#endif
++
++	case wordbeg:
++          DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
++	  if (!AT_STRINGS_END (d) && WORDCHAR_P (d)
++	      && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
++	    break;
++          goto fail;
++
++	case wordend:
++          DEBUG_PRINT1 ("EXECUTING wordend.\n");
++	  if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
++              && (AT_STRINGS_END (d) || !WORDCHAR_P (d)))
++	    break;
++          goto fail;
++
++#ifdef emacs
++  	case before_dot:
++          DEBUG_PRINT1 ("EXECUTING before_dot.\n");
++ 	  if (PTR_CHAR_POS ((unsigned char *) d) >= point)
++  	    goto fail;
++  	  break;
++
++  	case at_dot:
++          DEBUG_PRINT1 ("EXECUTING at_dot.\n");
++ 	  if (PTR_CHAR_POS ((unsigned char *) d) != point)
++  	    goto fail;
++  	  break;
++
++  	case after_dot:
++          DEBUG_PRINT1 ("EXECUTING after_dot.\n");
++          if (PTR_CHAR_POS ((unsigned char *) d) <= point)
++  	    goto fail;
++  	  break;
++
++	case syntaxspec:
++          DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
++	  mcnt = *p++;
++	  goto matchsyntax;
++
++        case wordchar:
++          DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
++	  mcnt = (int) Sword;
++        matchsyntax:
++	  PREFETCH ();
++	  /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
++	  d++;
++	  if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
++	    goto fail;
++          SET_REGS_MATCHED ();
++	  break;
++
++	case notsyntaxspec:
++          DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
++	  mcnt = *p++;
++	  goto matchnotsyntax;
++
++        case notwordchar:
++          DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
++	  mcnt = (int) Sword;
++        matchnotsyntax:
++	  PREFETCH ();
++	  /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
++	  d++;
++	  if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
++	    goto fail;
++	  SET_REGS_MATCHED ();
++          break;
++
++#else /* not emacs */
++	case wordchar:
++          DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
++	  PREFETCH ();
++          if (!WORDCHAR_P (d))
++            goto fail;
++	  SET_REGS_MATCHED ();
++          d++;
++	  break;
++
++	case notwordchar:
++          DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
++	  PREFETCH ();
++	  if (WORDCHAR_P (d))
++            goto fail;
++          SET_REGS_MATCHED ();
++          d++;
++	  break;
++#endif /* not emacs */
++
++        default:
++          abort ();
++	}
++      continue;  /* Successfully executed one pattern command; keep going.  */
++
++
++    /* We goto here if a matching operation fails. */
++    fail:
++      if (!FAIL_STACK_EMPTY ())
++	{ /* A restart point is known.  Restore to that state.  */
++          DEBUG_PRINT1 ("\nFAIL:\n");
++          POP_FAILURE_POINT (d, p,
++                             lowest_active_reg, highest_active_reg,
++                             regstart, regend, reg_info);
++
++          /* If this failure point is a dummy, try the next one.  */
++          if (!p)
++	    goto fail;
++
++          /* If we failed to the end of the pattern, don't examine *p.  */
++	  assert (p <= pend);
++          if (p < pend)
++            {
++              boolean is_a_jump_n = false;
++
++              /* If failed to a backwards jump that's part of a repetition
++                 loop, need to pop this failure point and use the next one.  */
++              switch ((re_opcode_t) *p)
++                {
++                case jump_n:
++                  is_a_jump_n = true;
++                case maybe_pop_jump:
++                case pop_failure_jump:
++                case jump:
++                  p1 = p + 1;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  p1 += mcnt;
++
++                  if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
++                      || (!is_a_jump_n
++                          && (re_opcode_t) *p1 == on_failure_jump))
++                    goto fail;
++                  break;
++                default:
++                  /* do nothing */ ;
++                }
++            }
++
++          if (d >= string1 && d <= end1)
++	    dend = end_match_1;
++        }
++      else
++        break;   /* Matching at this starting point really fails.  */
++    } /* for (;;) */
++
++  if (best_regs_set)
++    goto restore_best_regs;
++
++  FREE_VARIABLES ();
++
++  return -1;         			/* Failure to match.  */
++} /* re_match_2 */
++\f
++/* Subroutine definitions for re_match_2.  */
++
++
++/* We are passed P pointing to a register number after a start_memory.
++
++   Return true if the pattern up to the corresponding stop_memory can
++   match the empty string, and false otherwise.
++
++   If we find the matching stop_memory, sets P to point to one past its number.
++   Otherwise, sets P to an undefined byte less than or equal to END.
++
++   We don't handle duplicates properly (yet).  */
++
++static boolean
++PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
++                                   PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  /* Point to after the args to the start_memory.  */
++  UCHAR_T *p1 = *p + 2;
++
++  while (p1 < end)
++    {
++      /* Skip over opcodes that can match nothing, and return true or
++	 false, as appropriate, when we get to one that can't, or to the
++         matching stop_memory.  */
++
++      switch ((re_opcode_t) *p1)
++        {
++        /* Could be either a loop or a series of alternatives.  */
++        case on_failure_jump:
++          p1++;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++
++          /* If the next operation is not a jump backwards in the
++	     pattern.  */
++
++	  if (mcnt >= 0)
++	    {
++              /* Go through the on_failure_jumps of the alternatives,
++                 seeing if any of the alternatives cannot match nothing.
++                 The last alternative starts with only a jump,
++                 whereas the rest start with on_failure_jump and end
++                 with a jump, e.g., here is the pattern for `a|b|c':
++
++                 /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
++                 /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
++                 /exactn/1/c
++
++                 So, we have to first go through the first (n-1)
++                 alternatives and then deal with the last one separately.  */
++
++
++              /* Deal with the first (n-1) alternatives, which start
++                 with an on_failure_jump (see above) that jumps to right
++                 past a jump_past_alt.  */
++
++              while ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] ==
++		     jump_past_alt)
++                {
++                  /* `mcnt' holds how many bytes long the alternative
++                     is, including the ending `jump_past_alt' and
++                     its number.  */
++
++                  if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt -
++						(1 + OFFSET_ADDRESS_SIZE),
++						reg_info))
++                    return false;
++
++                  /* Move to right after this alternative, including the
++		     jump_past_alt.  */
++                  p1 += mcnt;
++
++                  /* Break if it's the beginning of an n-th alternative
++                     that doesn't begin with an on_failure_jump.  */
++                  if ((re_opcode_t) *p1 != on_failure_jump)
++                    break;
++
++		  /* Still have to check that it's not an n-th
++		     alternative that starts with an on_failure_jump.  */
++		  p1++;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  if ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] !=
++		      jump_past_alt)
++                    {
++		      /* Get to the beginning of the n-th alternative.  */
++                      p1 -= 1 + OFFSET_ADDRESS_SIZE;
++                      break;
++                    }
++                }
++
++              /* Deal with the last alternative: go back and get number
++                 of the `jump_past_alt' just before it.  `mcnt' contains
++                 the length of the alternative.  */
++              EXTRACT_NUMBER (mcnt, p1 - OFFSET_ADDRESS_SIZE);
++
++              if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt, reg_info))
++                return false;
++
++              p1 += mcnt;	/* Get past the n-th alternative.  */
++            } /* if mcnt > 0 */
++          break;
++
++
++        case stop_memory:
++	  assert (p1[1] == **p);
++          *p = p1 + 2;
++          return true;
++
++
++        default:
++          if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
++            return false;
++        }
++    } /* while p1 < end */
++
++  return false;
++} /* group_match_null_string_p */
++
++
++/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
++   It expects P to be the first byte of a single alternative and END one
++   byte past the last. The alternative can contain groups.  */
++
++static boolean
++PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end,
++                                 PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  UCHAR_T *p1 = p;
++
++  while (p1 < end)
++    {
++      /* Skip over opcodes that can match nothing, and break when we get
++         to one that can't.  */
++
++      switch ((re_opcode_t) *p1)
++        {
++	/* It's a loop.  */
++        case on_failure_jump:
++          p1++;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++          p1 += mcnt;
++          break;
++
++	default:
++          if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
++            return false;
++        }
++    }  /* while p1 < end */
++
++  return true;
++} /* alt_match_null_string_p */
++
++
++/* Deals with the ops common to group_match_null_string_p and
++   alt_match_null_string_p.
++
++   Sets P to one after the op and its arguments, if any.  */
++
++static boolean
++PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
++                                       PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  boolean ret;
++  int reg_no;
++  UCHAR_T *p1 = *p;
++
++  switch ((re_opcode_t) *p1++)
++    {
++    case no_op:
++    case begline:
++    case endline:
++    case begbuf:
++    case endbuf:
++    case wordbeg:
++    case wordend:
++    case wordbound:
++    case notwordbound:
++#ifdef emacs
++    case before_dot:
++    case at_dot:
++    case after_dot:
++#endif
++      break;
++
++    case start_memory:
++      reg_no = *p1;
++      assert (reg_no > 0 && reg_no <= MAX_REGNUM);
++      ret = PREFIX(group_match_null_string_p) (&p1, end, reg_info);
++
++      /* Have to set this here in case we're checking a group which
++         contains a group and a back reference to it.  */
++
++      if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
++        REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
++
++      if (!ret)
++        return false;
++      break;
++
++    /* If this is an optimized succeed_n for zero times, make the jump.  */
++    case jump:
++      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++      if (mcnt >= 0)
++        p1 += mcnt;
++      else
++        return false;
++      break;
++
++    case succeed_n:
++      /* Get to the number of times to succeed.  */
++      p1 += OFFSET_ADDRESS_SIZE;
++      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++
++      if (mcnt == 0)
++        {
++          p1 -= 2 * OFFSET_ADDRESS_SIZE;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++          p1 += mcnt;
++        }
++      else
++        return false;
++      break;
++
++    case duplicate:
++      if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
++        return false;
++      break;
++
++    case set_number_at:
++      p1 += 2 * OFFSET_ADDRESS_SIZE;
++
++    default:
++      /* All other opcodes mean we cannot match the empty string.  */
++      return false;
++  }
++
++  *p = p1;
++  return true;
++} /* common_op_match_null_string_p */
++
++
++/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
++   bytes; nonzero otherwise.  */
++
++static int
++PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len,
++                        RE_TRANSLATE_TYPE translate)
++{
++  register const UCHAR_T *p1 = (const UCHAR_T *) s1;
++  register const UCHAR_T *p2 = (const UCHAR_T *) s2;
++  while (len)
++    {
++#ifdef WCHAR
++      if (((*p1<=0xff)?translate[*p1++]:*p1++)
++	  != ((*p2<=0xff)?translate[*p2++]:*p2++))
++	return 1;
++#else /* BYTE */
++      if (translate[*p1++] != translate[*p2++]) return 1;
++#endif /* WCHAR */
++      len--;
++    }
++  return 0;
++}
++\f
++
++#else /* not INSIDE_RECURSION */
++
++/* Entry points for GNU code.  */
++
++/* re_compile_pattern is the GNU regular expression compiler: it
++   compiles PATTERN (of length SIZE) and puts the result in BUFP.
++   Returns 0 if the pattern was valid, otherwise an error string.
++
++   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
++   are set in BUFP on entry.
++
++   We call regex_compile to do the actual compilation.  */
++
++const char *
++re_compile_pattern (const char *pattern, size_t length,
++                    struct re_pattern_buffer *bufp)
++{
++  reg_errcode_t ret;
++
++  /* GNU code is written to assume at least RE_NREGS registers will be set
++     (and at least one extra will be -1).  */
++  bufp->regs_allocated = REGS_UNALLOCATED;
++
++  /* And GNU code determines whether or not to get register information
++     by passing null for the REGS argument to re_match, etc., not by
++     setting no_sub.  */
++  bufp->no_sub = 0;
++
++  /* Match anchors at newline.  */
++  bufp->newline_anchor = 1;
++
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (pattern, length, re_syntax_options, bufp);
++  else
++# endif
++    ret = byte_regex_compile (pattern, length, re_syntax_options, bufp);
++
++  if (!ret)
++    return NULL;
++  return gettext (re_error_msgid[(int) ret]);
++}
++#ifdef _LIBC
++weak_alias (__re_compile_pattern, re_compile_pattern)
++#endif
++\f
++/* Entry points compatible with 4.2 BSD regex library.  We don't define
++   them unless specifically requested.  */
++
++#if defined _REGEX_RE_COMP || defined _LIBC
++
++/* BSD has one and only one pattern buffer.  */
++static struct re_pattern_buffer re_comp_buf;
++
++char *
++#ifdef _LIBC
++/* Make these definitions weak in libc, so POSIX programs can redefine
++   these names if they don't use our functions, and still use
++   regcomp/regexec below without link errors.  */
++weak_function
++#endif
++re_comp (const char *s)
++{
++  reg_errcode_t ret;
++
++  if (!s)
++    {
++      if (!re_comp_buf.buffer)
++	return (char *) gettext ("No previous regular expression");
++      return 0;
++    }
++
++  if (!re_comp_buf.buffer)
++    {
++      re_comp_buf.buffer = (unsigned char *) malloc (200);
++      if (re_comp_buf.buffer == NULL)
++        return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
++      re_comp_buf.allocated = 200;
++
++      re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
++      if (re_comp_buf.fastmap == NULL)
++	return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
++    }
++
++  /* Since `re_exec' always passes NULL for the `regs' argument, we
++     don't need to initialize the pattern buffer fields which affect it.  */
++
++  /* Match anchors at newlines.  */
++  re_comp_buf.newline_anchor = 1;
++
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
++  else
++# endif
++    ret = byte_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
++
++  if (!ret)
++    return NULL;
++
++  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
++  return (char *) gettext (re_error_msgid[(int) ret]);
++}
++
++
++int
++#ifdef _LIBC
++weak_function
++#endif
++re_exec (const char *s)
++{
++  const int len = strlen (s);
++  return
++    0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
++}
++
++#endif /* _REGEX_RE_COMP */
++\f
++/* POSIX.2 functions.  Don't define these for Emacs.  */
++
++#ifndef emacs
++
++/* regcomp takes a regular expression as a string and compiles it.
++
++   PREG is a regex_t *.  We do not expect any fields to be initialized,
++   since POSIX says we shouldn't.  Thus, we set
++
++     `buffer' to the compiled pattern;
++     `used' to the length of the compiled pattern;
++     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
++       REG_EXTENDED bit in CFLAGS is set; otherwise, to
++       RE_SYNTAX_POSIX_BASIC;
++     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
++     `fastmap' to an allocated space for the fastmap;
++     `fastmap_accurate' to zero;
++     `re_nsub' to the number of subexpressions in PATTERN.
++
++   PATTERN is the address of the pattern string.
++
++   CFLAGS is a series of bits which affect compilation.
++
++     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
++     use POSIX basic syntax.
++
++     If REG_NEWLINE is set, then . and [^...] don't match newline.
++     Also, regexec will try a match beginning after every newline.
++
++     If REG_ICASE is set, then we considers upper- and lowercase
++     versions of letters to be equivalent when matching.
++
++     If REG_NOSUB is set, then when PREG is passed to regexec, that
++     routine will report only success or failure, and nothing about the
++     registers.
++
++   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
++   the return codes and their meanings.)  */
++
++int
++regcomp (regex_t *preg, const char *pattern, int cflags)
++{
++  reg_errcode_t ret;
++  reg_syntax_t syntax
++    = (cflags & REG_EXTENDED) ?
++      RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
++
++  /* regex_compile will allocate the space for the compiled pattern.  */
++  preg->buffer = 0;
++  preg->allocated = 0;
++  preg->used = 0;
++
++  /* Try to allocate space for the fastmap.  */
++  preg->fastmap = (char *) malloc (1 << BYTEWIDTH);
++
++  if (cflags & REG_ICASE)
++    {
++      int i;
++
++      preg->translate
++	= (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
++				      * sizeof (*(RE_TRANSLATE_TYPE)0));
++      if (preg->translate == NULL)
++        return (int) REG_ESPACE;
++
++      /* Map uppercase characters to corresponding lowercase ones.  */
++      for (i = 0; i < CHAR_SET_SIZE; i++)
++        preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i;
++    }
++  else
++    preg->translate = NULL;
++
++  /* If REG_NEWLINE is set, newlines are treated differently.  */
++  if (cflags & REG_NEWLINE)
++    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
++      syntax &= ~RE_DOT_NEWLINE;
++      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
++      /* It also changes the matching behavior.  */
++      preg->newline_anchor = 1;
++    }
++  else
++    preg->newline_anchor = 0;
++
++  preg->no_sub = !!(cflags & REG_NOSUB);
++
++  /* POSIX says a null character in the pattern terminates it, so we
++     can use strlen here in compiling the pattern.  */
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (pattern, strlen (pattern), syntax, preg);
++  else
++# endif
++    ret = byte_regex_compile (pattern, strlen (pattern), syntax, preg);
++
++  /* POSIX doesn't distinguish between an unmatched open-group and an
++     unmatched close-group: both are REG_EPAREN.  */
++  if (ret == REG_ERPAREN) ret = REG_EPAREN;
++
++  if (ret == REG_NOERROR && preg->fastmap)
++    {
++      /* Compute the fastmap now, since regexec cannot modify the pattern
++	 buffer.  */
++      if (re_compile_fastmap (preg) == -2)
++	{
++	  /* Some error occurred while computing the fastmap, just forget
++	     about it.  */
++	  free (preg->fastmap);
++	  preg->fastmap = NULL;
++	}
++    }
++
++  return (int) ret;
++}
++#ifdef _LIBC
++weak_alias (__regcomp, regcomp)
++#endif
++
++
++/* regexec searches for a given pattern, specified by PREG, in the
++   string STRING.
++
++   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
++   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
++   least NMATCH elements, and we set them to the offsets of the
++   corresponding matched substrings.
++
++   EFLAGS specifies `execution flags' which affect matching: if
++   REG_NOTBOL is set, then ^ does not match at the beginning of the
++   string; if REG_NOTEOL is set, then $ does not match at the end.
++
++   We return 0 if we find a match and REG_NOMATCH if not.  */
++
++int
++regexec (const regex_t *preg, const char *string, size_t nmatch,
++         regmatch_t pmatch[], int eflags)
++{
++  int ret;
++  struct re_registers regs;
++  regex_t private_preg;
++  int len = strlen (string);
++  boolean want_reg_info = !preg->no_sub && nmatch > 0;
++
++  private_preg = *preg;
++
++  private_preg.not_bol = !!(eflags & REG_NOTBOL);
++  private_preg.not_eol = !!(eflags & REG_NOTEOL);
++
++  /* The user has told us exactly how many registers to return
++     information about, via `nmatch'.  We have to pass that on to the
++     matching routines.  */
++  private_preg.regs_allocated = REGS_FIXED;
++
++  if (want_reg_info)
++    {
++      regs.num_regs = nmatch;
++      regs.start = TALLOC (nmatch * 2, regoff_t);
++      if (regs.start == NULL)
++        return (int) REG_NOMATCH;
++      regs.end = regs.start + nmatch;
++    }
++
++  /* Perform the searching operation.  */
++  ret = re_search (&private_preg, string, len,
++                   /* start: */ 0, /* range: */ len,
++                   want_reg_info ? &regs : (struct re_registers *) 0);
++
++  /* Copy the register information to the POSIX structure.  */
++  if (want_reg_info)
++    {
++      if (ret >= 0)
++        {
++          unsigned r;
++
++          for (r = 0; r < nmatch; r++)
++            {
++              pmatch[r].rm_so = regs.start[r];
++              pmatch[r].rm_eo = regs.end[r];
++            }
++        }
++
++      /* If we needed the temporary register info, free the space now.  */
++      free (regs.start);
++    }
++
++  /* We want zero return to mean success, unlike `re_search'.  */
++  return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
++}
++#ifdef _LIBC
++/* EGLIBC: This is handled in regexec-compat.c.  */
++/*weak_alias (__regexec, regexec)*/
++#include "regexec-compat.c"
++#endif
++
++
++/* Returns a message corresponding to an error code, ERRCODE, returned
++   from either regcomp or regexec.   We don't use PREG here.  */
++
++size_t
++regerror (int errcode, const regex_t *preg __attribute__ ((unused)),
++          char *errbuf, size_t errbuf_size)
++{
++  const char *msg;
++  size_t msg_size;
++
++  if (errcode < 0
++      || errcode >= (int) (sizeof (re_error_msgid)
++			   / sizeof (re_error_msgid[0])))
++    /* Only error codes returned by the rest of the code should be passed
++       to this routine.  If we are given anything else, or if other regex
++       code generates an invalid error code, then the program has a bug.
++       Dump core so we can fix it.  */
++    abort ();
++
++  msg = gettext (re_error_msgid[errcode]);
++
++  msg_size = strlen (msg) + 1; /* Includes the null.  */
++
++  if (errbuf_size != 0)
++    {
++      if (msg_size > errbuf_size)
++        {
++#if defined HAVE_MEMPCPY || defined _LIBC
++	  *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
++#else
++          memcpy (errbuf, msg, errbuf_size - 1);
++          errbuf[errbuf_size - 1] = 0;
++#endif
++        }
++      else
++        memcpy (errbuf, msg, msg_size);
++    }
++
++  return msg_size;
++}
++#ifdef _LIBC
++weak_alias (__regerror, regerror)
++#endif
++
++
++/* Free dynamically allocated space used by PREG.  */
++
++void
++regfree (regex_t *preg)
++{
++  if (preg->buffer != NULL)
++    free (preg->buffer);
++  preg->buffer = NULL;
++
++  preg->allocated = 0;
++  preg->used = 0;
++
++  if (preg->fastmap != NULL)
++    free (preg->fastmap);
++  preg->fastmap = NULL;
++  preg->fastmap_accurate = 0;
++
++  if (preg->translate != NULL)
++    free (preg->translate);
++  preg->translate = NULL;
++}
++#ifdef _LIBC
++weak_alias (__regfree, regfree)
++#endif
++
++#endif /* not emacs  */
++
++#endif /* not INSIDE_RECURSION */
++
++\f
++#undef STORE_NUMBER
++#undef STORE_NUMBER_AND_INCR
++#undef EXTRACT_NUMBER
++#undef EXTRACT_NUMBER_AND_INCR
++
++#undef DEBUG_PRINT_COMPILED_PATTERN
++#undef DEBUG_PRINT_DOUBLE_STRING
++
++#undef INIT_FAIL_STACK
++#undef RESET_FAIL_STACK
++#undef DOUBLE_FAIL_STACK
++#undef PUSH_PATTERN_OP
++#undef PUSH_FAILURE_POINTER
++#undef PUSH_FAILURE_INT
++#undef PUSH_FAILURE_ELT
++#undef POP_FAILURE_POINTER
++#undef POP_FAILURE_INT
++#undef POP_FAILURE_ELT
++#undef DEBUG_PUSH
++#undef DEBUG_POP
++#undef PUSH_FAILURE_POINT
++#undef POP_FAILURE_POINT
++
++#undef REG_UNSET_VALUE
++#undef REG_UNSET
++
++#undef PATFETCH
++#undef PATFETCH_RAW
++#undef PATUNFETCH
++#undef TRANSLATE
++
++#undef INIT_BUF_SIZE
++#undef GET_BUFFER_SPACE
++#undef BUF_PUSH
++#undef BUF_PUSH_2
++#undef BUF_PUSH_3
++#undef STORE_JUMP
++#undef STORE_JUMP2
++#undef INSERT_JUMP
++#undef INSERT_JUMP2
++#undef EXTEND_BUFFER
++#undef GET_UNSIGNED_NUMBER
++#undef FREE_STACK_RETURN
++
++# undef POINTER_TO_OFFSET
++# undef MATCHING_IN_FRST_STRING
++# undef PREFETCH
++# undef AT_STRINGS_BEG
++# undef AT_STRINGS_END
++# undef WORDCHAR_P
++# undef FREE_VAR
++# undef FREE_VARIABLES
++# undef NO_HIGHEST_ACTIVE_REG
++# undef NO_LOWEST_ACTIVE_REG
++
++# undef CHAR_T
++# undef UCHAR_T
++# undef COMPILED_BUFFER_VAR
++# undef OFFSET_ADDRESS_SIZE
++# undef CHAR_CLASS_SIZE
++# undef PREFIX
++# undef ARG_PREFIX
++# undef PUT_CHAR
++# undef BYTE
++# undef WCHAR
++
++# define DEFINED_ONCE
+diff --git a/pwd/Makefile b/pwd/Makefile
+index 7f6de03..916d546 100644
+--- a/pwd/Makefile
++++ b/pwd/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for pwd portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= pwd
+ 
+ include ../Makeconfig
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 1dcb75f..2e4b630 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for resolv portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= resolv
+ 
+ include ../Makeconfig
+@@ -27,21 +29,22 @@ headers	:= resolv.h \
+ 	   arpa/nameser.h arpa/nameser_compat.h \
+ 	   sys/bitypes.h
+ 
+-routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
+-	    res_hconf res_libc res-state
++routines-$(OPTION_EGLIBC_INET) \
++	+= herror inet_addr inet_ntop inet_pton nsap_addr res_init \
++	   res_hconf res_libc res-state
+ 
+-tests = tst-aton tst-leaks tst-inet_ntop
+-xtests = tst-leaks2
++tests-$(OPTION_EGLIBC_INET) += tst-aton tst-leaks tst-inet_ntop
++xtests-$(OPTION_EGLIBC_INET) += tst-leaks2
+ 
+ generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
+ 
+-extra-libs := libresolv libnss_dns
++extra-libs-$(OPTION_EGLIBC_INET) += libresolv libnss_dns
+ ifeq ($(have-thread-library),yes)
+-extra-libs += libanl
+-routines += gai_sigqueue
++extra-libs-$(OPTION_EGLIBC_INET_ANL) += libanl
++routines-$(OPTION_EGLIBC_INET) += gai_sigqueue
+ tests += tst-res_hconf_reorder
+ endif
+-extra-libs-others = $(extra-libs)
++extra-libs-others-y += $(extra-libs-y)
+ libresolv-routines := gethnamaddr res_comp res_debug	\
+ 		      res_data res_mkquery res_query res_send		\
+ 		      inet_net_ntop inet_net_pton inet_neta base64	\
+@@ -61,7 +64,7 @@ routines                += $(libnss_dns-routines) $(libresolv-routines)
+ static-only-routines    += $(libnss_dns-routines) $(libresolv-routines)
+ endif
+ 
+-ifeq (yesyes,$(build-shared)$(have-thread-library))
++ifeq (yesyesy,$(build-shared)$(have-thread-library)$(OPTION_EGLIBC_INET_ANL))
+ tests: $(objpfx)ga_test
+ endif
+ 
+diff --git a/stdio-common/Makefile b/stdio-common/Makefile
+index d0bf0e1..8655801 100644
+--- a/stdio-common/Makefile
++++ b/stdio-common/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Specific makefile for stdio-common.
+ #
++include ../option-groups.mak
++
+ subdir	:= stdio-common
+ 
+ include ../Makeconfig
+@@ -30,7 +32,7 @@ routines	:=							      \
+ 	vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex	      \
+ 	reg-modifier reg-type						      \
+ 	printf_size fprintf printf snprintf sprintf asprintf dprintf	      \
+-	vfwprintf vfscanf vfwscanf					      \
++	vfscanf								      \
+ 	fscanf scanf sscanf						      \
+ 	perror psignal							      \
+ 	tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname		      \
+@@ -41,23 +43,36 @@ routines	:=							      \
+ 	isoc99_vsscanf							      \
+ 	psiginfo
+ 
+-aux	:= errlist siglist printf-parsemb printf-parsewc fxprintf
++# Ideally, _itowa and itowa-digits would be in this option group as
++# well, but it is used unconditionally by printf_fp and printf_fphex,
++# and it didn't seem straightforward to disentangle it.
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++	+= vfwprintf vfwscanf
++
++aux	:= errlist siglist printf-parsemb fxprintf
++aux-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += printf-parsewc
+ 
+ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
+ 	 temptest tst-fileno test-fwrite tst-ungetc tst-ferror \
+ 	 xbug errnobug \
+ 	 bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \
+-	 tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \
++	 tfformat tiformat tllformat tstdiomisc tst-printfsz \
+ 	 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \
+-	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
+-	 tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
+-	 tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \
++	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
++	 tst-fseek tst-fmemopen tst-gets \
++	 tst-sprintf tst-rndseek tst-fdopen tst-fphex \
+ 	 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
+-	 tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
+-	 bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
+-	 scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
+-	 bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
++	 tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
++	 bug19 tst-popen2 scanf14 scanf15 bug21 bug22 \
++	 scanf16 scanf17 tst-setvbuf1 bug23 bug24 \
++	 bug-vfprintf-nargs tst-sprintf3 \
+ 	 bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++	 += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
++	 += tst-perror bug19a bug20 tst-long-dbl-fphex tst-fphex-wide
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++	 += bug18a tst-swscanf tst-wc-printf
+ 
+ test-srcs = tst-unbputc tst-printf
+ 
+diff --git a/stdio-common/_i18n_number.h b/stdio-common/_i18n_number.h
+index 3c73044..ac62b3a 100644
+--- a/stdio-common/_i18n_number.h
++++ b/stdio-common/_i18n_number.h
+@@ -19,10 +19,13 @@
+ #include <stdbool.h>
+ #include <wchar.h>
+ #include <wctype.h>
++#include <gnu/option-groups.h>
+ 
+ #include "../locale/outdigits.h"
+ #include "../locale/outdigitswc.h"
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
++
+ static CHAR_T *
+ _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
+ {
+@@ -115,3 +118,13 @@ _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
+ 
+   return w;
+ }
++
++#else
++
++static CHAR_T *
++_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
++{
++  return w;
++}
++
++#endif
+diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c
+index 7b2eb94..8476076 100644
+--- a/stdio-common/fxprintf.c
++++ b/stdio-common/fxprintf.c
+@@ -23,6 +23,7 @@
+ #include <wchar.h>
+ #include <string.h>
+ #include <libioP.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -37,6 +38,7 @@ __fxprintf (FILE *fp, const char *fmt, ...)
+   int res;
+   if (_IO_fwide (fp, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       size_t len = strlen (fmt) + 1;
+       wchar_t wfmt[len];
+       for (size_t i = 0; i < len; ++i)
+@@ -45,6 +47,9 @@ __fxprintf (FILE *fp, const char *fmt, ...)
+ 	  wfmt[i] = fmt[i];
+ 	}
+       res = __vfwprintf (fp, wfmt, ap);
++#else
++      abort();
++#endif
+     }
+   else
+     res = _IO_vfprintf (fp, fmt, ap);
+diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
+index 3023b20..bd0df66 100644
+--- a/stdio-common/printf_fp.c
++++ b/stdio-common/printf_fp.c
+@@ -39,6 +39,7 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ #include <stdbool.h>
+ #include <rounding-mode.h>
+ 
+@@ -142,6 +143,10 @@ extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
+ extern unsigned int __guess_grouping (unsigned int intdig_max,
+ 				      const char *grouping);
+ 
++/* Ideally, when OPTION_EGLIBC_LOCALE_CODE is disabled, this should do
++   all its work in ordinary characters, rather than doing it in wide
++   characters and then converting at the end.  But that is a challenge
++   for another day.  */
+ 
+ static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
+ 			      unsigned int intdig_no, const char *grouping,
+@@ -251,7 +256,14 @@ ___printf_fp (FILE *fp,
+   mp_limb_t cy;
+ 
+   /* Nonzero if this is output on a wide character stream.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+ 
+   /* Buffer in which we produce the output.  */
+   wchar_t *wbuffer = NULL;
+@@ -261,6 +273,7 @@ ___printf_fp (FILE *fp,
+   p.expsign = 0;
+ 
+   /* Figure out the decimal point character.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->extra == 0)
+     {
+       decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+@@ -280,7 +293,13 @@ ___printf_fp (FILE *fp,
+   /* The decimal point character must not be zero.  */
+   assert (*decimal != '\0');
+   assert (decimalwc != L'\0');
++#else
++  /* Hard-code values from 'C' locale.  */
++  decimal = ".";
++  decimalwc = L'.';
++#endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->group)
+     {
+       if (info->extra == 0)
+@@ -324,6 +343,9 @@ ___printf_fp (FILE *fp,
+     }
+   else
+     grouping = NULL;
++#else
++  grouping = NULL;
++#endif
+ 
+   /* Fetch the argument value.	*/
+ #ifndef __NO_LONG_DOUBLE_MATH
+diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
+index 6c3b5e9..f660ce0 100644
+--- a/stdio-common/printf_fphex.c
++++ b/stdio-common/printf_fphex.c
+@@ -28,6 +28,7 @@
+ #include <_itoa.h>
+ #include <_itowa.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ #include <stdbool.h>
+ #include <rounding-mode.h>
+ 
+@@ -139,10 +140,18 @@ __printf_fphex (FILE *fp,
+   int done = 0;
+ 
+   /* Nonzero if this is output on a wide character stream.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+ 
+ 
+   /* Figure out the decimal point character.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->extra == 0)
+     {
+       decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+@@ -156,6 +165,10 @@ __printf_fphex (FILE *fp,
+     }
+   /* The decimal point character must never be zero.  */
+   assert (*decimal != '\0' && decimalwc != L'\0');
++#else
++  decimal = ".";
++  decimalwc = L'.';
++#endif
+ 
+ 
+   /* Fetch the argument value.	*/
+diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
+index 7dcd58e..6fb7491 100644
+--- a/stdio-common/printf_size.c
++++ b/stdio-common/printf_size.c
+@@ -23,6 +23,7 @@
+ #include <math.h>
+ #include <printf.h>
+ #include <libioP.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ /* This defines make it possible to use the same code for GNU C library and
+@@ -116,7 +117,14 @@ __printf_size (FILE *fp, const struct printf_info *info,
+ 
+   struct printf_info fp_info;
+   int done = 0;
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+   int res;
+ 
+   /* Fetch the argument value.	*/
+diff --git a/stdio-common/scanf14.c b/stdio-common/scanf14.c
+index cffccb0..6cc260a 100644
+--- a/stdio-common/scanf14.c
++++ b/stdio-common/scanf14.c
+@@ -3,6 +3,7 @@
+ #include <string.h>
+ #include <wchar.h>
+ #include <libc-internal.h>
++#include <gnu/option-groups.h>
+ 
+ #define FAIL() \
+   do {							\
+@@ -48,6 +49,7 @@ main (void)
+   /* See explanation above.  */
+   DIAG_PUSH_NEEDS_COMMENT;
+   DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat");
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2)
+     FAIL ();
+   else
+@@ -57,6 +59,7 @@ main (void)
+       memset (lsp, 'x', sizeof L"3.25");
+       free (lsp);
+     }
++#endif
+   if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2)
+     FAIL ();
+   else
+diff --git a/stdio-common/tst-popen.c b/stdio-common/tst-popen.c
+index 5def27f..7c9b91e 100644
+--- a/stdio-common/tst-popen.c
++++ b/stdio-common/tst-popen.c
+@@ -19,6 +19,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ do_test (void)
+@@ -34,12 +35,14 @@ do_test (void)
+       return 1;
+     }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+   /* POSIX says that pipe streams are byte-oriented.  */
+   if (fwide (f, 0) >= 0)
+     {
+       puts ("popen did not return byte-oriented stream");
+       result = 1;
+     }
++#endif
+ 
+   if (getline (&line, &len, f) != 5)
+     {
+diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c
+index d5284b9..f1e3d21 100644
+--- a/stdio-common/tst-sprintf.c
++++ b/stdio-common/tst-sprintf.c
+@@ -3,7 +3,7 @@
+ #include <locale.h>
+ #include <string.h>
+ #include <libc-internal.h>
+-
++#include <gnu/option-groups.h>
+ 
+ static int
+ do_test (void)
+@@ -11,12 +11,14 @@ do_test (void)
+   char buf[100];
+   int result = 0;
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (sprintf (buf, "%.0ls", L"foo") != 0
+       || strlen (buf) != 0)
+     {
+       puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output");
+       result = 1;
+     }
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+ #define SIZE (1024*70000)
+ #define STR(x) #x
+diff --git a/stdio-common/tstdiomisc.c b/stdio-common/tstdiomisc.c
+index 5548a71..31ed024 100644
+--- a/stdio-common/tstdiomisc.c
++++ b/stdio-common/tstdiomisc.c
+@@ -4,6 +4,7 @@
+ #include <string.h>
+ #include <wchar.h>
+ #include <libc-internal.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ t1 (void)
+@@ -134,6 +135,7 @@ F (void)
+   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+ 	  buf);
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
+ 	    qnanval, qnanval, qnanval, qnanval,
+ 	    qnanval, qnanval, qnanval, qnanval);
+@@ -171,6 +173,7 @@ F (void)
+   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+ 	  wbuf);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   lqnanval = NAN;
+ 
+@@ -215,6 +218,7 @@ F (void)
+   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+ 	  buf);
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
+ 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
+ 	    lqnanval, lqnanval, lqnanval, lqnanval,
+@@ -259,6 +263,7 @@ F (void)
+   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+ 	  wbuf);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   return result;
+ }
+diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
+index 0592e70..f21d973 100644
+--- a/stdio-common/vfprintf.c
++++ b/stdio-common/vfprintf.c
+@@ -29,6 +29,7 @@
+ #include <_itoa.h>
+ #include <locale/localeinfo.h>
+ #include <stdio.h>
++#include <gnu/option-groups.h>
+ 
+ /* This code is shared between the standard stdio implementation found
+    in GNU C library and the libio implementation originally found in
+@@ -140,6 +141,18 @@ typedef wchar_t THOUSANDS_SEP_T;
+ # define EOF WEOF
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define MULTIBYTE_SUPPORT (1)
++#else
++# define MULTIBYTE_SUPPORT (0)
++#endif
++
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define LOCALE_SUPPORT (1)
++#else
++# define LOCALE_SUPPORT (0)
++#endif
++
+ #include "_i18n_number.h"
+ 
+ /* Include the shared code for parsing the format string.  */
+@@ -1065,8 +1078,11 @@ static const uint8_t jump_table[] =
+ # define process_string_arg(fspec) \
+     LABEL (form_character):						      \
+       /* Character.  */							      \
+-      if (is_long)							      \
+-	goto LABEL (form_wcharacter);					      \
++      if (is_long)                                                            \
++        {                                                                     \
++          assert (MULTIBYTE_SUPPORT);                                         \
++          goto LABEL (form_wcharacter);                                       \
++        }                                                                     \
+       --width;	/* Account for the character itself.  */		      \
+       if (!left)							      \
+ 	PAD (' ');							      \
+@@ -1079,6 +1095,7 @@ static const uint8_t jump_table[] =
+       break;								      \
+ 									      \
+     LABEL (form_wcharacter):						      \
++      assert (MULTIBYTE_SUPPORT);                                             \
+       {									      \
+ 	/* Wide character.  */						      \
+ 	char buf[MB_CUR_MAX];						      \
+@@ -1145,6 +1162,7 @@ static const uint8_t jump_table[] =
+ 	  }								      \
+ 	else								      \
+ 	  {								      \
++            assert (MULTIBYTE_SUPPORT);                                       \
+ 	    const wchar_t *s2 = (const wchar_t *) string;		      \
+ 	    mbstate_t mbstate;						      \
+ 									      \
+@@ -1399,7 +1417,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
+     LABEL (flag_quote):
+       group = 1;
+ 
+-      if (grouping == (const char *) -1)
++      if (! LOCALE_SUPPORT)
++        grouping = NULL;
++      else if (grouping == (const char *) -1)
+ 	{
+ #ifdef COMPILE_WPRINTF
+ 	  thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+@@ -1728,8 +1748,9 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format,
+   size_t cnt;
+ 
+   CHAR_T *workstart = NULL;
+-
+-  if (grouping == (const char *) -1)
++  if (! LOCALE_SUPPORT)
++    grouping = NULL;
++  else if (grouping == (const char *) -1)
+     {
+ #ifdef COMPILE_WPRINTF
+       thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
+index 0e204e7..66cc0af 100644
+--- a/stdio-common/vfscanf.c
++++ b/stdio-common/vfscanf.c
+@@ -29,6 +29,7 @@
+ #include <wctype.h>
+ #include <bits/libc-lock.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ 
+ #ifdef	__GNUC__
+ # define HAVE_LONGLONG
+@@ -133,6 +134,12 @@
+ # define WINT_T		int
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define MULTIBYTE_SUPPORT (1)
++#else
++# define MULTIBYTE_SUPPORT (0)
++#endif
++
+ #define encode_error() do {						      \
+ 			  errval = 4;					      \
+ 			  __set_errno (EILSEQ);				      \
+@@ -316,24 +323,35 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+   ARGCHECK (s, format);
+ 
+  {
+-#ifndef COMPILE_WSCANF
++#if __OPTION_EGLIBC_LOCALE_CODE && !defined (COMPILE_WSCANF)
+    struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
+ #endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+    /* Figure out the decimal point character.  */
+-#ifdef COMPILE_WSCANF
++# ifdef COMPILE_WSCANF
+    decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
+-#else
++# else
+    decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
+-#endif
++# endif
+    /* Figure out the thousands separator character.  */
+-#ifdef COMPILE_WSCANF
++# ifdef COMPILE_WSCANF
+    thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
+-#else
++# else
+    thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
+    if (*thousands == '\0')
+      thousands = NULL;
+-#endif
++# endif
++#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
++   /* Hard-code values from the C locale.  */
++# ifdef COMPILE_WSCANF
++   decimal = L'.';
++   thousands = L'\0';
++# else
++   decimal = ".";
++   thousands = NULL;
++# endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+  }
+ 
+   /* Lock the stream.  */
+@@ -385,6 +403,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ #ifndef COMPILE_WSCANF
+       if (!isascii ((unsigned char) *f))
+ 	{
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  /* Non-ASCII, may be a multibyte.  */
+ 	  int len = __mbrlen (f, strlen (f), &state);
+ 	  if (len > 0)
+@@ -830,6 +850,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ 	    }
+ 	  /* FALLTHROUGH */
+ 	case L_('C'):
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  if (width == -1)
+ 	    width = 1;
+ 
+@@ -1172,6 +1194,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ 	  /* FALLTHROUGH */
+ 
+ 	case L_('S'):
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  {
+ #ifndef COMPILE_WSCANF
+ 	    mbstate_t cstate;
+@@ -1419,10 +1443,17 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ 	      const char *mbdigits[10];
+ 	      const char *mbdigits_extended[10];
+ #endif
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	      /*  "to_inpunct" is a map from ASCII digits to their
+ 		  equivalent in locale. This is defined for locales
+ 		  which use an extra digits set.  */
+ 	      wctrans_t map = __wctrans ("to_inpunct");
++#else
++              /* This will always be the case when
++                 OPTION_EGLIBC_LOCALE_CODE is disabled, but the
++                 compiler can't figure that out.  */
++              wctrans_t map = NULL;
++#endif
+ 	      int n;
+ 
+ 	      from_level = 0;
+@@ -2088,6 +2119,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ 		--width;
+ 	    }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	  wctrans_t map;
+ 	  if (__builtin_expect ((flags & I18N) != 0, 0)
+ 	      /* Hexadecimal floats make no sense, fixing localized
+@@ -2304,6 +2336,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ 	      ;
+ #endif
+ 	    }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 
+ 	  /* Have we read any character?  If we try to read a number
+ 	     in hexadecimal notation and we have read only the `0x'
+@@ -2343,7 +2376,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ 
+ 	case L_('['):	/* Character class.  */
+ 	  if (flags & LONG)
+-	    STRING_ARG (wstr, wchar_t, 100);
++            {
++              assert (MULTIBYTE_SUPPORT);
++              STRING_ARG (wstr, wchar_t, 100);
++            }
+ 	  else
+ 	    STRING_ARG (str, char, 100);
+ 
+@@ -2417,6 +2453,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ 	  if (flags & LONG)
+ 	    {
+ 	      size_t now = read_in;
++              assert (MULTIBYTE_SUPPORT);
+ #ifdef COMPILE_WSCANF
+ 	      if (__glibc_unlikely (inchar () == WEOF))
+ 		input_error ();
+diff --git a/stdlib/Makefile b/stdlib/Makefile
+index 402466a..7e7e304 100644
+--- a/stdlib/Makefile
++++ b/stdlib/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for stdlib routines
+ #
++include ../option-groups.mak
++
+ subdir	:= stdlib
+ 
+ include ../Makeconfig
+@@ -30,7 +32,7 @@ headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
+ 	   alloca.h fmtmsg.h						      \
+ 	   bits/stdlib-bsearch.h
+ 
+-routines	:=							      \
++routines-y	:=							      \
+ 	atof atoi atol atoll						      \
+ 	abort								      \
+ 	bsearch qsort msort						      \
+@@ -39,7 +41,6 @@ routines	:=							      \
+ 	quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl     \
+ 	abs labs llabs							      \
+ 	div ldiv lldiv							      \
+-	mblen mbstowcs mbtowc wcstombs wctomb				      \
+ 	random random_r rand rand_r					      \
+ 	drand48 erand48 lrand48 nrand48 mrand48 jrand48			      \
+ 	srand48 seed48 lcong48						      \
+@@ -52,9 +53,18 @@ routines	:=							      \
+ 	strtof_l strtod_l strtold_l					      \
+ 	system canonicalize						      \
+ 	a64l l64a							      \
+-	rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg		      \
+-	strtoimax strtoumax wcstoimax wcstoumax				      \
++	getsubopt xpg_basename						      \
++	strtoimax strtoumax						      \
+ 	getcontext setcontext makecontext swapcontext
++routines-$(OPTION_EGLIBC_LOCALE_CODE) +=				      \
++	strfmon strfmon_l
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	mblen mbstowcs mbtowc wcstombs wctomb				      \
++	wcstoimax wcstoumax
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP))
++routines-y += rpmatch
++endif
++routines-$(OPTION_EGLIBC_FMTMSG) += fmtmsg
+ aux =	grouping groupingwc tens_in_limb
+ 
+ # These routines will be omitted from the libc shared object.
+@@ -62,20 +72,24 @@ aux =	grouping groupingwc tens_in_limb
+ # linked against when the shared library will be used.
+ static-only-routines = atexit at_quick_exit
+ 
+-test-srcs	:= tst-fmtmsg
+-tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
++test-srcs-$(OPTION_EGLIBC_FMTMSG)	:= tst-fmtmsg
++tests		:= tst-strtol tst-strtod testrand testsort testdiv	    \
+ 		   test-canon test-canon2 tst-strtoll tst-environ	    \
+ 		   tst-xpg-basename tst-random tst-random2 tst-bsearch	    \
+ 		   tst-limits tst-rand48 bug-strtod tst-setcontext          \
+-		   tst-setcontext2 test-a64l tst-qsort tst-system testmb2   \
+-		   bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3  \
+-		   tst-rand48-2 tst-makecontext tst-strtod4 tst-strtod5     \
++		   tst-setcontext2 test-a64l tst-qsort tst-system	    \
++		   bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 		    \
++		   tst-rand48-2 tst-makecontext 			    \
+ 		   tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1    \
+ 		   tst-makecontext3 bug-getcontext bug-fmtmsg1		    \
+ 		   tst-secure-getenv tst-strtod-overflow tst-strtod-round   \
+ 		   tst-tininess tst-strtod-underflow tst-tls-atexit	    \
+ 		   tst-setcontext3 tst-tls-atexit-nodelete
+ tests-static	:= tst-secure-getenv
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= tst-strtod3 tst-strtod4 tst-strtod5 testmb2
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++		+= testmb
+ 
+ modules-names	= tst-tls-atexit-lib
+ 
+@@ -116,8 +130,10 @@ CFLAGS-tst-makecontext2.c = $(stack-align-test-flags)
+ tests-special += $(objpfx)isomac.out
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_EGLIBC_FMTMSG))
+ tests-special += $(objpfx)tst-fmtmsg.out
+ endif
++endif
+ 
+ include ../Rules
+ 
+diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
+index e13ab1e..63efe41 100644
+--- a/stdlib/strtod_l.c
++++ b/stdlib/strtod_l.c
+@@ -17,6 +17,7 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
+ #include <xlocale.h>
+ 
+ extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
+@@ -548,6 +549,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
+   /* Used in several places.  */
+   int cnt;
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   struct __locale_data *current = loc->__locales[LC_NUMERIC];
+ 
+   if (__glibc_unlikely (group))
+@@ -586,6 +588,17 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
+   decimal_len = strlen (decimal);
+   assert (decimal_len > 0);
+ #endif
++#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
++  /* Hard-code values from the 'C' locale.  */
++  grouping = NULL;
++#ifdef USE_WIDE_CHAR
++  decimal = L'.';
++# define decimal_len 1
++#else
++  decimal = ".";
++  decimal_len = 1;
++#endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 
+   /* Prepare number representation.  */
+   exponent = 0;
+diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c
+index a469208..28fb423 100644
+--- a/stdlib/tst-strtod.c
++++ b/stdlib/tst-strtod.c
+@@ -23,6 +23,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <math.h>
++#include <gnu/option-groups.h>
+ 
+ struct ltest
+   {
+@@ -176,7 +177,9 @@ main (int argc, char ** argv)
+ 
+   status |= long_dbl ();
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   status |= locale_test ();
++#endif
+ 
+   return status ? EXIT_FAILURE : EXIT_SUCCESS;
+ }
+@@ -219,6 +222,7 @@ long_dbl (void)
+   return 0;
+ }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ /* Perform a few tests in a locale with thousands separators.  */
+ static int
+ locale_test (void)
+@@ -276,3 +280,4 @@ locale_test (void)
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+diff --git a/streams/Makefile b/streams/Makefile
+index a8a6162..ceb423f 100644
+--- a/streams/Makefile
++++ b/streams/Makefile
+@@ -18,11 +18,14 @@
+ #
+ #	Makefile for streams.
+ #
++include ../option-groups.mak
++
+ subdir	:= streams
+ 
+ include ../Makeconfig
+ 
+ headers		= stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
+-routines	= isastream getmsg getpmsg putmsg putpmsg fattach fdetach
++routines-$(OPTION_EGLIBC_STREAMS) \
++	+= isastream getmsg getpmsg putmsg putpmsg fattach fdetach
+ 
+ include ../Rules
+diff --git a/string/Makefile b/string/Makefile
+index 8424a61..5988834 100644
+--- a/string/Makefile
++++ b/string/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for string portion of library.
+ #
++include ../option-groups.mak
++
+ subdir	:= string
+ 
+ include ../Makeconfig
+@@ -39,10 +41,12 @@ routines	:= strcat strchr strcmp strcoll strcpy strcspn		\
+ 		   $(addprefix argz-,append count create ctsep next	\
+ 				     delete extract insert stringify	\
+ 				     addsep replace)			\
+-		   envz basename					\
++		   basename						\
+ 		   strcoll_l strxfrm_l string-inlines memrchr		\
+ 		   xpg-strerror strerror_l
+ 
++routines-$(OPTION_EGLIBC_ENVZ) += envz
++
+ strop-tests	:= memchr memcmp memcpy memmove mempcpy memset memccpy	\
+ 		   stpcpy stpncpy strcat strchr strcmp strcpy strcspn	\
+ 		   strlen strncmp strncpy strpbrk strrchr strspn memmem	\
+@@ -51,10 +55,12 @@ strop-tests	:= memchr memcmp memcpy memmove mempcpy memset memccpy	\
+ tests		:= tester inl-tester noinl-tester testcopy test-ffs	\
+ 		   tst-strlen stratcliff tst-svc tst-inlcall		\
+ 		   bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap	\
+-		   tst-strtok tst-strxfrm bug-strcoll1 tst-strfry	\
++		   tst-strtok tst-strfry	\
+ 		   bug-strtok1 $(addprefix test-,$(strop-tests))	\
+-		   bug-envz1 tst-strxfrm2 tst-endian tst-svc2		\
+-		   tst-strtok_r
++		   tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r
++tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= tst-strxfrm bug-strcoll1
+ 
+ xtests = tst-strcoll-overflow
+ 
+diff --git a/string/strcoll_l.c b/string/strcoll_l.c
+index 8f1225f..b36b18c 100644
+--- a/string/strcoll_l.c
++++ b/string/strcoll_l.c
+@@ -24,6 +24,7 @@
+ #include <stdint.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ #ifndef STRING_TYPE
+ # define STRING_TYPE char
+@@ -260,7 +261,11 @@ int
+ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ {
+   struct __locale_data *current = l->__locales[LC_COLLATE];
++#if __OPTION_EGLIBC_LOCALE_CODE
+   uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++#else
++  const uint_fast32_t nrules = 0;
++#endif
+   /* We don't assign the following values right away since it might be
+      unnecessary in case there are no rules.  */
+   const unsigned char *rulesets;
+diff --git a/string/strerror_l.c b/string/strerror_l.c
+index 2ed78b5..6584813 100644
+--- a/string/strerror_l.c
++++ b/string/strerror_l.c
+@@ -21,6 +21,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ static __thread char *last_value;
+@@ -29,10 +30,14 @@ static __thread char *last_value;
+ static const char *
+ translate (const char *str, locale_t loc)
+ {
++#if __OPTION_EGLIBC_LOCALE_CODE
+   locale_t oldloc = __uselocale (loc);
+   const char *res = _(str);
+   __uselocale (oldloc);
+   return res;
++#else
++  return str;
++#endif
+ }
+ 
+ 
+diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c
+index 8b61ea2..41fdc22 100644
+--- a/string/strxfrm_l.c
++++ b/string/strxfrm_l.c
+@@ -24,6 +24,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ #ifndef STRING_TYPE
+ # define STRING_TYPE char
+@@ -669,7 +670,11 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+ {
+   locale_data_t l_data;
+   struct __locale_data *current = l->__locales[LC_COLLATE];
++#if __OPTION_EGLIBC_LOCALE_CODE
+   l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++#else
++  l_data.nrules = 0;
++#endif
+ 
+   /* Handle byte comparison case.  */
+   if (l_data.nrules == 0)
+diff --git a/string/test-strcmp.c b/string/test-strcmp.c
+index dc4ba6f..a978656 100644
+--- a/string/test-strcmp.c
++++ b/string/test-strcmp.c
+@@ -329,34 +329,6 @@ check (void)
+ 		FOR_EACH_IMPL (impl, 0)
+ 		check_result (impl, s1 + i1, s2 + i2, exp_result);
+       }
+-
+-  /* Test cases where there are multiple zero bytes after the first.  */
+-
+-  for (size_t i = 0; i < 16 + 1; i++)
+-    {
+-      s1[i] = 0x00;
+-      s2[i] = 0x00;
+-    }
+-
+-  for (size_t i = 0; i < 16; i++)
+-    {
+-      int exp_result;
+-
+-      for (int val = 0x01; val < 0x100; val++)
+-	{
+-	  for (size_t j = 0; j < i; j++)
+-	    {
+-	      s1[j] = val;
+-	      s2[j] = val;
+-	    }
+-
+-	  s2[i] = val;
+-
+-	  exp_result = SIMPLE_STRCMP (s1, s2);
+-	  FOR_EACH_IMPL (impl, 0)
+-	    check_result (impl, s1, s2, exp_result);
+-	}
+-    }
+ }
+ 
+ 
+diff --git a/string/tst-strxfrm.c b/string/tst-strxfrm.c
+index f48cfc0..c3a51f9 100644
+--- a/string/tst-strxfrm.c
++++ b/string/tst-strxfrm.c
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ char const string[] = "";
+@@ -64,8 +65,10 @@ do_test (void)
+   int result = 0;
+ 
+   result |= test ("C");
++#if __OPTION_EGLIBC_LOCALE_CODE
+   result |= test ("en_US.ISO-8859-1");
+   result |= test ("de_DE.UTF-8");
++#endif
+ 
+   return result;
+ }
+diff --git a/string/tst-strxfrm2.c b/string/tst-strxfrm2.c
+index d5a1115..19c7f30 100644
+--- a/string/tst-strxfrm2.c
++++ b/string/tst-strxfrm2.c
+@@ -1,6 +1,7 @@
+ #include <locale.h>
+ #include <stdio.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ do_test (void)
+@@ -38,6 +39,7 @@ do_test (void)
+       res = 1;
+     }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
+     {
+       puts ("setlocale failed");
+@@ -75,6 +77,7 @@ do_test (void)
+ 	  res = 1;
+ 	}
+     }
++#endif
+ 
+   return res;
+ }
+diff --git a/sunrpc/Makefile b/sunrpc/Makefile
+index 60caa0a..5bc70ab 100644
+--- a/sunrpc/Makefile
++++ b/sunrpc/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for sunrpc portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= sunrpc
+ 
+ include ../Makeconfig
+@@ -55,7 +57,6 @@ headers-in-tirpc = $(addprefix rpc/,auth.h auth_unix.h clnt.h pmap_clnt.h \
+ headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \
+ 		       $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h
+ headers = rpc/netdb.h
+-install-others = $(inst_sysconfdir)/rpc
+ generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \
+ 	     $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen
+ generated-dirs += rpcsvc
+@@ -65,20 +66,28 @@ headers += $(headers-in-tirpc) $(headers-not-in-tirpc)
+ endif
+ 
+ ifeq ($(build-shared),yes)
+-need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
++need-export-routines-$(OPTION_EGLIBC_SUNRPC) := \
++			auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
+ 			clnt_udp get_myaddr key_call netname pm_getport \
+-			rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \
++			rpc_thread svc svc_tcp svc_udp xdr_array xdr \
+ 			xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \
+ 			svc_run
++need-export-routines-y += xcrypt
++need-export-routines := $(need-export-routines-y)
+ 
+-routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
++routines-$(OPTION_EGLIBC_SUNRPC) := \
++	    auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
+ 	    rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \
+ 	    pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \
+ 	    svc_simple xdr_float xdr_rec publickey authdes_prot \
+-	    des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \
++	    key_prot openchild rtime svcauth_des \
+ 	    getrpcent getrpcbyname getrpcbynumber \
+ 	    getrpcent_r getrpcbyname_r getrpcbynumber_r \
+-	    clnt_unix svc_unix create_xid $(need-export-routines)
++	    clnt_unix svc_unix create_xid
++
++# xdecrypt is also used by nss/nss_files/files-key.c.
++routines-y += des_crypt des_impl des_soft $(need-export-routines)
++
+ ifneq ($(link-obsolete-rpc),yes)
+ # We only add the RPC for compatibility to libc.so.
+ shared-only-routines = $(routines)
+@@ -87,25 +96,28 @@ endif
+ 
+ # We do not build rpcinfo anymore.  It is not needed for a bootstrap
+ # and not wanted on complete systems.
+-# others := rpcinfo
+-# install-sbin := rpcinfo
+-install-bin := rpcgen
++# others-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
++# install-sbin-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
++install-bin-$(OPTION_EGLIBC_SUNRPC) += rpcgen
+ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
+ 	      rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
+ 	      rpc_tblout.o rpc_sample.o
+-extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
+-others += rpcgen
++extra-objs-$(OPTION_EGLIBC_SUNRPC) = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
++others-$(OPTION_EGLIBC_SUNRPC) += rpcgen
++
++install-others-$(OPTION_EGLIBC_SUNRPC) += $(inst_sysconfdir)/rpc
+ 
+-tests = tst-xdrmem tst-xdrmem2 test-rpcent
+-xtests := tst-getmyaddr
++tests-$(OPTION_EGLIBC_SUNRPC) = tst-xdrmem tst-xdrmem2 test-rpcent
++xtests-$(OPTION_EGLIBC_SUNRPC) := tst-getmyaddr
+ 
+ ifeq ($(have-thread-library),yes)
+-xtests += thrsvc
++xtests-$(OPTION_EGLIBC_SUNRPC) += thrsvc
+ endif
+ 
+ headers += $(rpcsvc:%.x=rpcsvc/%.h)
+-extra-libs := librpcsvc
+-extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass.
++extra-libs-$(OPTION_EGLIBC_SUNRPC) += librpcsvc
++# Make it in `others' pass, not `lib' pass.
++extra-libs-others-y += $(extra-libs-y)
+ librpcsvc-routines = $(rpcsvc:%.x=x%)
+ librpcsvc-inhibit-o = .os # Build no shared rpcsvc library.
+ omit-deps = $(librpcsvc-routines)
+diff --git a/sysdeps/arm/Makefile b/sysdeps/arm/Makefile
+index 17c129b..543791a 100644
+--- a/sysdeps/arm/Makefile
++++ b/sysdeps/arm/Makefile
+@@ -37,10 +37,13 @@ ifeq ($(subdir),csu)
+ # get offset to rtld_global._dl_hwcap
+ gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym
+ aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math
+-aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \
++aeabi_routines = aeabi_assert aeabi_errno_addr \
+ 		 aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \
+ 		 aeabi_memmove aeabi_memset \
+ 		 aeabi_read_tp libc-aeabi_read_tp
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++aeabi_routines += aeabi_localeconv
++endif
+ 
+ sysdep_routines += $(aeabi_constants) $(aeabi_routines)
+ static-only-routines += $(aeabi_constants) aeabi_read_tp
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index 7a0fe8d..a3e2c0a 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -435,6 +435,12 @@ extern struct rtld_global _rtld_global __rtld_global_attribute__;
+ # undef __rtld_global_attribute__
+ #endif
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
++# define GLRO_dl_debug_mask GLRO(dl_debug_mask)
++#else
++# define GLRO_dl_debug_mask 0
++#endif
++
+ #ifndef SHARED
+ # define GLRO(name) _##name
+ #else
+@@ -447,8 +453,10 @@ struct rtld_global_ro
+ {
+ #endif
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
+   /* If nonzero the appropriate debug information is printed.  */
+   EXTERN int _dl_debug_mask;
++#endif
+ #define DL_DEBUG_LIBS	    (1 << 0)
+ #define DL_DEBUG_IMPCALLS   (1 << 1)
+ #define DL_DEBUG_BINDINGS   (1 << 2)
+diff --git a/sysdeps/gnu/Makefile b/sysdeps/gnu/Makefile
+index ea68037..3175cc3 100644
+--- a/sysdeps/gnu/Makefile
++++ b/sysdeps/gnu/Makefile
+@@ -59,7 +59,8 @@ $(foreach o,$(object-suffixes) $(object-suffixes:=.d),\
+ endif
+ 
+ ifeq ($(subdir),login)
+-sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
++sysdep_routines-$(OPTION_EGLIBC_UTMPX) \
++		+= setutxent getutxent endutxent getutxid getutxline \
+ 		   pututxline utmpxname updwtmpx getutmpx getutmp
+ 
+ sysdep_headers += utmpx.h bits/utmpx.h
+diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
+index 222122d..4509357 100644
+--- a/sysdeps/ieee754/ldbl-opt/Makefile
++++ b/sysdeps/ieee754/ldbl-opt/Makefile
+@@ -11,19 +11,18 @@ libm-routines += s_nexttowardfd
+ routines += math_ldbl_opt nldbl-compat
+ 
+ extra-libs += libnldbl
+-libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
++libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \
+ 		 obstack_printf obstack_vprintf printf scanf snprintf \
+-		 sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \
+-		 vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \
+-		 vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \
+-		 wprintf wscanf printf_fp printf_size \
+-		 fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \
+-		 swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \
+-		 vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \
+-		 wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \
++		 sprintf sscanf vasprintf vdprintf vfprintf \
++		 vfscanf vprintf vscanf vsnprintf \
++		 vsprintf vsscanf \
++		 printf_fp printf_size \
++		 fprintf_chk printf_chk snprintf_chk sprintf_chk \
++		 vfprintf_chk vprintf_chk \
++		 vsnprintf_chk vsprintf_chk \
++		 asprintf_chk vasprintf_chk dprintf_chk \
+ 		 vdprintf_chk obstack_printf_chk obstack_vprintf_chk \
+ 		 syslog syslog_chk vsyslog vsyslog_chk \
+-		 strfmon strfmon_l \
+ 		 strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
+ 		 qecvt qfcvt qgcvt qecvt_r qfcvt_r \
+ 		 isinf isnan finite signbit scalb log2 lgamma_r ceil \
+@@ -38,9 +37,15 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
+ 		 casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \
+ 		 cabs carg cimag creal clog10 \
+ 		 isoc99_scanf isoc99_fscanf isoc99_sscanf \
+-		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
++		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf
++libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l
++libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \
++		 swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \
++		 vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \
++		 vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \
+ 		 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
+ 		 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
++libnldbl-calls += $(libnldbl-calls-y)
+ libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
+ libnldbl-inhibit-o = $(object-suffixes)
+ libnldbl-static-only-routines = $(libnldbl-routines)
+diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
+index 0198886..55501cd 100644
+--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
++++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
+@@ -26,6 +26,7 @@
+ #include <locale/localeinfo.h>
+ #include <sys/syslog.h>
+ #include <bits/libc-lock.h>
++#include <gnu/option-groups.h>
+ 
+ #include "nldbl-compat.h"
+ 
+@@ -33,20 +34,14 @@ libc_hidden_proto (__nldbl_vfprintf)
+ libc_hidden_proto (__nldbl_vsscanf)
+ libc_hidden_proto (__nldbl_vsprintf)
+ libc_hidden_proto (__nldbl_vfscanf)
+-libc_hidden_proto (__nldbl_vfwscanf)
+ libc_hidden_proto (__nldbl_vdprintf)
+-libc_hidden_proto (__nldbl_vswscanf)
+-libc_hidden_proto (__nldbl_vfwprintf)
+-libc_hidden_proto (__nldbl_vswprintf)
+ libc_hidden_proto (__nldbl_vsnprintf)
+ libc_hidden_proto (__nldbl_vasprintf)
+ libc_hidden_proto (__nldbl_obstack_vprintf)
+-libc_hidden_proto (__nldbl___vfwprintf_chk)
+ libc_hidden_proto (__nldbl___vsnprintf_chk)
+ libc_hidden_proto (__nldbl___vfprintf_chk)
+ libc_hidden_proto (__nldbl___vsyslog_chk)
+ libc_hidden_proto (__nldbl___vsprintf_chk)
+-libc_hidden_proto (__nldbl___vswprintf_chk)
+ libc_hidden_proto (__nldbl___vasprintf_chk)
+ libc_hidden_proto (__nldbl___vdprintf_chk)
+ libc_hidden_proto (__nldbl___obstack_vprintf_chk)
+@@ -54,8 +49,17 @@ libc_hidden_proto (__nldbl___vstrfmon)
+ libc_hidden_proto (__nldbl___vstrfmon_l)
+ libc_hidden_proto (__nldbl___isoc99_vsscanf)
+ libc_hidden_proto (__nldbl___isoc99_vfscanf)
++
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++libc_hidden_proto (__nldbl_vfwscanf)
++libc_hidden_proto (__nldbl_vswscanf)
++libc_hidden_proto (__nldbl_vfwprintf)
++libc_hidden_proto (__nldbl_vswprintf)
++libc_hidden_proto (__nldbl___vfwprintf_chk)
++libc_hidden_proto (__nldbl___vswprintf_chk)
+ libc_hidden_proto (__nldbl___isoc99_vswscanf)
+ libc_hidden_proto (__nldbl___isoc99_vfwscanf)
++#endif
+ 
+ static void
+ __nldbl_cleanup (void *arg)
+@@ -117,6 +121,7 @@ __nldbl_fprintf (FILE *stream, const char *fmt, ...)
+ }
+ weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
+@@ -130,6 +135,7 @@ __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -226,6 +232,7 @@ __nldbl_snprintf (char *s, size_t maxlen, const char *fmt, ...)
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
+@@ -239,6 +246,7 @@ __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section weak_function
+@@ -264,6 +272,7 @@ __nldbl_vdprintf (int d, const char *fmt, va_list arg)
+ }
+ libc_hidden_def (__nldbl_vdprintf)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -275,6 +284,7 @@ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
+   return res;
+ }
+ libc_hidden_def (__nldbl_vfwprintf)
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -297,6 +307,7 @@ __nldbl_vsnprintf (char *string, size_t maxlen, const char *fmt,
+ libc_hidden_def (__nldbl_vsnprintf)
+ weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
+@@ -330,6 +341,7 @@ __nldbl_wprintf (const wchar_t *fmt, ...)
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -419,6 +431,7 @@ __nldbl_scanf (const char *fmt, ...)
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -491,6 +504,7 @@ __nldbl_wscanf (const wchar_t *fmt, ...)
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -506,6 +520,7 @@ __nldbl___fprintf_chk (FILE *stream, int flag, const char *fmt, ...)
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
+@@ -519,6 +534,7 @@ __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -563,6 +579,7 @@ __nldbl___sprintf_chk (char *s, int flag, size_t slen, const char *fmt, ...)
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
+@@ -577,6 +594,7 @@ __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -590,6 +608,7 @@ __nldbl___vfprintf_chk (FILE *s, int flag, const char *fmt, va_list ap)
+ }
+ libc_hidden_def (__nldbl___vfprintf_chk)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
+@@ -601,6 +620,7 @@ __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
+   return res;
+ }
+ libc_hidden_def (__nldbl___vfwprintf_chk)
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -635,6 +655,7 @@ __nldbl___vsprintf_chk (char *string, int flag, size_t slen, const char *fmt,
+ }
+ libc_hidden_def (__nldbl___vsprintf_chk)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
+@@ -668,6 +689,7 @@ __nldbl___wprintf_chk (int flag, const wchar_t *fmt, ...)
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -775,6 +797,7 @@ __nldbl___printf_fp (FILE *fp, const struct printf_info *info,
+   return ___printf_fp (fp, &info_no_ldbl, args);
+ }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ ssize_t
+ attribute_compat_text_section
+ __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...)
+@@ -829,6 +852,7 @@ __nldbl___vstrfmon_l (char *s, size_t maxsize, __locale_t loc,
+   return res;
+ }
+ libc_hidden_def (__nldbl___vstrfmon_l)
++#endif
+ 
+ void
+ attribute_compat_text_section
+@@ -941,6 +965,7 @@ __nldbl___isoc99_scanf (const char *fmt, ...)
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -1014,6 +1039,7 @@ __nldbl___isoc99_wscanf (const wchar_t *fmt, ...)
+ 
+   return done;
+ }
++#endif
+ 
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+ compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0);
+@@ -1057,6 +1083,7 @@ compat_symbol (libc, __nldbl_printf_size, printf_size, GLIBC_2_1);
+ compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1);
+ #endif
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2)
++# if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2);
+@@ -1069,6 +1096,7 @@ compat_symbol (libc, __nldbl_vfwscanf, vfwscanf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2);
++# endif
+ #endif
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
+ compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3);
+diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
+index 0d2c8af..f4cea50 100644
+--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
++++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
+@@ -30,6 +30,7 @@
+ #include <math.h>
+ #include <monetary.h>
+ #include <sys/syslog.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ /* Declare the __nldbl_NAME function the wrappers call that's in libc.so.  */
+@@ -37,19 +38,15 @@
+ 
+ NLDBL_DECL (_IO_vfscanf);
+ NLDBL_DECL (vfscanf);
+-NLDBL_DECL (vfwscanf);
+ NLDBL_DECL (obstack_vprintf);
+ NLDBL_DECL (vasprintf);
+ NLDBL_DECL (dprintf);
+ NLDBL_DECL (vdprintf);
+ NLDBL_DECL (fprintf);
+ NLDBL_DECL (vfprintf);
+-NLDBL_DECL (vfwprintf);
+ NLDBL_DECL (vsnprintf);
+ NLDBL_DECL (vsprintf);
+ NLDBL_DECL (vsscanf);
+-NLDBL_DECL (vswprintf);
+-NLDBL_DECL (vswscanf);
+ NLDBL_DECL (__asprintf);
+ NLDBL_DECL (asprintf);
+ NLDBL_DECL (__printf_fp);
+@@ -66,12 +63,18 @@ NLDBL_DECL (__isoc99_sscanf);
+ NLDBL_DECL (__isoc99_vscanf);
+ NLDBL_DECL (__isoc99_vfscanf);
+ NLDBL_DECL (__isoc99_vsscanf);
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++NLDBL_DECL (vfwscanf);
++NLDBL_DECL (vfwprintf);
++NLDBL_DECL (vswprintf);
++NLDBL_DECL (vswscanf);
+ NLDBL_DECL (__isoc99_wscanf);
+ NLDBL_DECL (__isoc99_fwscanf);
+ NLDBL_DECL (__isoc99_swscanf);
+ NLDBL_DECL (__isoc99_vwscanf);
+ NLDBL_DECL (__isoc99_vfwscanf);
+ NLDBL_DECL (__isoc99_vswscanf);
++#endif
+ 
+ /* This one does not exist in the normal interface, only
+    __nldbl___vstrfmon really exists.  */
+@@ -82,22 +85,23 @@ extern ssize_t __nldbl___vstrfmon (char *, size_t, const char *, va_list)
+    since we don't compile with _FORTIFY_SOURCE.  */
+ extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
+ 				   const char *__restrict, _G_va_list);
+-extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
+-				    const wchar_t *__restrict, __gnuc_va_list);
+ extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
+ 				   const char *__restrict, _G_va_list) __THROW;
+ extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
+ 				    const char *__restrict, _G_va_list)
+   __THROW;
+-extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
+-				    const wchar_t *__restrict, __gnuc_va_list)
+-  __THROW;
+ extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list)
+   __THROW;
+ extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list);
+ extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *,
+ 					  _G_va_list) __THROW;
+ extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
+-
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
++				    const wchar_t *__restrict, __gnuc_va_list);
++extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
++				    const wchar_t *__restrict, __gnuc_va_list)
++  __THROW;
++#endif
+ 
+ #endif /* __NLDBL_COMPAT_H */
+diff --git a/sysdeps/nptl/Makefile b/sysdeps/nptl/Makefile
+index e9339a3..782009b 100644
+--- a/sysdeps/nptl/Makefile
++++ b/sysdeps/nptl/Makefile
+@@ -18,6 +18,9 @@
+ 
+ ifeq ($(subdir),nptl)
+ libpthread-sysdep_routines += errno-loc
++ifeq ($(OPTION_EGLIBC_BIG_MACROS),n)
++sysdep_routines += small-macros-fns
++endif
+ endif
+ 
+ ifeq ($(subdir),rt)
+diff --git a/sysdeps/nptl/bits/libc-lock.h b/sysdeps/nptl/bits/libc-lock.h
+index 5599cf1..b839378 100644
+--- a/sysdeps/nptl/bits/libc-lock.h
++++ b/sysdeps/nptl/bits/libc-lock.h
+@@ -24,6 +24,14 @@
+ #include <stddef.h>
+ 
+ 
++#ifdef _LIBC
++# include <lowlevellock.h>
++# include <tls.h>
++# include <pthread-functions.h>
++# include <errno.h> /* For EBUSY.  */
++# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS.  */
++#endif
++
+ /* Mutex type.  */
+ #if defined _LIBC || defined _IO_MTSAFE_IO
+ # if (!IS_IN (libc) && !IS_IN (libpthread)) || !defined _LIBC
+@@ -87,6 +95,15 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+ 
+ /* Lock the recursive named lock variable.  */
+ #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_lock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
++
+ # define __libc_lock_lock_recursive(NAME) \
+   do {									      \
+     void *self = THREAD_SELF;						      \
+@@ -97,6 +114,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+       }									      \
+     ++(NAME).cnt;							      \
+   } while (0)
++# else
++# define __libc_lock_lock_recursive(NAME)				\
++  __libc_lock_lock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_lock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+@@ -104,6 +125,14 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+ 
+ /* Try to lock the recursive named lock variable.  */
+ #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_trylock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_trylock_recursive(NAME) \
+   ({									      \
+     int result = 0;							      \
+@@ -122,6 +151,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+       ++(NAME).cnt;							      \
+     result;								      \
+   })
++# else
++# define __libc_lock_trylock_recursive(NAME) \
++  __libc_lock_trylock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_trylock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
+@@ -129,6 +162,14 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+ 
+ /* Unlock the recursive named lock variable.  */
+ #if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread))
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_unlock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ /* We do no error checking here.  */
+ # define __libc_lock_unlock_recursive(NAME) \
+   do {									      \
+@@ -138,6 +179,10 @@ typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+ 	lll_unlock ((NAME).lock, LLL_PRIVATE);				      \
+       }									      \
+   } while (0)
++# else
++# define __libc_lock_unlock_recursive(NAME) \
++  __libc_lock_unlock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_unlock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+diff --git a/sysdeps/nptl/bits/libc-lockP.h b/sysdeps/nptl/bits/libc-lockP.h
+index f55f621..da98869 100644
+--- a/sysdeps/nptl/bits/libc-lockP.h
++++ b/sysdeps/nptl/bits/libc-lockP.h
+@@ -33,6 +33,8 @@
+ #include <lowlevellock.h>
+ #include <tls.h>
+ #include <pthread-functions.h>
++#include <errno.h> /* For EBUSY.  */
++#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS.  */
+ 
+ #if IS_IN (libpthread)
+ /* This gets us the declarations of the __pthread_* internal names,
+@@ -171,10 +173,22 @@ typedef pthread_key_t __libc_key_t;
+ 
+ /* Lock the named lock variable.  */
+ #if IS_IN (libc) || IS_IN (libpthread)
+-# ifndef __libc_lock_lock
+-#  define __libc_lock_lock(NAME) \
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_lock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_lock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
++#  ifndef __libc_lock_lock
++#   define __libc_lock_lock(NAME) \
+   ({ lll_lock (NAME, LLL_PRIVATE); 0; })
+-# endif
++#  endif
++# else
++#  define __libc_lock_lock(NAME)               \
++  __libc_lock_lock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # undef __libc_lock_lock
+ # define __libc_lock_lock(NAME) \
+@@ -187,10 +201,22 @@ typedef pthread_key_t __libc_key_t;
+ 
+ /* Try to lock the named lock variable.  */
+ #if IS_IN (libc) || IS_IN (libpthread)
+-# ifndef __libc_lock_trylock
+-#  define __libc_lock_trylock(NAME) \
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern int __libc_lock_trylock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_trylock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
++#  ifndef __libc_lock_trylock
++#   define __libc_lock_trylock(NAME) \
+   lll_trylock (NAME)
+-# endif
++#  endif
++# else
++# define __libc_lock_trylock(NAME) \
++  __libc_lock_trylock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # undef __libc_lock_trylock
+ # define __libc_lock_trylock(NAME) \
+@@ -206,8 +232,20 @@ typedef pthread_key_t __libc_key_t;
+ 
+ /* Unlock the named lock variable.  */
+ #if IS_IN (libc) || IS_IN (libpthread)
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_unlock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_unlock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_unlock(NAME) \
+   lll_unlock (NAME, LLL_PRIVATE)
++# else
++# define __libc_lock_unlock(NAME) \
++  __libc_lock_unlock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_unlock(NAME) \
+   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
+diff --git a/sysdeps/nptl/small-macros-fns.c b/sysdeps/nptl/small-macros-fns.c
+new file mode 100644
+index 0000000..f751053
+--- /dev/null
++++ b/sysdeps/nptl/small-macros-fns.c
+@@ -0,0 +1,72 @@
++/* EGLIBC: function wrappers for big macros.
++   Copyright (C) 2009 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; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++
++#include <gnu/option-groups.h>
++
++/* Handle macros from ./bits/libc-lock.h.  */
++#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++
++/* Get the macros for function bodies through a back door.  */
++# undef __OPTION_EGLIBC_BIG_MACROS
++# define __OPTION_EGLIBC_BIG_MACROS 2
++# include <bits/libc-lock.h>
++
++void
++__libc_lock_lock_fn (__libc_lock_t *name)
++{
++  __libc_lock_lock (*name);
++}
++libc_hidden_def (__libc_lock_lock_fn);
++
++void
++__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  __libc_lock_lock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_lock_recursive_fn);
++
++int
++__libc_lock_trylock_fn (__libc_lock_t *name)
++{
++  return __libc_lock_trylock (*name);
++}
++libc_hidden_def (__libc_lock_trylock_fn);
++
++int
++__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  return __libc_lock_trylock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_trylock_recursive_fn);
++
++void
++__libc_lock_unlock_fn (__libc_lock_t *name)
++{
++  __libc_lock_unlock (*name);
++}
++libc_hidden_def (__libc_lock_unlock_fn);
++
++void
++__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  __libc_lock_unlock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_unlock_recursive_fn);
++
++#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/
+diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c
+index 26e4692..d0a26c8 100644
+--- a/sysdeps/unix/sysv/linux/gethostid.c
++++ b/sysdeps/unix/sysv/linux/gethostid.c
+@@ -21,6 +21,7 @@
+ #include <unistd.h>
+ #include <netdb.h>
+ #include <not-cancel.h>
++#include <gnu/option-groups.h>
+ 
+ #define HOSTIDFILE "/etc/hostid"
+ 
+@@ -89,6 +90,7 @@ gethostid (void)
+ 	return id;
+     }
+ 
++#if __OPTION_EGLIBC_INET
+   /* Getting from the file was not successful.  An intelligent guess for
+      a unique number of a host is its IP address.  Return this.  */
+   if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0')
+@@ -115,5 +117,9 @@ gethostid (void)
+   /* For the return value to be not exactly the IP address we do some
+      bit fiddling.  */
+   return (int32_t) (in.s_addr << 16 | in.s_addr >> 16);
++#else
++  /* Return an arbitrary value.  */
++  return 0;
++#endif
+ }
+ #endif
+diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
+index 53a8bbb..cb110d4 100644
+--- a/sysdeps/unix/sysv/linux/libc_fatal.c
++++ b/sysdeps/unix/sysv/linux/libc_fatal.c
+@@ -23,6 +23,7 @@
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/uio.h>
++#include <gnu/option-groups.h>
+ 
+ static bool
+ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
+@@ -40,6 +41,7 @@ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
+ static void
+ backtrace_and_maps (int do_abort, bool written, int fd)
+ {
++#if __OPTION_EGLIBC_BACKTRACE
+   if (do_abort > 1 && written)
+     {
+       void *addrs[64];
+@@ -62,6 +64,7 @@ backtrace_and_maps (int do_abort, bool written, int fd)
+           close_not_cancel_no_status (fd2);
+         }
+     }
++#endif /* __OPTION_EGLIBC_BACKTRACE */
+ }
+ #define BEFORE_ABORT		backtrace_and_maps
+ 
+diff --git a/time/Makefile b/time/Makefile
+index a411f62..2d022ca 100644
+--- a/time/Makefile
++++ b/time/Makefile
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for time routines
+ #
++include ../option-groups.mak
++
+ subdir	:= time
+ 
+ include ../Makeconfig
+@@ -30,15 +32,23 @@ routines := offtime asctime clock ctime ctime_r difftime \
+ 	    tzfile getitimer setitimer			 \
+ 	    stime dysize timegm ftime			 \
+ 	    getdate strptime strptime_l			 \
+-	    strftime wcsftime strftime_l wcsftime_l	 \
++	    strftime strftime_l				 \
+ 	    timespec_get
+-aux :=	    era alt_digit lc-time-cleanup
+ 
+-tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
+-	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR)                \
++	    := wcsftime wcsftime_l
++aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup
++
++tests	:= test_time clocktest tst-posixtz \
++	   tst-getdate tst-mktime tst-mktime2 tst-strftime \
+ 	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
+ 	   tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime
+ 
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++	        += tst-strptime tst-ftime_l
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
++	        += tst_wcsftime
++
+ include ../Rules
+ 
+ tz-cflags = -DTZDIR='"$(zonedir)"' \
+diff --git a/time/strftime_l.c b/time/strftime_l.c
+index b48ef34..bfdd618 100644
+--- a/time/strftime_l.c
++++ b/time/strftime_l.c
+@@ -35,6 +35,10 @@
+ # include "../locale/localeinfo.h"
+ #endif
+ 
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined emacs && !defined HAVE_BCOPY
+ # define HAVE_MEMCPY 1
+ #endif
+@@ -882,7 +886,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+ 	case L_('C'):
+ 	  if (modifier == L_('E'))
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+@@ -955,7 +959,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+ 
+ 	  if (modifier == L_('O') && 0 <= number_value)
+ 	    {
+-#ifdef _NL_CURRENT
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
+ 	      /* Get the locale specific alternate representation of
+ 		 the number NUMBER_VALUE.  If none exist NULL is returned.  */
+ 	      const CHAR_T *cp = nl_get_alt_digit (number_value
+@@ -1260,7 +1264,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+ 	case L_('Y'):
+ 	  if (modifier == 'E')
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+@@ -1285,7 +1289,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+ 	case L_('y'):
+ 	  if (modifier == L_('E'))
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+diff --git a/time/strptime_l.c b/time/strptime_l.c
+index 5640cce..784ccbc 100644
+--- a/time/strptime_l.c
++++ b/time/strptime_l.c
+@@ -29,6 +29,7 @@
+ 
+ #ifdef _LIBC
+ # define HAVE_LOCALTIME_R 0
++# include <gnu/option-groups.h>
+ # include "../locale/localeinfo.h"
+ #endif
+ 
+@@ -84,7 +85,7 @@ localtime_r (t, tp)
+     if (val < from || val > to)						      \
+       return NULL;							      \
+   } while (0)
+-#ifdef _NL_CURRENT
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
+ # define get_alt_number(from, to, n) \
+   ({									      \
+      __label__ do_normal;						      \
+@@ -257,8 +258,10 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
+   int cnt;
+   int cnt_longest;
+   size_t val;
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+   size_t num_eras;
+   struct era_entry *era = NULL;
++#endif
+   enum ptime_locale_status { not, loc, raw } decided_longest;
+   struct __strptime_state
+   {
+@@ -820,6 +823,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
+ 	      s.want_xday = 1;
+ 	      break;
+ 	    case 'C':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  if (s.era_cnt >= 0)
+@@ -856,10 +860,12 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
+ 
+ 		  s.decided = raw;
+ 		}
++#endif
+ 	      /* The C locale has no era information, so use the
+ 		 normal representation.  */
+ 	      goto match_century;
+  	    case 'y':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  get_number(0, 9999, 4);
+@@ -918,9 +924,10 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
+ 
+ 		  s.decided = raw;
+ 		}
+-
++#endif
+ 	      goto match_year_in_century;
+ 	    case 'Y':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  num_eras = _NL_CURRENT_WORD (LC_TIME,
+@@ -948,6 +955,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
+ 
+ 		  s.decided = raw;
+ 		}
++#endif
+ 	      get_number (0, 9999, 4);
+ 	      tm->tm_year = val - 1900;
+ 	      s.want_century = 0;
+@@ -1118,6 +1126,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
+ 	tm->tm_year = (s.century - 19) * 100;
+     }
+ 
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+   if (s.era_cnt != -1)
+     {
+       era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);
+@@ -1132,6 +1141,7 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
+ 	tm->tm_year = era->start_date[0];
+     }
+   else
++#endif
+     if (s.want_era)
+       {
+ 	/* No era found but we have seen an E modifier.  Rectify some
+diff --git a/timezone/Makefile b/timezone/Makefile
+index 886b06e..f922684 100644
+--- a/timezone/Makefile
++++ b/timezone/Makefile
+@@ -127,7 +127,7 @@ $(testdata)/XT%: testdata/XT%
+ 
+ $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
+ 	sed -e 's|/bin/bash|/bin/sh|' \
+-	    -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
++	    -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \
+ 	    -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
+ 	    -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
+ 	    -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \
+diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
+index 44a4494..db9fc24 100644
+--- a/wcsmbs/Makefile
++++ b/wcsmbs/Makefile
+@@ -18,15 +18,21 @@
+ #
+ #	Sub-makefile for wcsmbs portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= wcsmbs
+ 
+ include ../Makeconfig
+ 
+ headers	:= wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h
+ 
+-routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
++# These functions are used by printf_fp.c, even in the plain case; see
++# comments there for OPTION_EGLIBC_LOCALE_CODE.
++routines  := wmemcpy wmemset
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++	  := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
+ 	    wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
+-	    wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \
++	    wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \
+ 	    btowc wctob mbsinit \
+ 	    mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
+ 	    mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \
+@@ -38,14 +44,21 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
+ 	    wcscoll_l wcsxfrm_l \
+ 	    wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
+ 	    wcsmbsload mbsrtowcs_l \
+-	    isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
+ 	    isoc99_swscanf isoc99_vswscanf \
+ 	    mbrtoc16 c16rtomb
+ 
+-strop-tests :=  wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy
+-tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
+-	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
+-	 tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests))
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)                           \
++	+= isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf
++
++strop-tests :=  wcscmp wmemcmp wmemcmp wcslen wcschr wcsrchr wcscpy
++
++tests := tst-wchar-h
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++	+= tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++	+= tst-wcstof wcsmbs-tst1 tst-wcsnlen \
++	tst-wcpncpy tst-mbsrtowcs \
++	wcsatcliff $(addprefix test-,$(strop-tests))
+ 
+ include ../Rules
+ 
+diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
+index 6bb49bc..2ab9d07 100644
+--- a/wcsmbs/wcsmbsload.c
++++ b/wcsmbs/wcsmbsload.c
+@@ -21,6 +21,7 @@
+ #include <limits.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ #include <locale/localeinfo.h>
+ #include <wcsmbsload.h>
+@@ -143,6 +144,7 @@ __wcsmbs_getfct (const char *to, const char *from, size_t *nstepsp)
+   })
+ 
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ /* Some of the functions here must not be used while setlocale is called.  */
+ __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
+ 
+@@ -211,6 +213,17 @@ __wcsmbs_load_conv (struct __locale_data *new_category)
+ 
+   __libc_rwlock_unlock (__libc_setlocale_lock);
+ }
++#else
++void
++internal_function
++__wcsmbs_load_conv (struct __locale_data *new_category)
++{
++  /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach
++     this point: there is no way to change locales, so every locale
++     passed to get_gconv_fcts should be _nl_C_LC_CTYPE.  */
++  abort ();
++}
++#endif
+ 
+ 
+ /* Clone the current conversion function set.  */
+diff --git a/wctype/Makefile b/wctype/Makefile
+index c56f07c..4e8af43 100644
+--- a/wctype/Makefile
++++ b/wctype/Makefile
+@@ -18,14 +18,20 @@
+ #
+ #	Sub-makefile for wctype portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= wctype
+ 
+ include ../Makeconfig
+ 
+ headers		:= wctype.h
+-routines	:= wcfuncs wctype iswctype wctrans towctrans \
+-		   wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l
+-
+-tests	:= test_wctype test_wcfuncs bug-wctypeh
++routines 	:= wctrans towctrans towctrans_l
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++		:= wcfuncs wctype iswctype \
++		   wcfuncs_l wctype_l iswctype_l wctrans_l
++
++tests	:=
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++     += test_wctype test_wcfuncs bug-wctypeh
+ 
+ include ../Rules
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch b/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch
new file mode 100644
index 0000000..c359cce
--- /dev/null
+++ b/recipes-core/glibc/glibc/0025-eglibc-Install-PIC-archives.patch
@@ -0,0 +1,123 @@
+From 5773417fa91a18cd39fb35c9907d72af0ed9ea33 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 01:57:01 +0000
+Subject: [PATCH 25/27] eglibc: Install PIC archives
+
+Forward port from eglibc
+
+2008-02-07  Joseph Myers  <joseph@codesourcery.com>
+
+        * Makerules (install-extras, install-map): New variables.
+        (installed-libcs): Add libc_pic.a.
+        (install-lib): Include _pic.a files for versioned shared
+        libraries.
+        (install-map-nosubdir, install-extras-nosubdir): Add rules for
+        installing extra files.
+        (install-no-libc.a-nosubdir): Depend on install-map-nosubdir and
+        install-extras-nosubdir.
+
+2008-04-01  Maxim Kuvyrkov  <maxim@codesourcery.com>
+
+        * Makerules (install-lib): Don't install libpthread_pic.a.
+        (install-map): Don't install libpthread_pic.map.
+
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ Makerules | 42 ++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/Makerules b/Makerules
+index 1dd41aa..41778e1 100644
+--- a/Makerules
++++ b/Makerules
+@@ -713,6 +713,9 @@ ifeq ($(build-shared),yes)
+ $(common-objpfx)libc.so: $(common-objpfx)libc.map
+ endif
+ common-generated += libc.so libc_pic.os
++ifndef subdir
++install-extras := soinit.o sofini.o
++endif
+ ifdef libc.so-version
+ $(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so
+ 	$(make-link)
+@@ -955,6 +958,7 @@ endif
+ 
+ install: check-install-supported
+ 
++installed-libcs := $(installed-libcs) $(inst_libdir)/libc_pic.a
+ install: $(installed-libcs)
+ $(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force)
+ 	$(make-target-directory)
+@@ -983,6 +987,22 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
+ install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
+ install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
+ 
++# Install the _pic.a files for versioned libraries, and corresponding
++# .map files.
++# libpthread_pic.a breaks mklibs, so don't install it and its map.
++install-lib := $(install-lib) $(install-lib.so-versioned:%.so=%_pic.a)
++install-lib := $(filter-out libpthread_pic.a,$(install-lib))
++# Despite having a soname libhurduser and libmachuser do not use symbol
++# versioning, so don't install the corresponding .map files.
++ifeq ($(build-shared),yes)
++install-map := $(patsubst %.so,%.map,\
++			$(foreach L,$(install-lib.so-versioned),$(notdir $L)))
++install-map := $(filter-out libhurduser.map libmachuser.map libpthread.map,$(install-map))
++ifndef subdir
++install-map := $(install-map) libc.map
++endif
++endif
++
+ # For versioned libraries, we install three files:
+ #	$(inst_libdir)/libfoo.so	-- for linking, symlink or ld script
+ #	$(inst_slibdir)/libfoo.so.NN	-- for loading by SONAME, symlink
+@@ -1225,9 +1245,22 @@ $(addprefix $(inst_includedir)/,$(headers-nonh)): $(inst_includedir)/%: \
+ endif	# headers-nonh
+ endif	# headers
+ 
++ifdef install-map
++$(addprefix $(inst_libdir)/,$(patsubst lib%.map,lib%_pic.map,$(install-map))): \
++  $(inst_libdir)/lib%_pic.map: $(common-objpfx)lib%.map $(+force)
++	$(do-install)
++endif
++
++ifdef install-extras
++$(addprefix $(inst_libdir)/libc_pic/,$(install-extras)): \
++  $(inst_libdir)/libc_pic/%.o: $(elf-objpfx)%.os $(+force)
++	$(do-install)
++endif
++
+ .PHONY: install-bin-nosubdir install-bin-script-nosubdir \
+ 	install-rootsbin-nosubdir install-sbin-nosubdir install-lib-nosubdir \
+-	install-data-nosubdir install-headers-nosubdir
++	install-data-nosubdir install-headers-nosubdir install-map-nosubdir \
++	install-extras-nosubdir
+ install-bin-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin))
+ install-bin-script-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin-script))
+ install-rootsbin-nosubdir: \
+@@ -1240,6 +1273,10 @@ install-data-nosubdir: $(addprefix $(inst_datadir)/,$(install-data))
+ install-headers-nosubdir: $(addprefix $(inst_includedir)/,$(headers))
+ install-others-nosubdir: $(install-others)
+ install-others-programs-nosubdir: $(install-others-programs)
++install-map-nosubdir: $(addprefix $(inst_libdir)/,\
++		       $(patsubst lib%.map,lib%_pic.map,$(install-map)))
++install-extras-nosubdir: $(addprefix $(inst_libdir)/libc_pic/,\
++		       $(install-extras))
+ 
+ # We need all the `-nosubdir' targets so that `install' in the parent
+ # doesn't depend on several things which each iterate over the subdirs.
+@@ -1249,7 +1286,8 @@ install-%:: install-%-nosubdir ;
+ 
+ .PHONY: install install-no-libc.a-nosubdir
+ install-no-libc.a-nosubdir: install-headers-nosubdir install-data-nosubdir \
+-			    install-lib-nosubdir install-others-nosubdir
++			    install-lib-nosubdir install-others-nosubdir \
++			    install-map-nosubdir install-extras-nosubdir
+ ifeq ($(build-programs),yes)
+ install-no-libc.a-nosubdir: install-bin-nosubdir install-bin-script-nosubdir \
+ 			    install-rootsbin-nosubdir install-sbin-nosubdir \
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch b/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch
new file mode 100644
index 0000000..6b611db
--- /dev/null
+++ b/recipes-core/glibc/glibc/0026-eglibc-dl_debug_mask-is-controlled-by-__OPTION_EGLIB.patch
@@ -0,0 +1,556 @@
+From ba069b3107f5ad200c4ab95e69cf368e2353b00a Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 18 Mar 2015 00:46:50 +0000
+Subject: [PATCH 26/27] eglibc: dl_debug_mask is controlled by
+ __OPTION_EGLIBC_RTLD_DEBUG
+
+use GLRO_dl_debug_mask
+
+Singed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+---
+ csu/libc-start.c       |  4 ++--
+ elf/dl-cache.c         |  4 ++--
+ elf/dl-close.c         |  6 +++---
+ elf/dl-conflict.c      |  2 +-
+ elf/dl-deps.c          |  6 +++---
+ elf/dl-error.c         |  2 +-
+ elf/dl-fini.c          |  4 ++--
+ elf/dl-init.c          |  4 ++--
+ elf/dl-load.c          | 16 ++++++++--------
+ elf/dl-lookup.c        | 14 +++++++-------
+ elf/dl-object.c        |  2 +-
+ elf/dl-open.c          | 10 +++++-----
+ elf/dl-reloc.c         |  2 +-
+ elf/dl-version.c       |  2 +-
+ elf/get-dynamic-info.h |  2 +-
+ elf/rtld.c             | 22 +++++++++++-----------
+ 16 files changed, 51 insertions(+), 51 deletions(-)
+
+diff --git a/csu/libc-start.c b/csu/libc-start.c
+index 0afa7c0..2151fb6 100644
+--- a/csu/libc-start.c
++++ b/csu/libc-start.c
+@@ -238,7 +238,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
+ 
+   /* Call the initializer of the program, if any.  */
+ #ifdef SHARED
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
+     GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
+ #endif
+   if (init)
+@@ -261,7 +261,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
+ #endif
+ 
+ #ifdef SHARED
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+     GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
+ #endif
+ 
+diff --git a/elf/dl-cache.c b/elf/dl-cache.c
+index 862f1d8..dab9c51 100644
+--- a/elf/dl-cache.c
++++ b/elf/dl-cache.c
+@@ -194,7 +194,7 @@ _dl_load_cache_lookup (const char *name)
+   const char *best;
+ 
+   /* Print a message if the loading of libs is traced.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+     _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);
+ 
+   if (cache == NULL)
+@@ -292,7 +292,7 @@ _dl_load_cache_lookup (const char *name)
+     }
+ 
+   /* Print our result if wanted.  */
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
+       && best != NULL)
+     _dl_debug_printf ("  trying file=%s\n", best);
+ 
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index c897247..b1b4bd5 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -125,7 +125,7 @@ _dl_close_worker (struct link_map *map, bool force)
+ 	dl_close_state = rerun;
+ 
+       /* There are still references to this object.  Do nothing more.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
+ 			  map->l_name, map->l_direct_opencount);
+ 
+@@ -269,7 +269,7 @@ _dl_close_worker (struct link_map *map, bool force)
+ 	  if (imap->l_init_called)
+ 	    {
+ 	      /* When debugging print a message first.  */
+-	      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
++	      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS,
+ 				    0))
+ 		_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+ 				  imap->l_name, nsid);
+@@ -711,7 +711,7 @@ _dl_close_worker (struct link_map *map, bool force)
+ 	  free (imap->l_reldeps);
+ 
+ 	  /* Print debugging message.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	    _dl_debug_printf ("\nfile=%s [%lu];  destroying link map\n",
+ 			      imap->l_name, imap->l_ns);
+ 
+diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
+index 47a946e..e6a3f21 100644
+--- a/elf/dl-conflict.c
++++ b/elf/dl-conflict.c
+@@ -32,7 +32,7 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
+ 		       ElfW(Rela) *conflictend)
+ {
+ #if ! ELF_MACHINE_NO_RELA
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
+     _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
+ 
+   {
+diff --git a/elf/dl-deps.c b/elf/dl-deps.c
+index eee146a..1a4b004 100644
+--- a/elf/dl-deps.c
++++ b/elf/dl-deps.c
+@@ -127,7 +127,7 @@ empty dynamic string token substitution"));				      \
+ 	    else							      \
+ 	      {								      \
+ 		/* This is for DT_AUXILIARY.  */			      \
+-		if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))   \
++		if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))   \
+ 		  _dl_debug_printf (N_("\
+ cannot load auxiliary `%s' because of empty dynamic string token "	      \
+ 					    "substitution\n"), __str);	      \
+@@ -303,7 +303,7 @@ _dl_map_object_deps (struct link_map *map,
+ 		args.name = name;
+ 
+ 		/* Say that we are about to load an auxiliary library.  */
+-		if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
++		if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS,
+ 				      0))
+ 		  _dl_debug_printf ("load auxiliary object=%s"
+ 				    " requested by file=%s\n",
+@@ -520,7 +520,7 @@ _dl_map_object_deps (struct link_map *map,
+       runp->map->l_reserved = 0;
+     }
+ 
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0
+       && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
+     {
+       /* If we are to compute conflicts, we have to build local scope
+diff --git a/elf/dl-error.c b/elf/dl-error.c
+index 0fc3fd8..ea82f4d 100644
+--- a/elf/dl-error.c
++++ b/elf/dl-error.c
+@@ -139,7 +139,7 @@ internal_function
+ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
+ 		   const char *errstring)
+ {
+-  if (__builtin_expect (GLRO(dl_debug_mask)
++  if (__builtin_expect (GLRO_dl_debug_mask
+ 			& ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
+     _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
+ 		      errstring, receiver ? "continued" : "fatal");
+diff --git a/elf/dl-fini.c b/elf/dl-fini.c
+index 6cfe651..f59f7fe 100644
+--- a/elf/dl-fini.c
++++ b/elf/dl-fini.c
+@@ -234,7 +234,7 @@ _dl_fini (void)
+ 		  || l->l_info[DT_FINI] != NULL)
+ 		{
+ 		  /* When debugging print a message first.  */
+-		  if (__builtin_expect (GLRO(dl_debug_mask)
++		  if (__builtin_expect (GLRO_dl_debug_mask
+ 					& DL_DEBUG_IMPCALLS, 0))
+ 		    _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+ 				      DSO_FILENAME (l->l_name),
+@@ -286,7 +286,7 @@ _dl_fini (void)
+       goto again;
+     }
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
+     _dl_debug_printf ("\nruntime linker statistics:\n"
+ 		      "           final number of relocations: %lu\n"
+ 		      "final number of relocations from cache: %lu\n",
+diff --git a/elf/dl-init.c b/elf/dl-init.c
+index 2f85731..e46e8b6 100644
+--- a/elf/dl-init.c
++++ b/elf/dl-init.c
+@@ -46,7 +46,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
+     return;
+ 
+   /* Print a debug message if wanted.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+     _dl_debug_printf ("\ncalling init: %s\n\n",
+ 		      DSO_FILENAME (l->l_name));
+ 
+@@ -96,7 +96,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
+       ElfW(Addr) *addrs;
+       unsigned int cnt;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+ 	_dl_debug_printf ("\ncalling preinit: %s\n\n",
+ 			  DSO_FILENAME (main_map->l_name));
+ 
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index f664f50..8c28744 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -943,7 +943,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
+     }
+ 
+   /* Print debugging message.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("file=%s [%lu];  generating link map\n", name, nsid);
+ 
+   /* This is the ELF header.  We read it in `open_verify'.  */
+@@ -1347,7 +1347,7 @@ cannot enable executable stack as shared object requires");
+ 
+   l->l_entry += l->l_addr;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("\
+   dynamic: 0x%0*lx  base: 0x%0*lx   size: 0x%0*Zx\n\
+     entry: 0x%0*lx  phdr: 0x%0*lx  phnum:   %*u\n\n",
+@@ -1789,7 +1789,7 @@ open_path (const char *name, size_t namelen, int mode,
+ 
+       /* If we are debugging the search for libraries print the path
+ 	 now if it hasn't happened now.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)
+ 	  && current_what != this_dir->what)
+ 	{
+ 	  current_what = this_dir->what;
+@@ -1810,7 +1810,7 @@ open_path (const char *name, size_t namelen, int mode,
+ 	     - buf);
+ 
+ 	  /* Print name we try if this is wanted.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	    _dl_debug_printf ("  trying file=%s\n", buf);
+ 
+ 	  fd = open_verify (buf, fbp, loader, whatcode, mode,
+@@ -1955,7 +1955,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+     }
+ 
+   /* Display information if we are debugging.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)
+       && loader != NULL)
+     _dl_debug_printf ((mode & __RTLD_CALLMAP) == 0
+ 		      ? "\nfile=%s [%lu];  needed by %s [%lu]\n"
+@@ -1997,7 +1997,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+ 
+       size_t namelen = strlen (name) + 1;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
+ 
+       fd = -1;
+@@ -2119,7 +2119,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+ #endif
+ 
+       /* Add another newline when we are tracing the library loading.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("\n");
+     }
+   else
+@@ -2152,7 +2152,7 @@ _dl_map_object (struct link_map *loader, const char *name,
+   if (__glibc_unlikely (fd == -1))
+     {
+       if (trace_mode
+-	  && __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0))
++	  && __glibc_likely ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) == 0))
+ 	{
+ 	  /* We haven't found an appropriate library.  But since we
+ 	     are only interested in the list of libraries this isn't
+diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
+index 11cb44b..588c3e4 100644
+--- a/elf/dl-lookup.c
++++ b/elf/dl-lookup.c
+@@ -302,7 +302,7 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
+ 	 hash table.  */
+       if (__glibc_unlikely (tab->size))
+ 	{
+-	  assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
++	  assert (GLRO_dl_debug_mask & DL_DEBUG_PRELINK);
+ 	  goto success;
+ 	}
+ #endif
+@@ -378,7 +378,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
+ 	continue;
+ 
+       /* Print some debugging info if wanted.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS))
+ 	_dl_debug_printf ("symbol=%s;  lookup in file=%s [%lu]\n",
+ 			  undef_name, DSO_FILENAME (map->l_name),
+ 			  map->l_ns);
+@@ -755,7 +755,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
+ 	}
+ 
+       /* Display information if we are debugging.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("\
+ \nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
+ 			  DSO_FILENAME (map->l_name),
+@@ -859,7 +859,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
+     {
+       if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
+ 	  && skip_map == NULL
+-	  && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
++	  && !(GLRO_dl_debug_mask & DL_DEBUG_UNUSED))
+ 	{
+ 	  /* We could find no value for a strong reference.  */
+ 	  const char *reference_name = undef_map ? undef_map->l_name : "";
+@@ -935,7 +935,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
+   if (__glibc_unlikely (current_value.m->l_used == 0))
+     current_value.m->l_used = 1;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask)
++  if (__glibc_unlikely (GLRO_dl_debug_mask
+ 			& (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK)))
+     _dl_debug_bindings (undef_name, undef_map, ref,
+ 			&current_value, version, type_class, protected);
+@@ -1000,7 +1000,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
+ {
+   const char *reference_name = undef_map->l_name;
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
++  if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS)
+     {
+       _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
+ 			DSO_FILENAME (reference_name),
+@@ -1014,7 +1014,7 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
+ 	_dl_debug_printf_c ("\n");
+     }
+ #ifdef SHARED
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++  if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+     {
+       int conflict = 0;
+       struct sym_val val = { NULL, NULL };
+diff --git a/elf/dl-object.c b/elf/dl-object.c
+index 1d58bbc..938a257 100644
+--- a/elf/dl-object.c
++++ b/elf/dl-object.c
+@@ -98,7 +98,7 @@ _dl_new_object (char *realname, const char *libname, int type,
+   new->l_type = type;
+   /* If we set the bit now since we know it is never used we avoid
+      dirtying the cache line later.  */
+-  if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0)
++  if ((GLRO_dl_debug_mask & DL_DEBUG_UNUSED) == 0)
+     new->l_used = 1;
+   new->l_loader = loader;
+ #if NO_TLS_OFFSET != 0
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index 2db1c02..1288604 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -147,7 +147,7 @@ add_to_global (struct link_map *new)
+ 	  ns->_ns_main_searchlist->r_list[new_nlist++] = map;
+ 
+ 	  /* We modify the global scope.  Report this.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+ 	    _dl_debug_printf ("\nadd %s [%lu] to global scope\n",
+ 			      map->l_name, map->l_ns);
+ 	}
+@@ -251,7 +251,7 @@ dl_open_worker (void *a)
+   if (__glibc_unlikely (new->l_searchlist.r_list != NULL))
+     {
+       /* Let the user know about the opencount.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ 			  new->l_name, new->l_ns, new->l_direct_opencount);
+ 
+@@ -302,7 +302,7 @@ dl_open_worker (void *a)
+   LIBC_PROBE (map_complete, 3, args->nsid, r, new);
+ 
+   /* Print scope information.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+     _dl_show_scope (new, 0);
+ 
+   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
+@@ -519,7 +519,7 @@ dl_open_worker (void *a)
+ 	}
+ 
+       /* Print scope information.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+ 	_dl_show_scope (imap, from_scope);
+     }
+ 
+@@ -577,7 +577,7 @@ TLS generation counter wrapped!  Please report this."));
+ #endif
+ 
+   /* Let the user know about the opencount.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ 		      new->l_name, new->l_ns, new->l_direct_opencount);
+ }
+diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
+index 61252d7..4c83815 100644
+--- a/elf/dl-reloc.c
++++ b/elf/dl-reloc.c
+@@ -178,7 +178,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
+       && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
+     lazy = 0;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
+     _dl_debug_printf ("\nrelocation processing: %s%s\n",
+ 		      DSO_FILENAME (l->l_name), lazy ? " (lazy)" : "");
+ 
+diff --git a/elf/dl-version.c b/elf/dl-version.c
+index f6e5cd9..320628c 100644
+--- a/elf/dl-version.c
++++ b/elf/dl-version.c
+@@ -82,7 +82,7 @@ match_symbol (const char *name, Lmid_t ns, ElfW(Word) hash, const char *string,
+   int result = 0;
+ 
+   /* Display information about what we are doing while debugging.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_VERSIONS))
+     _dl_debug_printf ("\
+ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
+ 		      string, DSO_FILENAME (map->l_name),
+diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
+index dc8359d..7774fda 100644
+--- a/elf/get-dynamic-info.h
++++ b/elf/get-dynamic-info.h
+@@ -166,7 +166,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
+ 	 them. Therefore to avoid breaking existing applications the
+ 	 best we can do is add a warning during debugging with the
+ 	 intent of notifying the user of the problem.  */
+-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
++      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0)
+ 	  && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
+ 	_dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n",
+ 			  l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
+diff --git a/elf/rtld.c b/elf/rtld.c
+index fc3a2db..59c4637 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -323,7 +323,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
+     }
+ #endif
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
+     {
+ #ifndef HP_TIMING_NONAVAIL
+       print_statistics (&rtld_total_time);
+@@ -1701,7 +1701,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+ 	 after relocation.  */
+       struct link_map *l;
+ 
+-      if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++      if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+ 	{
+ 	  struct r_scope_elem *scope = &main_map->l_searchlist;
+ 
+@@ -1731,7 +1731,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+ 		_dl_printf ("\n");
+ 	    }
+ 	}
+-      else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
++      else if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
+ 	{
+ 	  /* Look through the dependencies of the main executable
+ 	     and determine which of them is not actually
+@@ -1839,7 +1839,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+ 		    }
+ 		}
+ 
+-	      if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++	      if ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+ 		  && rtld_multiple_ref)
+ 		{
+ 		  /* Mark the link map as not yet relocated again.  */
+@@ -1972,7 +1972,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+       if (r_list == r_listend && liblist == liblistend)
+ 	prelinked = true;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("\nprelink checking: %s\n",
+ 			  prelinked ? "ok" : "failed");
+     }
+@@ -1990,7 +1990,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+   GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
+ 
+   /* Print scope information.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+     {
+       _dl_debug_printf ("\nInitial object scopes\n");
+ 
+@@ -2265,7 +2265,7 @@ process_dl_debug (const char *dl_debug)
+ 	    if (debopts[cnt].len == len
+ 		&& memcmp (dl_debug, debopts[cnt].name, len) == 0)
+ 	      {
+-		GLRO(dl_debug_mask) |= debopts[cnt].mask;
++		GLRO_dl_debug_mask |= debopts[cnt].mask;
+ 		any_debug = 1;
+ 		break;
+ 	      }
+@@ -2286,7 +2286,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
+       ++dl_debug;
+     }
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
++  if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
+     {
+       /* In order to get an accurate picture of whether a particular
+ 	 DT_NEEDED entry is actually used we have to process both
+@@ -2294,7 +2294,7 @@ warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
+       GLRO(dl_lazy) = 0;
+     }
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_HELP)
++  if (GLRO_dl_debug_mask & DL_DEBUG_HELP)
+     {
+       size_t cnt;
+ 
+@@ -2499,7 +2499,7 @@ process_envvars (enum mode *modep)
+ 	      mode = trace;
+ 	      GLRO(dl_verbose) = 1;
+ #if __OPTION_EGLIBC_RTLD_DEBUG
+-	      GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
++	      GLRO_dl_debug_mask |= DL_DEBUG_PRELINK;
+ #endif
+ 	      GLRO(dl_trace_prelink) = &envline[17];
+ 	    }
+@@ -2548,7 +2548,7 @@ process_envvars (enum mode *modep)
+ 	{
+ 	  unsetenv ("MALLOC_CHECK_");
+ #if __OPTION_EGLIBC_RTLD_DEBUG
+-	  GLRO(dl_debug_mask) = 0;
++	  GLRO_dl_debug_mask = 0;
+ #endif
+ 	}
+ 
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch b/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch
new file mode 100644
index 0000000..4106167
--- /dev/null
+++ b/recipes-core/glibc/glibc/0027-eglibc-use-option-groups-Conditionally-exclude-c-tes.patch
@@ -0,0 +1,145 @@
+From e98779aa56fae0346dff2d0b72acadd0eaf01891 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 27 May 2015 16:10:50 -0700
+Subject: [PATCH 27/27] eglibc-use-option-groups: Conditionally exclude c++
+ tests
+
+    Some test programs written in c++ are still included in spite of
+    "libc-cxx-tests" being omitted from DISTRO_FEATURES_LIBC.
+    All .cc programs are compiled with g++.
+    g++ automatically specifies linking against the C++ library.
+    This patch conditionally excludes the following tests as well:
+
+      bug-atexit3-lib.cc
+      tst-cancel24.cc
+      tst-cancel24-static.cc
+      tst-unique3lib.cc
+      tst-unique3lib2.cc
+      tst-unique4lib.cc
+      tst-unique3.cc
+      tst-unique4.cc
+
+    Tested with DISTRO_FEATURES_LIBC_remove = " libc-cxx-tests"
+
+    [YOCTO #7003]
+
+Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ dlfcn/Makefile |  8 ++++++--
+ elf/Makefile   | 19 ++++++++++++++-----
+ nptl/Makefile  | 12 ++++++++++--
+ 3 files changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/dlfcn/Makefile b/dlfcn/Makefile
+index 3827607..920bd58 100644
+--- a/dlfcn/Makefile
++++ b/dlfcn/Makefile
+@@ -39,16 +39,20 @@ ifeq (yes,$(build-shared))
+ tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
+ 	bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
+ 	tstatexit bug-dl-leaf tst-rec-dlopen
+-endif
+-
+ tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3
+ 
++endif
++
+ modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
+ 		defaultmod2 errmsg1mod modatexit modcxaatexit \
+ 		bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
+ 		bug-atexit2-lib bug-dl-leaf-lib \
+ 		bug-dl-leaf-lib-cb moddummy1 moddummy2
+ 
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++modules-names += bug-atexit3-lib
++endif
++
+ failtestmod.so-no-z-defs = yes
+ glreflib2.so-no-z-defs = yes
+ errmsg1mod.so-no-z-defs = yes
+diff --git a/elf/Makefile b/elf/Makefile
+index 71a18a1..26fe3c5 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -17,6 +17,8 @@
+ 
+ # Makefile for elf subdirectory of GNU C Library.
+ 
++include ../option-groups.mak
++
+ subdir		:= elf
+ 
+ include ../Makeconfig
+@@ -145,12 +147,15 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
+ 	 unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
+ 	 tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
+ 	 tst-stackguard1 tst-addr1 tst-thrlock \
+-	 tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \
+-	 tst-nodelete) \
++	 tst-unique1 tst-unique2 \
+ 	 tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
+ 	 tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
+ 	 tst-nodelete2
+ #	 reldep9
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++tests += $(if $(CXX),tst-unique3 tst-unique4 tst-nodelete)
++endif
++
+ ifeq ($(build-hardcoded-path-in-tests),yes)
+ tests += tst-dlopen-aout
+ LDFLAGS-tst-dlopen-aout = $(no-pie-ldflag)
+@@ -209,9 +214,6 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		tst-unique1mod1 tst-unique1mod2 \
+ 		tst-unique2mod1 tst-unique2mod2 \
+ 		tst-auditmod9a tst-auditmod9b \
+-		$(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
+-		  tst-nodelete-uniquemod tst-nodelete-rtldmod \
+-		  tst-nodelete-zmod) \
+ 		tst-initordera1 tst-initorderb1 \
+ 		tst-initordera2 tst-initorderb2 \
+ 		tst-initordera3 tst-initordera4 \
+@@ -220,6 +222,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
+ 		tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
+ 		tst-array5dep tst-null-argv-lib \
+ 		tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod
++
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++modules-names += $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
++		  tst-nodelete-uniquemod tst-nodelete-rtldmod \
++		  tst-nodelete-zmod)
++endif
++
+ ifeq (yes,$(have-protected-data))
+ modules-names += tst-protected1moda tst-protected1modb
+ tests += tst-protected1a tst-protected1b
+diff --git a/nptl/Makefile b/nptl/Makefile
+index 596ca3c..50a708b 100644
+--- a/nptl/Makefile
++++ b/nptl/Makefile
+@@ -390,12 +390,20 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
+ 		    $(common-objpfx)libc.a
+ 
+ tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \
+-		tst-cancel21-static tst-cancel24-static tst-cond8-static \
++		tst-cancel21-static tst-cond8-static \
+ 		tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
+ 		tst-sem12-static
+-tests += tst-stackguard1-static tst-cancel21-static tst-cancel24-static \
++
++ifeq (y,$(OPTION_EGLIBC_CXX_TESTS))
++tests-static += tst-cancel24-static
++endif
++
++tests += tst-stackguard1-static tst-cancel21-static \
+ 	 tst-cond8-static tst-mutex8-static tst-mutexpi8-static \
+ 	 tst-sem11-static tst-sem12-static
++
++tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24-static
++
+ xtests-static += tst-setuid1-static
+ 
+ # These tests are linked with libc before libpthread
+-- 
+2.1.4
+
diff --git a/recipes-core/glibc/glibc/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch b/recipes-core/glibc/glibc/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
new file mode 100644
index 0000000..8cfdbea
--- /dev/null
+++ b/recipes-core/glibc/glibc/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
@@ -0,0 +1,339 @@
+From a5357b7ce2a2982c5778435704bcdb55ce3667a0 Mon Sep 17 00:00:00 2001
+From: Jeff Law <law@redhat.com>
+Date: Mon, 15 Dec 2014 10:09:32 +0100
+Subject: [PATCH] CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
+
+A larger number of format specifiers coudld cause a stack overflow,
+potentially allowing to bypass _FORTIFY_SOURCE format string
+protection.
+---
+ ChangeLog               |  9 +++++++
+ NEWS                    | 13 +++++----
+ stdio-common/Makefile   |  2 +-
+ stdio-common/bug23-2.c  | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
+ stdio-common/bug23-3.c  | 50 +++++++++++++++++++++++++++++++++++
+ stdio-common/bug23-4.c  | 31 ++++++++++++++++++++++
+ stdio-common/vfprintf.c | 40 ++++++++++++++++++++++++++--
+ 7 files changed, 207 insertions(+), 8 deletions(-)
+ create mode 100644 stdio-common/bug23-2.c
+ create mode 100644 stdio-common/bug23-3.c
+ create mode 100644 stdio-common/bug23-4.c
+
+Index: git/ChangeLog
+===================================================================
+--- git.orig/ChangeLog
++++ git/ChangeLog
+@@ -1,3 +1,12 @@
++2014-12-15  Jeff Law  <law@redhat.com>
++
++   [BZ #16617]
++   * stdio-common/vfprintf.c (vfprintf): Allocate large specs array
++   on the heap.  (CVE-2012-3406)
++   * stdio-common/bug23-2.c, stdio-common/bug23-3.c: New file.
++   * stdio-common/bug23-4.c: New file.  Test case by Joseph Myers.
++   * stdio-common/Makefile (tests): Add bug23-2, bug23-3, bug23-4.
++
+ 2014-11-19  Carlos O'Donell  <carlos@redhat.com>
+        Florian Weimer  <fweimer@redhat.com>
+        Joseph Myers  <joseph@codesourcery.com>
+Index: git/NEWS
+===================================================================
+--- git.orig/NEWS
++++ git/NEWS
+@@ -13,24 +13,28 @@ Version 2.20
+   15698, 15804, 15894, 15946, 16002, 16064, 16095, 16194, 16198, 16275,
+   16284, 16287, 16315, 16348, 16349, 16354, 16357, 16362, 16447, 16516,
+   16532, 16539, 16545, 16561, 16562, 16564, 16574, 16599, 16600, 16609,
+-  16610, 16611, 16613, 16619, 16623, 16629, 16632, 16634, 16639, 16642,
+-  16648, 16649, 16670, 16674, 16677, 16680, 16681, 16683, 16689, 16695,
+-  16701, 16706, 16707, 16712, 16713, 16714, 16724, 16731, 16739, 16740,
+-  16743, 16754, 16758, 16759, 16760, 16770, 16786, 16789, 16791, 16796,
+-  16799, 16800, 16815, 16823, 16824, 16831, 16838, 16839, 16849, 16854,
+-  16876, 16877, 16878, 16882, 16885, 16888, 16890, 16892, 16912, 16915,
+-  16916, 16917, 16918, 16922, 16927, 16928, 16932, 16943, 16958, 16965,
+-  16966, 16967, 16977, 16978, 16984, 16990, 16996, 17009, 17022, 17031,
+-  17042, 17048, 17050, 17058, 17061, 17062, 17069, 17075, 17078, 17079,
+-  17084, 17086, 17088, 17092, 17097, 17125, 17135, 17137, 17150, 17153,
+-  17187, 17213, 17259, 17261, 17262, 17263, 17319, 17325, 17354, 17625.
+-
++  16610, 16611, 16613, 16617, 16619, 16623, 16629, 16632, 16634, 16639,
++  16642, 16648, 16649, 16670, 16674, 16677, 16680, 16681, 16683, 16689,
++  16695, 16701, 16706, 16707, 16712, 16713, 16714, 16724, 16731, 16739,
++  16740, 16743, 16754, 16758, 16759, 16760, 16770, 16786, 16789, 16791,
++  16796, 16799, 16800, 16815, 16823, 16824, 16831, 16838, 16839, 16849,
++  16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16892, 16912,
++  16915, 16916, 16917, 16918, 16922, 16927, 16928, 16932, 16943, 16958,
++  16965, 16966, 16967, 16977, 16978, 16984, 16990, 16996, 17009, 17022,
++  17031, 17042, 17048, 17050, 17058, 17061, 17062, 17069, 17075, 17078,
++  17079, 17084, 17086, 17088, 17092, 17097, 17125, 17135, 17137, 17150,
++  17153, 17187, 17213, 17259, 17261, 17262, 17263, 17319, 17325, 17354,
++  17625.
++
+ * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
+   under certain input conditions resulting in the execution of a shell for
+   command substitution when the applicaiton did not request it. The
+   implementation now checks WRDE_NOCMD immediately before executing the
+   shell and returns the error WRDE_CMDSUB as expected.
+ 
++* CVE-2012-3406 printf-style functions could run into a stack overflow when
++  processing format strings with a large number of format specifiers.
++
+ * Reverted change of ABI data structures for s390 and s390x:
+   On s390 and s390x the size of struct ucontext and jmp_buf was increased in
+   2.19. This change is reverted in 2.20. The introduced 2.19 symbol versions
+Index: git/stdio-common/bug23-2.c
+===================================================================
+--- /dev/null
++++ git/stdio-common/bug23-2.c
+@@ -0,0 +1,70 @@
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++
++static const char expected[] = "\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55\
++\n\
++a\n\
++abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
++
++static int
++do_test (void)
++{
++  char *buf = malloc (strlen (expected) + 1);
++  snprintf (buf, strlen (expected) + 1,
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++	    "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",
++	    "a", "b", "c", "d", 5);
++  return strcmp (buf, expected) != 0;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+Index: git/stdio-common/bug23-3.c
+===================================================================
+--- /dev/null
++++ git/stdio-common/bug23-3.c
+@@ -0,0 +1,50 @@
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++
++int
++do_test (void)
++{
++  size_t instances = 16384;
++#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
++  const char *item = "\na\nabbcd55";
++#define X3 X0 X0 X0 X0 X0 X0 X0 X0
++#define X6 X3 X3 X3 X3 X3 X3 X3 X3
++#define X9 X6 X6 X6 X6 X6 X6 X6 X6
++#define X12 X9 X9 X9 X9 X9 X9 X9 X9
++#define X14 X12 X12 X12 X12
++#define TRAILER "%%%%%%%%%%%%%%%%%%%%%%%%%%"
++#define TRAILER2 TRAILER TRAILER
++  size_t length = instances * strlen (item) + strlen (TRAILER) + 1;
++
++  char *buf = malloc (length + 1);
++  snprintf (buf, length + 1,
++	    X14 TRAILER2 "\n",
++	    "a", "b", "c", "d", 5);
++
++  const char *p = buf;
++  size_t i;
++  for (i = 0; i < instances; ++i)
++    {
++      const char *expected;
++      for (expected = item; *expected; ++expected)
++	{
++	  if (*p != *expected)
++	    {
++	      printf ("mismatch at offset %zu (%zu): expected %d, got %d\n",
++		      (size_t) (p - buf), i, *expected & 0xFF, *p & 0xFF);
++	      return 1;
++	    }
++	  ++p;
++	}
++    }
++  if (strcmp (p, TRAILER "\n") != 0)
++    {
++      printf ("mismatch at trailer: [%s]\n", p);
++      return 1;
++    }
++  free (buf);
++  return 0;
++}
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+Index: git/stdio-common/bug23-4.c
+===================================================================
+--- /dev/null
++++ git/stdio-common/bug23-4.c
+@@ -0,0 +1,31 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/resource.h>
++
++#define LIMIT 1000000
++
++int
++main (void)
++{
++  struct rlimit lim;
++  getrlimit (RLIMIT_STACK, &lim);
++  lim.rlim_cur = 1048576;
++  setrlimit (RLIMIT_STACK, &lim);
++  char *fmtstr = malloc (4 * LIMIT + 1);
++  if (fmtstr == NULL)
++    abort ();
++  char *output = malloc (LIMIT + 1);
++  if (output == NULL)
++    abort ();
++  for (size_t i = 0; i < LIMIT; i++)
++    memcpy (fmtstr + 4 * i, "%1$d", 4);
++  fmtstr[4 * LIMIT] = '\0';
++  int ret = snprintf (output, LIMIT + 1, fmtstr, 0);
++  if (ret != LIMIT)
++    abort ();
++  for (size_t i = 0; i < LIMIT; i++)
++    if (output[i] != '0')
++      abort ();
++  return 0;
++}
+Index: git/stdio-common/vfprintf.c
+===================================================================
+--- git.orig/stdio-common/vfprintf.c
++++ git/stdio-common/vfprintf.c
+@@ -276,6 +276,12 @@ vfprintf (FILE *s, const CHAR_T *format,
+   /* For the argument descriptions, which may be allocated on the heap.  */
+   void *args_malloced = NULL;
+ 
++  /* For positional argument handling.  */
++  struct printf_spec *specs;
++
++  /* Track if we malloced the SPECS array and thus must free it.  */
++  bool specs_malloced = false;
++
+   /* This table maps a character into a number representing a
+      class.  In each step there is a destination label for each
+      class.  */
+@@ -1699,8 +1705,8 @@ do_positional:
+     size_t nspecs = 0;
+     /* A more or less arbitrary start value.  */
+     size_t nspecs_size = 32 * sizeof (struct printf_spec);
+-    struct printf_spec *specs = alloca (nspecs_size);
+ 
++    specs = alloca (nspecs_size);
+     /* The number of arguments the format string requests.  This will
+        determine the size of the array needed to store the argument
+        attributes.  */
+@@ -1743,11 +1749,39 @@ do_positional:
+ 	if (nspecs * sizeof (*specs) >= nspecs_size)
+ 	  {
+ 	    /* Extend the array of format specifiers.  */
++	    if (nspecs_size * 2 < nspecs_size)
++	      {
++		__set_errno (ENOMEM);
++		done = -1;
++		goto all_done;
++	      }
+ 	    struct printf_spec *old = specs;
+-	    specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
++	    if (__libc_use_alloca (2 * nspecs_size))
++	      specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
++	    else
++	      {
++		nspecs_size *= 2;
++		specs = malloc (nspecs_size);
++		if (specs == NULL)
++		  {
++		    __set_errno (ENOMEM);
++		    specs = old;
++		    done = -1;
++		    goto all_done;
++		  }
++	      }
+ 
+ 	    /* Copy the old array's elements to the new space.  */
+ 	    memmove (specs, old, nspecs * sizeof (*specs));
++
++	    /* If we had previously malloc'd space for SPECS, then
++	       release it after the copy is complete.  */
++	    if (specs_malloced)
++	      free (old);
++
++	    /* Now set SPECS_MALLOCED if needed.  */
++	    if (!__libc_use_alloca (nspecs_size))
++	      specs_malloced = true;
+ 	  }
+ 
+ 	/* Parse the format specifier.  */
+@@ -2068,6 +2102,8 @@ do_positional:
+   }
+ 
+ all_done:
++  if (specs_malloced)
++    free (specs);
+   if (__glibc_unlikely (args_malloced != NULL))
+     free (args_malloced);
+   if (__glibc_unlikely (workstart != NULL))
+Index: git/stdio-common/Makefile
+===================================================================
+--- git.orig/stdio-common/Makefile
++++ git/stdio-common/Makefile
+@@ -66,7 +66,7 @@ tests := tstscanf test_rdwr test-popen t
+ 	 tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
+ 	 bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17 \
+ 	 tst-setvbuf1 bug23 bug24 bug-vfprintf-nargs tst-sprintf3 bug25 \
+-	 tst-printf-round bug26
++	 tst-printf-round bug23-2 bug23-3 bug23-4
+ 
+ tests-$(OPTION_EGLIBC_LOCALE_CODE) \
+       += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
diff --git a/recipes-core/glibc/glibc/CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch b/recipes-core/glibc/glibc/CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch
new file mode 100644
index 0000000..d95d182
--- /dev/null
+++ b/recipes-core/glibc/glibc/CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch
@@ -0,0 +1,215 @@
+From a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c Mon Sep 17 00:00:00 2001
+From: Carlos O'Donell <carlos@redhat.com>
+Date: Wed, 19 Nov 2014 11:44:12 -0500
+Subject: [PATCH] CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
+
+The function wordexp() fails to properly handle the WRDE_NOCMD
+flag when processing arithmetic inputs in the form of "$((... ``))"
+where "..." can be anything valid. The backticks in the arithmetic
+epxression are evaluated by in a shell even if WRDE_NOCMD forbade
+command substitution. This allows an attacker to attempt to pass
+dangerous commands via constructs of the above form, and bypass
+the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD
+in exec_comm(), the only place that can execute a shell. All other
+checks for WRDE_NOCMD are superfluous and removed.
+
+We expand the testsuite and add 3 new regression tests of roughly
+the same form but with a couple of nested levels.
+
+On top of the 3 new tests we add fork validation to the WRDE_NOCMD
+testing. If any forks are detected during the execution of a wordexp()
+call with WRDE_NOCMD, the test is marked as failed. This is slightly
+heuristic since vfork might be used in the future, but it provides a
+higher level of assurance that no shells were executed as part of
+command substitution with WRDE_NOCMD in effect. In addition it doesn't
+require libpthread or libdl, instead we use the public implementation
+namespace function __register_atfork (already part of the public ABI
+for libpthread).
+
+Tested on x86_64 with no regressions.
+---
+ ChangeLog            | 22 ++++++++++++++++++++++
+ NEWS                 |  8 +++++++-
+ posix/wordexp-test.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ posix/wordexp.c      | 16 ++++------------
+ 4 files changed, 77 insertions(+), 13 deletions(-)
+
+Index: git/ChangeLog
+===================================================================
+--- git.orig/ChangeLog
++++ git/ChangeLog
+@@ -1,3 +1,24 @@
++2014-11-19  Carlos O'Donell  <carlos@redhat.com>
++       Florian Weimer  <fweimer@redhat.com>
++       Joseph Myers  <joseph@codesourcery.com>
++       Adam Conrad  <adconrad@0c3.net>
++       Andreas Schwab  <schwab@suse.de>
++       Brooks  <bmoses@google.com>
++
++   [BZ #17625]
++   * wordexp-test.c (__dso_handle): Add prototype.
++   (__register_atfork): Likewise.
++   (__app_register_atfork): New function.
++   (registered_forks): New global.
++   (register_fork): New function.
++   (test_case): Add 3 new tests for WRDE_CMDSUB.
++   (main): Call __app_register_atfork.
++   (testit): If WRDE_NOCMD set registered_forks to zero, run test, and if
++   fork count is non-zero fail the test.
++   * posix/wordexp.c (exec_comm): Return WRDE_CMDSUB if WRDE_NOCMD flag
++   is set.
++   (parse_dollars): Remove check for WRDE_NOCMD.
++
+ 2014-09-07  Allan McRae  <allan@archlinux.org
+ 
+ 	* version.h (RELEASE): Set to "stable".
+Index: git/NEWS
+===================================================================
+--- git.orig/NEWS
++++ git/NEWS
+@@ -23,7 +23,13 @@ Version 2.20
+   16966, 16967, 16977, 16978, 16984, 16990, 16996, 17009, 17022, 17031,
+   17042, 17048, 17050, 17058, 17061, 17062, 17069, 17075, 17078, 17079,
+   17084, 17086, 17088, 17092, 17097, 17125, 17135, 17137, 17150, 17153,
+-  17187, 17213, 17259, 17261, 17262, 17263, 17319, 17325, 17354.
++  17187, 17213, 17259, 17261, 17262, 17263, 17319, 17325, 17354, 17625.
++
++* CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
++  under certain input conditions resulting in the execution of a shell for
++  command substitution when the applicaiton did not request it. The
++  implementation now checks WRDE_NOCMD immediately before executing the
++  shell and returns the error WRDE_CMDSUB as expected.
+ 
+ * Reverted change of ABI data structures for s390 and s390x:
+   On s390 and s390x the size of struct ucontext and jmp_buf was increased in
+Index: git/posix/wordexp-test.c
+===================================================================
+--- git.orig/posix/wordexp-test.c
++++ git/posix/wordexp-test.c
+@@ -27,6 +27,25 @@
+ 
+ #define IFS " \n\t"
+ 
++extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
++extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
++
++static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
++{
++  return __register_atfork (prepare, parent, child,
++			    &__dso_handle == NULL ? NULL : __dso_handle);
++}
++
++/* Number of forks seen.  */
++static int registered_forks;
++
++/* For each fork increment the fork count.  */
++static void
++register_fork (void)
++{
++  registered_forks++;
++}
++
+ struct test_case_struct
+ {
+   int retval;
+@@ -206,6 +225,12 @@ struct test_case_struct
+     { WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS },
+     { WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS },
+     { WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS },
++    /* Test for CVE-2014-7817. We test 3 combinations of command
++       substitution inside an arithmetic expression to make sure that
++       no commands are executed and error is returned.  */
++    { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
++    { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
++    { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS },
+ 
+     { -1, NULL, NULL, 0, 0, { NULL, }, IFS },
+   };
+@@ -258,6 +283,15 @@ main (int argc, char *argv[])
+ 	  return -1;
+     }
+ 
++  /* If we are not allowed to do command substitution, we install
++     fork handlers to verify that no forks happened.  No forks should
++     happen at all if command substitution is disabled.  */
++  if (__app_register_atfork (register_fork, NULL, NULL) != 0)
++    {
++      printf ("Failed to register fork handler.\n");
++      return -1;
++    }
++
+   for (test = 0; test_case[test].retval != -1; test++)
+     if (testit (&test_case[test]))
+       ++fail;
+@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc)
+ 
+   printf ("Test %d (%s): ", ++tests, tc->words);
+ 
++  if (tc->flags & WRDE_NOCMD)
++    registered_forks = 0;
++
+   if (tc->flags & WRDE_APPEND)
+     {
+       /* initial wordexp() call, to be appended to */
+@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc)
+     }
+   retval = wordexp (tc->words, &we, tc->flags);
+ 
++  if ((tc->flags & WRDE_NOCMD)
++      && (registered_forks > 0))
++    {
++	  printf ("FAILED fork called for WRDE_NOCMD\n");
++	  return 1;
++    }
++
+   if (tc->flags & WRDE_DOOFFS)
+       start_offs = sav_we.we_offs;
+ 
+Index: git/posix/wordexp.c
+===================================================================
+--- git.orig/posix/wordexp.c
++++ git/posix/wordexp.c
+@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size
+   pid_t pid;
+   int noexec = 0;
+ 
++  /* Do nothing if command substitution should not succeed.  */
++  if (flags & WRDE_NOCMD)
++    return WRDE_CMDSUB;
++
+   /* Don't fork() unless necessary */
+   if (!comm || !*comm)
+     return 0;
+@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word
+ 	    }
+ 	}
+ 
+-      if (flags & WRDE_NOCMD)
+-	return WRDE_CMDSUB;
+-
+       (*offset) += 2;
+       return parse_comm (word, word_length, max_length, words, offset, flags,
+ 			 quoted? NULL : pwordexp, ifs, ifs_white);
+@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_
+ 	  break;
+ 
+ 	case '`':
+-	  if (flags & WRDE_NOCMD)
+-	    return WRDE_CMDSUB;
+-
+ 	  ++(*offset);
+ 	  error = parse_backtick (word, word_length, max_length, words,
+ 				  offset, flags, NULL, NULL, NULL);
+@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *p
+ 	break;
+ 
+       case '`':
+-	if (flags & WRDE_NOCMD)
+-	  {
+-	    error = WRDE_CMDSUB;
+-	    goto do_error;
+-	  }
+-
+ 	++words_offset;
+ 	error = parse_backtick (&word, &word_length, &max_length, words,
+ 				&words_offset, flags, pwordexp, ifs,
diff --git a/recipes-core/glibc/glibc/CVE-2014-9402_endless-loop-in-getaddr_r.patch b/recipes-core/glibc/glibc/CVE-2014-9402_endless-loop-in-getaddr_r.patch
new file mode 100644
index 0000000..ba1da67
--- /dev/null
+++ b/recipes-core/glibc/glibc/CVE-2014-9402_endless-loop-in-getaddr_r.patch
@@ -0,0 +1,65 @@
+CVE-2014-9402 endless loop in getaddr_r
+
+
+https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commit;h=11e3417af6e354f1942c68a271ae51e892b2814d
+
+Upstream-Status: Backport
+
+Signed-off-by: Armin Kuster <akuster@mvista.com>
+
+From 11e3417af6e354f1942c68a271ae51e892b2814d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 15 Dec 2014 17:41:13 +0100
+Subject: [PATCH] Avoid infinite loop in nss_dns getnetbyname [BZ #17630]
+
+---
+ ChangeLog                    | 6 ++++++
+ NEWS                         | 7 +++++--
+ resolv/nss_dns/dns-network.c | 4 ++--
+ 3 files changed, 13 insertions(+), 4 deletions(-)
+
+Index: git/NEWS
+===================================================================
+--- git.orig/NEWS
++++ git/NEWS
+@@ -24,7 +24,10 @@ Version 2.20
+   17031, 17042, 17048, 17050, 17058, 17061, 17062, 17069, 17075, 17078,
+   17079, 17084, 17086, 17088, 17092, 17097, 17125, 17135, 17137, 17150,
+   17153, 17187, 17213, 17259, 17261, 17262, 17263, 17319, 17325, 17354,
+-  17625.
++  17625, 17630.
++
++* The nss_dns implementation of getnetbyname could run into an infinite loop
++  if the DNS response contained a PTR record of an unexpected format.
+ 
+ * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
+   under certain input conditions resulting in the execution of a shell for
+Index: git/resolv/nss_dns/dns-network.c
+===================================================================
+--- git.orig/resolv/nss_dns/dns-network.c
++++ git/resolv/nss_dns/dns-network.c
+@@ -398,8 +398,8 @@ getanswer_r (const querybuf *answer, int
+ 
+ 	case BYNAME:
+ 	  {
+-	    char **ap = result->n_aliases++;
+-	    while (*ap != NULL)
++	    char **ap;
++	    for (ap = result->n_aliases; *ap != NULL; ++ap)
+ 	      {
+ 		/* Check each alias name for being of the forms:
+ 		   4.3.2.1.in-addr.arpa		= net 1.2.3.4
+Index: git/ChangeLog
+===================================================================
+--- git.orig/ChangeLog
++++ git/ChangeLog
+@@ -1,3 +1,9 @@
++2014-12-16  Florian Weimer  <fweimer@redhat.com>
++
++       [BZ #17630]
++       * resolv/nss_dns/dns-network.c (getanswer_r): Iterate over alias
++       names.
++
+ 2014-12-15  Jeff Law  <law@redhat.com>
+ 
+    [BZ #16617]
diff --git a/recipes-core/glibc/glibc/CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch b/recipes-core/glibc/glibc/CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch
new file mode 100644
index 0000000..c02fa12
--- /dev/null
+++ b/recipes-core/glibc/glibc/CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch
@@ -0,0 +1,43 @@
+From 2959eda9272a033863c271aff62095abd01bd4e3 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun.is@lostca.se>
+Date: Tue, 21 Apr 2015 14:06:31 +0200
+Subject: [PATCH] CVE-2015-1781: resolv/nss_dns/dns-host.c buffer overflow
+ [BZ#18287]
+
+Upstream-Status: Backport
+https://sourceware.org/bugzilla/show_bug.cgi?id=18287
+---
+ resolv/nss_dns/dns-host.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index b16b0ddf110907a0086b86612e544d3dc75182b8..d8c55791591750567f00e616e5d7b378dec934a0 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -608,21 +608,22 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
+   int n, ancount, qdcount;
+   int haveanswer, had_error;
+   char *bp, **ap, **hap;
+   char tbuf[MAXDNAME];
+   const char *tname;
+   int (*name_ok) (const char *);
+   u_char packtmp[NS_MAXCDNAME];
+   int have_to_map = 0;
+   uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+   buffer += pad;
+-  if (__glibc_unlikely (buflen < sizeof (struct host_data) + pad))
++  buflen = buflen > pad ? buflen - pad : 0;
++  if (__glibc_unlikely (buflen < sizeof (struct host_data)))
+     {
+       /* The buffer is too small.  */
+     too_small:
+       *errnop = ERANGE;
+       *h_errnop = NETDB_INTERNAL;
+       return NSS_STATUS_TRYAGAIN;
+     }
+   host_data = (struct host_data *) buffer;
+   linebuflen = buflen - sizeof (struct host_data);
+   if (buflen - sizeof (struct host_data) != linebuflen)
+-- 
+2.2.2
+
diff --git a/recipes-core/glibc/glibc/GLRO_dl_debug_mask.patch b/recipes-core/glibc/glibc/GLRO_dl_debug_mask.patch
new file mode 100644
index 0000000..e858bfa
--- /dev/null
+++ b/recipes-core/glibc/glibc/GLRO_dl_debug_mask.patch
@@ -0,0 +1,529 @@
+Its controlled by __OPTION_EGLIBC_RTLD_DEBUG
+so we should use GLRO_dl_debug_mask
+
+Singed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Upstream-Status: Pending
+Index: git/elf/dl-open.c
+===================================================================
+--- git.orig/elf/dl-open.c	2014-08-27 05:03:59.732070587 +0000
++++ git/elf/dl-open.c	2014-08-27 05:05:25.656070587 +0000
+@@ -147,7 +147,7 @@
+ 	  ns->_ns_main_searchlist->r_list[new_nlist++] = map;
+ 
+ 	  /* We modify the global scope.  Report this.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+ 	    _dl_debug_printf ("\nadd %s [%lu] to global scope\n",
+ 			      map->l_name, map->l_ns);
+ 	}
+@@ -243,7 +243,7 @@
+   if (__glibc_unlikely (new->l_searchlist.r_list != NULL))
+     {
+       /* Let the user know about the opencount.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ 			  new->l_name, new->l_ns, new->l_direct_opencount);
+ 
+@@ -294,7 +294,7 @@
+   LIBC_PROBE (map_complete, 3, args->nsid, r, new);
+ 
+   /* Print scope information.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+     _dl_show_scope (new, 0);
+ 
+   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
+@@ -511,7 +511,7 @@
+ 	}
+ 
+       /* Print scope information.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+ 	_dl_show_scope (imap, from_scope);
+     }
+ 
+@@ -584,7 +584,7 @@
+ #endif
+ 
+   /* Let the user know about the opencount.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
+ 		      new->l_name, new->l_ns, new->l_direct_opencount);
+ }
+Index: git/elf/rtld.c
+===================================================================
+--- git.orig/elf/rtld.c	2014-08-27 05:03:59.732070587 +0000
++++ git/elf/rtld.c	2014-08-27 05:12:33.812070587 +0000
+@@ -321,7 +321,7 @@
+     }
+ #endif
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
+     {
+ #ifndef HP_TIMING_NONAVAIL
+       print_statistics (&rtld_total_time);
+@@ -1699,7 +1699,7 @@
+ 	 after relocation.  */
+       struct link_map *l;
+ 
+-      if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++      if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+ 	{
+ 	  struct r_scope_elem *scope = &main_map->l_searchlist;
+ 
+@@ -1729,7 +1729,7 @@
+ 		_dl_printf ("\n");
+ 	    }
+ 	}
+-      else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
++      else if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
+ 	{
+ 	  /* Look through the dependencies of the main executable
+ 	     and determine which of them is not actually
+@@ -1837,7 +1837,7 @@
+ 		    }
+ 		}
+ 
+-	      if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++	      if ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+ 		  && rtld_multiple_ref)
+ 		{
+ 		  /* Mark the link map as not yet relocated again.  */
+@@ -1970,7 +1970,7 @@
+       if (r_list == r_listend && liblist == liblistend)
+ 	prelinked = true;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("\nprelink checking: %s\n",
+ 			  prelinked ? "ok" : "failed");
+     }
+@@ -1988,7 +1988,7 @@
+   GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
+ 
+   /* Print scope information.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SCOPES))
+     {
+       _dl_debug_printf ("\nInitial object scopes\n");
+ 
+@@ -2262,7 +2262,7 @@
+ 	    if (debopts[cnt].len == len
+ 		&& memcmp (dl_debug, debopts[cnt].name, len) == 0)
+ 	      {
+-		GLRO(dl_debug_mask) |= debopts[cnt].mask;
++		GLRO_dl_debug_mask |= debopts[cnt].mask;
+ 		any_debug = 1;
+ 		break;
+ 	      }
+@@ -2283,7 +2283,7 @@
+       ++dl_debug;
+     }
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
++  if (GLRO_dl_debug_mask & DL_DEBUG_UNUSED)
+     {
+       /* In order to get an accurate picture of whether a particular
+ 	 DT_NEEDED entry is actually used we have to process both
+@@ -2291,7 +2291,7 @@
+       GLRO(dl_lazy) = 0;
+     }
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_HELP)
++  if (GLRO_dl_debug_mask & DL_DEBUG_HELP)
+     {
+       size_t cnt;
+ 
+@@ -2490,7 +2490,7 @@
+ 	    {
+ 	      mode = trace;
+ 	      GLRO(dl_verbose) = 1;
+-	      GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
++	      GLRO_dl_debug_mask |= DL_DEBUG_PRELINK;
+ 	      GLRO(dl_trace_prelink) = &envline[17];
+ 	    }
+ 	  break;
+@@ -2537,7 +2537,7 @@
+       if (__access ("/etc/suid-debug", F_OK) != 0)
+ 	{
+ 	  unsetenv ("MALLOC_CHECK_");
+-	  GLRO(dl_debug_mask) = 0;
++	  GLRO_dl_debug_mask = 0;
+ 	}
+ 
+       if (mode != normal)
+Index: git/elf/dl-lookup.c
+===================================================================
+--- git.orig/elf/dl-lookup.c	2014-08-27 05:03:59.732070587 +0000
++++ git/elf/dl-lookup.c	2014-08-27 05:13:07.644070587 +0000
+@@ -300,7 +300,7 @@
+ 	 hash table.  */
+       if (__glibc_unlikely (tab->size))
+ 	{
+-	  assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
++	  assert (GLRO_dl_debug_mask & DL_DEBUG_PRELINK);
+ 	  goto success;
+ 	}
+ #endif
+@@ -375,7 +375,7 @@
+ 	continue;
+ 
+       /* Print some debugging info if wanted.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS))
+ 	_dl_debug_printf ("symbol=%s;  lookup in file=%s [%lu]\n",
+ 			  undef_name, DSO_FILENAME (map->l_name),
+ 			  map->l_ns);
+@@ -698,7 +698,7 @@
+ 	}
+ 
+       /* Display information if we are debugging.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("\
+ \nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
+ 			  DSO_FILENAME (map->l_name),
+@@ -802,7 +802,7 @@
+     {
+       if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
+ 	  && skip_map == NULL
+-	  && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
++	  && !(GLRO_dl_debug_mask & DL_DEBUG_UNUSED))
+ 	{
+ 	  /* We could find no value for a strong reference.  */
+ 	  const char *reference_name = undef_map ? undef_map->l_name : "";
+@@ -873,7 +873,7 @@
+   if (__glibc_unlikely (current_value.m->l_used == 0))
+     current_value.m->l_used = 1;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask)
++  if (__glibc_unlikely (GLRO_dl_debug_mask
+ 			& (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK)))
+     _dl_debug_bindings (undef_name, undef_map, ref,
+ 			&current_value, version, type_class, protected);
+@@ -938,7 +938,7 @@
+ {
+   const char *reference_name = undef_map->l_name;
+ 
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
++  if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS)
+     {
+       _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
+ 			DSO_FILENAME (reference_name),
+@@ -952,7 +952,7 @@
+ 	_dl_debug_printf_c ("\n");
+     }
+ #ifdef SHARED
+-  if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
++  if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+     {
+       int conflict = 0;
+       struct sym_val val = { NULL, NULL };
+Index: git/elf/get-dynamic-info.h
+===================================================================
+--- git.orig/elf/get-dynamic-info.h	2014-08-27 05:03:59.732070587 +0000
++++ git/elf/get-dynamic-info.h	2014-08-27 05:03:59.728070587 +0000
+@@ -157,7 +157,7 @@
+ 	 them. Therefore to avoid breaking existing applications the
+ 	 best we can do is add a warning during debugging with the
+ 	 intent of notifying the user of the problem.  */
+-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
++      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0)
+ 	  && l->l_flags_1 & ~DT_1_SUPPORTED_MASK)
+ 	_dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.\n",
+ 			  l->l_flags_1 & ~DT_1_SUPPORTED_MASK);
+Index: git/csu/libc-start.c
+===================================================================
+--- git.orig/csu/libc-start.c	2014-08-27 04:59:01.412070587 +0000
++++ git/csu/libc-start.c	2014-08-27 05:09:28.936070587 +0000
+@@ -238,7 +238,7 @@
+ 
+   /* Call the initializer of the program, if any.  */
+ #ifdef SHARED
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
+     GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
+ #endif
+   if (init)
+@@ -261,7 +261,7 @@
+ #endif
+ 
+ #ifdef SHARED
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+     GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
+ #endif
+ 
+Index: git/elf/dl-cache.c
+===================================================================
+--- git.orig/elf/dl-cache.c	2014-08-27 04:59:01.568070587 +0000
++++ git/elf/dl-cache.c	2014-08-27 05:10:14.384070587 +0000
+@@ -187,7 +187,7 @@
+   const char *best;
+ 
+   /* Print a message if the loading of libs is traced.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+     _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);
+ 
+   if (cache == NULL)
+@@ -285,7 +285,7 @@
+     }
+ 
+   /* Print our result if wanted.  */
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
+       && best != NULL)
+     _dl_debug_printf ("  trying file=%s\n", best);
+ 
+Index: git/elf/dl-close.c
+===================================================================
+--- git.orig/elf/dl-close.c	2014-08-27 04:59:01.568070587 +0000
++++ git/elf/dl-close.c	2014-08-27 05:10:26.456070587 +0000
+@@ -125,7 +125,7 @@
+ 	dl_close_state = rerun;
+ 
+       /* There are still references to this object.  Do nothing more.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	_dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
+ 			  map->l_name, map->l_direct_opencount);
+ 
+@@ -257,7 +257,7 @@
+ 	  if (imap->l_init_called)
+ 	    {
+ 	      /* When debugging print a message first.  */
+-	      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
++	      if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS,
+ 				    0))
+ 		_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+ 				  imap->l_name, nsid);
+@@ -664,7 +664,7 @@
+ 	  free (imap->l_reldeps);
+ 
+ 	  /* Print debugging message.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+ 	    _dl_debug_printf ("\nfile=%s [%lu];  destroying link map\n",
+ 			      imap->l_name, imap->l_ns);
+ 
+Index: git/elf/dl-conflict.c
+===================================================================
+--- git.orig/elf/dl-conflict.c	2014-08-27 04:59:01.568070587 +0000
++++ git/elf/dl-conflict.c	2014-08-27 05:10:37.652070587 +0000
+@@ -32,7 +32,7 @@
+ 		       ElfW(Rela) *conflictend)
+ {
+ #if ! ELF_MACHINE_NO_RELA
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
+     _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
+ 
+   {
+Index: git/elf/dl-deps.c
+===================================================================
+--- git.orig/elf/dl-deps.c	2014-08-27 04:59:01.568070587 +0000
++++ git/elf/dl-deps.c	2014-08-27 05:10:48.260070587 +0000
+@@ -127,7 +127,7 @@
+ 	    else							      \
+ 	      {								      \
+ 		/* This is for DT_AUXILIARY.  */			      \
+-		if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))   \
++		if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))   \
+ 		  _dl_debug_printf (N_("\
+ cannot load auxiliary `%s' because of empty dynamic string token "	      \
+ 					    "substitution\n"), __str);	      \
+@@ -303,7 +303,7 @@
+ 		args.name = name;
+ 
+ 		/* Say that we are about to load an auxiliary library.  */
+-		if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS,
++		if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS,
+ 				      0))
+ 		  _dl_debug_printf ("load auxiliary object=%s"
+ 				    " requested by file=%s\n",
+@@ -520,7 +520,7 @@
+       runp->map->l_reserved = 0;
+     }
+ 
+-  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
++  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_PRELINK, 0) != 0
+       && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
+     {
+       /* If we are to compute conflicts, we have to build local scope
+Index: git/elf/dl-error.c
+===================================================================
+--- git.orig/elf/dl-error.c	2014-08-27 04:59:01.568070587 +0000
++++ git/elf/dl-error.c	2014-08-27 05:11:06.752070587 +0000
+@@ -139,7 +139,7 @@
+ _dl_signal_cerror (int errcode, const char *objname, const char *occation,
+ 		   const char *errstring)
+ {
+-  if (__builtin_expect (GLRO(dl_debug_mask)
++  if (__builtin_expect (GLRO_dl_debug_mask
+ 			& ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
+     _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
+ 		      errstring, receiver ? "continued" : "fatal");
+Index: git/elf/dl-fini.c
+===================================================================
+--- git.orig/elf/dl-fini.c	2014-08-27 04:59:01.568070587 +0000
++++ git/elf/dl-fini.c	2014-08-27 05:11:17.544070587 +0000
+@@ -234,7 +234,7 @@
+ 		  || l->l_info[DT_FINI] != NULL)
+ 		{
+ 		  /* When debugging print a message first.  */
+-		  if (__builtin_expect (GLRO(dl_debug_mask)
++		  if (__builtin_expect (GLRO_dl_debug_mask
+ 					& DL_DEBUG_IMPCALLS, 0))
+ 		    _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+ 				      DSO_FILENAME (l->l_name),
+@@ -286,7 +286,7 @@
+       goto again;
+     }
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_STATISTICS))
+     _dl_debug_printf ("\nruntime linker statistics:\n"
+ 		      "           final number of relocations: %lu\n"
+ 		      "final number of relocations from cache: %lu\n",
+Index: git/elf/dl-init.c
+===================================================================
+--- git.orig/elf/dl-init.c	2014-08-27 04:59:01.568070587 +0000
++++ git/elf/dl-init.c	2014-08-27 05:11:28.372070587 +0000
+@@ -52,7 +52,7 @@
+     return;
+ 
+   /* Print a debug message if wanted.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+     _dl_debug_printf ("\ncalling init: %s\n\n",
+ 		      DSO_FILENAME (l->l_name));
+ 
+@@ -102,7 +102,7 @@
+       ElfW(Addr) *addrs;
+       unsigned int cnt;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_IMPCALLS))
+ 	_dl_debug_printf ("\ncalling preinit: %s\n\n",
+ 			  DSO_FILENAME (main_map->l_name));
+ 
+Index: git/elf/dl-load.c
+===================================================================
+--- git.orig/elf/dl-load.c	2014-08-27 04:59:01.572070587 +0000
++++ git/elf/dl-load.c	2014-08-27 05:11:41.156070587 +0000
+@@ -957,7 +957,7 @@
+     }
+ 
+   /* Print debugging message.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("file=%s [%lu];  generating link map\n", name, nsid);
+ 
+   /* This is the ELF header.  We read it in `open_verify'.  */
+@@ -1361,7 +1361,7 @@
+ 
+   l->l_entry += l->l_addr;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES))
+     _dl_debug_printf ("\
+   dynamic: 0x%0*lx  base: 0x%0*lx   size: 0x%0*Zx\n\
+     entry: 0x%0*lx  phdr: 0x%0*lx  phnum:   %*u\n\n",
+@@ -1787,7 +1787,7 @@
+ 
+       /* If we are debugging the search for libraries print the path
+ 	 now if it hasn't happened now.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS)
+ 	  && current_what != this_dir->what)
+ 	{
+ 	  current_what = this_dir->what;
+@@ -1808,7 +1808,7 @@
+ 	     - buf);
+ 
+ 	  /* Print name we try if this is wanted.  */
+-	  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++	  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	    _dl_debug_printf ("  trying file=%s\n", buf);
+ 
+ 	  fd = open_verify (buf, fbp, loader, whatcode, mode,
+@@ -1953,7 +1953,7 @@
+     }
+ 
+   /* Display information if we are debugging.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_FILES)
+       && loader != NULL)
+     _dl_debug_printf ((mode & __RTLD_CALLMAP) == 0
+ 		      ? "\nfile=%s [%lu];  needed by %s [%lu]\n"
+@@ -1995,7 +1995,7 @@
+ 
+       size_t namelen = strlen (name) + 1;
+ 
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
+ 
+       fd = -1;
+@@ -2122,7 +2122,7 @@
+ 			&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
+ 
+       /* Add another newline when we are tracing the library loading.  */
+-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
++      if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("\n");
+     }
+   else
+@@ -2155,7 +2155,7 @@
+   if (__glibc_unlikely (fd == -1))
+     {
+       if (trace_mode
+-	  && __glibc_likely ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) == 0))
++	  && __glibc_likely ((GLRO_dl_debug_mask & DL_DEBUG_PRELINK) == 0))
+ 	{
+ 	  /* We haven't found an appropriate library.  But since we
+ 	     are only interested in the list of libraries this isn't
+Index: git/elf/dl-object.c
+===================================================================
+--- git.orig/elf/dl-object.c	2014-08-27 04:59:01.572070587 +0000
++++ git/elf/dl-object.c	2014-08-27 05:11:51.756070587 +0000
+@@ -98,7 +98,7 @@
+   new->l_type = type;
+   /* If we set the bit now since we know it is never used we avoid
+      dirtying the cache line later.  */
+-  if ((GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) == 0)
++  if ((GLRO_dl_debug_mask & DL_DEBUG_UNUSED) == 0)
+     new->l_used = 1;
+   new->l_loader = loader;
+ #if NO_TLS_OFFSET != 0
+Index: git/elf/dl-reloc.c
+===================================================================
+--- git.orig/elf/dl-reloc.c	2014-08-27 04:59:01.572070587 +0000
++++ git/elf/dl-reloc.c	2014-08-27 05:12:07.056070587 +0000
+@@ -183,7 +183,7 @@
+       && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
+     lazy = 0;
+ 
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_RELOC))
+     _dl_debug_printf ("\nrelocation processing: %s%s\n",
+ 		      DSO_FILENAME (l->l_name), lazy ? " (lazy)" : "");
+ 
+Index: git/elf/dl-version.c
+===================================================================
+--- git.orig/elf/dl-version.c	2014-08-27 04:59:01.608070587 +0000
++++ git/elf/dl-version.c	2014-08-27 05:12:19.568070587 +0000
+@@ -82,7 +82,7 @@
+   int result = 0;
+ 
+   /* Display information about what we are doing while debugging.  */
+-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS))
++  if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_VERSIONS))
+     _dl_debug_printf ("\
+ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
+ 		      string, DSO_FILENAME (map->l_name),
diff --git a/recipes-core/glibc/glibc/IO-acquire-lock-fix.patch b/recipes-core/glibc/glibc/IO-acquire-lock-fix.patch
new file mode 100644
index 0000000..ffbaba1
--- /dev/null
+++ b/recipes-core/glibc/glibc/IO-acquire-lock-fix.patch
@@ -0,0 +1,17 @@
+import http://sourceware.org/ml/libc-ports/2007-12/msg00000.html
+
+Upstream-Status: Pending
+
+Index: git/bits/stdio-lock.h
+===================================================================
+--- git.orig/bits/stdio-lock.h	2014-08-29 10:33:57.960070587 -0700
++++ git/bits/stdio-lock.h	2014-08-29 10:33:57.952070587 -0700
+@@ -49,6 +49,8 @@
+   _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, (_fp));      \
+   _IO_flockfile (_fp)
+ 
++# define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp)
++
+ # define _IO_release_lock(_fp) \
+   _IO_funlockfile (_fp);						      \
+   _IO_cleanup_region_end (0)
diff --git a/recipes-core/glibc/glibc/add_resource_h_to_wait_h.patch b/recipes-core/glibc/glibc/add_resource_h_to_wait_h.patch
new file mode 100644
index 0000000..4559de7
--- /dev/null
+++ b/recipes-core/glibc/glibc/add_resource_h_to_wait_h.patch
@@ -0,0 +1,20 @@
+The older versions of perf still require sys/resource.h to be 
+present in this header, the newer version of perf in 3.2 and
+beyond directly include sys/resource.h
+
+Upstream-Status: Inapproriate [older kernel/perf specific]
+
+Signed-off-by: Saul Wold <sgw@linux.intel.com>
+
+Index: git/posix/sys/wait.h
+===================================================================
+--- git.orig/posix/sys/wait.h	2014-08-29 10:35:10.432070587 -0700
++++ git/posix/sys/wait.h	2014-08-29 10:35:10.424070587 -0700
+@@ -27,6 +27,7 @@
+ __BEGIN_DECLS
+ 
+ #include <signal.h>
++#include <sys/resource.h>
+ 
+ /* These macros could also be defined in <stdlib.h>.  */
+ #if !defined _STDLIB_H || (!defined __USE_XOPEN && !defined __USE_XOPEN2K8)
diff --git a/recipes-core/glibc/glibc/eglibc-header-bootstrap.patch b/recipes-core/glibc/glibc/eglibc-header-bootstrap.patch
new file mode 100644
index 0000000..e1aa139
--- /dev/null
+++ b/recipes-core/glibc/glibc/eglibc-header-bootstrap.patch
@@ -0,0 +1,85 @@
+Taken from EGLIBC, r1484 + r1525
+	
+	2007-02-20  Jim Blandy  <jimb@codesourcery.com>
+	
+	        * Makefile (install-headers): Preserve old behavior: depend on
+	        $(inst_includedir)/gnu/stubs.h only if install-bootstrap-headers
+	        is set; otherwise, place gnu/stubs.h on the 'install-others' list.
+	
+	2007-02-16  Jim Blandy  <jimb@codesourcery.com>
+	
+	        * Makefile: Amend make install-headers to install everything
+	        necessary for building a cross-compiler.  Install gnu/stubs.h as
+	        part of 'install-headers', not 'install-others'.
+	        If install-bootstrap-headers is 'yes', install a dummy copy of
+	        gnu/stubs.h, instead of computing the real thing.
+	        * include/stubs-bootstrap.h: New file.
+
+Upstream-Status: Pending
+
+Index: git/Makefile
+===================================================================
+--- git.orig/Makefile	2014-08-27 18:35:18.908070587 +0000
++++ git/Makefile	2014-08-27 18:35:19.340070587 +0000
+@@ -69,9 +69,18 @@
+ vpath %.h $(subdir-dirs)
+ 
+ # What to install.
+-install-others = $(inst_includedir)/gnu/stubs.h
+ install-bin-script =
+ 
++# If we're bootstrapping, install a dummy gnu/stubs.h along with the
++# other headers, so 'make install-headers' produces a useable include
++# tree.  Otherwise, install gnu/stubs.h later, after the rest of the
++# build is done.
++ifeq ($(install-bootstrap-headers),yes)
++install-headers: $(inst_includedir)/gnu/stubs.h
++else
++install-others = $(inst_includedir)/gnu/stubs.h
++endif
++
+ ifeq (yes,$(build-shared))
+ headers += gnu/lib-names.h
+ endif
+@@ -151,6 +160,16 @@
+ 
+ subdir-stubs := $(foreach dir,$(subdirs),$(common-objpfx)$(dir)/stubs)
+ 
++# gnu/stubs.h depends (via the subdir 'stubs' targets) on all the .o
++# files in EGLIBC.  For bootstrapping a GCC/EGLIBC pair, an empty
++# gnu/stubs.h is good enough.
++ifeq ($(install-bootstrap-headers),yes)
++$(inst_includedir)/gnu/stubs.h: include/stubs-bootstrap.h $(+force)
++	$(make-target-directory)
++	$(INSTALL_DATA) $< $@
++
++installed-stubs =
++else
+ ifndef abi-variants
+ installed-stubs = $(inst_includedir)/gnu/stubs.h
+ else
+@@ -177,6 +196,7 @@
+ 
+ install-others-nosubdir: $(installed-stubs)
+ endif
++endif
+ 
+ 
+ # Since stubs.h is never needed when building the library, we simplify the
+Index: git/include/stubs-bootstrap.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/include/stubs-bootstrap.h	2014-08-27 18:35:19.340070587 +0000
+@@ -0,0 +1,12 @@
++/* Placeholder stubs.h file for bootstrapping.
++
++   When bootstrapping a GCC/EGLIBC pair, GCC requires that the EGLIBC
++   headers be installed, but we can't fully build EGLIBC without that
++   GCC.  So we run the command:
++
++      make install-headers install-bootstrap-headers=yes
++
++   to install the headers GCC needs, but avoid building certain
++   difficult headers.  The <gnu/stubs.h> header depends, via the
++   EGLIBC subdir 'stubs' make targets, on every .o file in EGLIBC, but
++   an empty stubs.h like this will do fine for GCC.  */
diff --git a/recipes-core/glibc/glibc/eglibc-install-pic-archives.patch b/recipes-core/glibc/glibc/eglibc-install-pic-archives.patch
new file mode 100644
index 0000000..9a31255
--- /dev/null
+++ b/recipes-core/glibc/glibc/eglibc-install-pic-archives.patch
@@ -0,0 +1,109 @@
+2008-02-07  Joseph Myers  <joseph@codesourcery.com>
+
+        * Makerules (install-extras, install-map): New variables.
+        (installed-libcs): Add libc_pic.a.
+        (install-lib): Include _pic.a files for versioned shared
+        libraries.
+        (install-map-nosubdir, install-extras-nosubdir): Add rules for
+        installing extra files.
+        (install-no-libc.a-nosubdir): Depend on install-map-nosubdir and
+        install-extras-nosubdir.
+
+
+2008-04-01  Maxim Kuvyrkov  <maxim@codesourcery.com>
+
+        * Makerules (install-lib): Don't install libpthread_pic.a.
+        (install-map): Don't install libpthread_pic.map.
+
+Upstream-Status: Pending
+
+Index: git/Makerules
+===================================================================
+--- git.orig/Makerules	2014-08-27 18:49:22.552070587 +0000
++++ git/Makerules	2014-08-27 18:49:27.308070587 +0000
+@@ -612,6 +631,9 @@
+ $(common-objpfx)libc.so: $(common-objpfx)libc.map
+ endif
+ common-generated += libc.so libc_pic.os
++ifndef subdir
++install-extras := soinit.o sofini.o
++endif
+ ifdef libc.so-version
+ $(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so
+ 	$(make-link)
+@@ -834,6 +856,7 @@
+ installed-libcs := $(foreach o,$(filter-out .os,$(object-suffixes-for-libc)),\
+ 			     $(inst_libdir)/$(patsubst %,$(libtype$o),\
+ 						     $(libprefix)$(libc-name)))
++installed-libcs := $(installed-libcs) $(inst_libdir)/libc_pic.a
+ install: $(installed-libcs)
+ $(installed-libcs): $(inst_libdir)/lib$(libprefix)%: lib $(+force)
+ 	$(make-target-directory)
+@@ -862,6 +885,22 @@
+ install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
+ install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
+ 
++# Install the _pic.a files for versioned libraries, and corresponding
++# .map files.
++# libpthread_pic.a breaks mklibs, so don't install it and its map.
++install-lib := $(install-lib) $(install-lib.so-versioned:%.so=%_pic.a)
++install-lib := $(filter-out libpthread_pic.a,$(install-lib))
++# Despite having a soname libhurduser and libmachuser do not use symbol
++# versioning, so don't install the corresponding .map files.
++ifeq ($(build-shared),yes)
++install-map := $(patsubst %.so,%.map,\
++			$(foreach L,$(install-lib.so-versioned),$(notdir $L)))
++install-map := $(filter-out libhurduser.map libmachuser.map libpthread.map,$(install-map))
++ifndef subdir
++install-map := $(install-map) libc.map
++endif
++endif
++
+ # For versioned libraries, we install three files:
+ #	$(inst_libdir)/libfoo.so	-- for linking, symlink or ld script
+ #	$(inst_slibdir)/libfoo.so.NN	-- for loading by SONAME, symlink
+@@ -1103,9 +1142,22 @@
+ endif	# headers-nonh
+ endif	# headers
+ 
++ifdef install-map
++$(addprefix $(inst_libdir)/,$(patsubst lib%.map,lib%_pic.map,$(install-map))): \
++  $(inst_libdir)/lib%_pic.map: $(common-objpfx)lib%.map $(+force)
++	$(do-install)
++endif
++
++ifdef install-extras
++$(addprefix $(inst_libdir)/libc_pic/,$(install-extras)): \
++  $(inst_libdir)/libc_pic/%.o: $(elfobjdir)/%.os $(+force)
++	$(do-install)
++endif
++
+ .PHONY: install-bin-nosubdir install-bin-script-nosubdir \
+ 	install-rootsbin-nosubdir install-sbin-nosubdir install-lib-nosubdir \
+-	install-data-nosubdir install-headers-nosubdir
++	install-data-nosubdir install-headers-nosubdir install-map-nosubdir \
++	install-extras-nosubdir
+ install-bin-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin))
+ install-bin-script-nosubdir: $(addprefix $(inst_bindir)/,$(install-bin-script))
+ install-rootsbin-nosubdir: \
+@@ -1118,6 +1170,10 @@
+ install-headers-nosubdir: $(addprefix $(inst_includedir)/,$(headers))
+ install-others-nosubdir: $(install-others)
+ install-others-programs-nosubdir: $(install-others-programs)
++install-map-nosubdir: $(addprefix $(inst_libdir)/,\
++		       $(patsubst lib%.map,lib%_pic.map,$(install-map)))
++install-extras-nosubdir: $(addprefix $(inst_libdir)/libc_pic/,\
++		       $(install-extras))
+ 
+ # We need all the `-nosubdir' targets so that `install' in the parent
+ # doesn't depend on several things which each iterate over the subdirs.
+@@ -1127,7 +1183,8 @@
+ 
+ .PHONY: install install-no-libc.a-nosubdir
+ install-no-libc.a-nosubdir: install-headers-nosubdir install-data-nosubdir \
+-			    install-lib-nosubdir install-others-nosubdir
++			    install-lib-nosubdir install-others-nosubdir \
++			    install-map-nosubdir install-extras-nosubdir
+ ifeq ($(build-programs),yes)
+ install-no-libc.a-nosubdir: install-bin-nosubdir install-bin-script-nosubdir \
+ 			    install-rootsbin-nosubdir install-sbin-nosubdir \
diff --git a/recipes-core/glibc/glibc/eglibc-ppc8xx-cache-line-workaround.patch b/recipes-core/glibc/glibc/eglibc-ppc8xx-cache-line-workaround.patch
new file mode 100644
index 0000000..bb83d6d
--- /dev/null
+++ b/recipes-core/glibc/glibc/eglibc-ppc8xx-cache-line-workaround.patch
@@ -0,0 +1,68 @@
+2007-06-13  Nathan Sidwell  <nathan@codesourcery.com>
+            Mark Shinwell  <shinwell@codesourcery.com>
+
+        * sysdeps/unix/sysv/linux/powerpc/libc-start.c
+        (__libc_start_main): Detect 8xx parts and clear
+        __cache_line_size if detected.
+        * sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
+        (DL_PLATFORM_AUXV): Likewise.
+
+Upstream-Status: Pending
+
+Index: git/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
+===================================================================
+--- git.orig/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c	2014-08-27 18:49:23.996070587 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c	2014-08-27 18:49:27.332070587 +0000
+@@ -24,9 +24,21 @@
+ /* Scan the Aux Vector for the "Data Cache Block Size" entry.  If found
+    verify that the static extern __cache_line_size is defined by checking
+    for not NULL.  If it is defined then assign the cache block size
+-   value to __cache_line_size.  */
++   value to __cache_line_size.  This is used by memset to
++   optimize setting to zero.  We have to detect 8xx processors, which
++   have buggy dcbz implementations that cannot report page faults
++   correctly.  That requires reading SPR, which is a privileged
++   operation.  Fortunately 2.2.18 and later emulates PowerPC mfspr
++   reads from the PVR register.   */
+ #define DL_PLATFORM_AUXV						      \
+       case AT_DCACHEBSIZE:						      \
++	if (__LINUX_KERNEL_VERSION >= 0x020218)				      \
++	  {								      \
++	    unsigned pvr = 0;						      \
++	    asm ("mfspr %0, 287" : "=r" (pvr));				      \
++	    if ((pvr & 0xffff0000) == 0x00500000)			      \
++	      break;							      \
++	  }								      \
+ 	__cache_line_size = av->a_un.a_val;				      \
+ 	break;
+ 
+Index: git/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+===================================================================
+--- git.orig/sysdeps/unix/sysv/linux/powerpc/libc-start.c	2014-08-27 18:49:23.996070587 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/libc-start.c	2014-08-27 18:49:27.332070587 +0000
+@@ -68,11 +68,24 @@
+       rtld_fini = NULL;
+     }
+ 
+-  /* Initialize the __cache_line_size variable from the aux vector.  */
++  /* Initialize the __cache_line_size variable from the aux vector.
++     This is used by memset to optimize setting to zero.  We have to
++     detect 8xx processors, which have buggy dcbz implementations that
++     cannot report page faults correctly.  That requires reading SPR,
++     which is a privileged operation.  Fortunately 2.2.18 and later
++     emulates PowerPC mfspr reads from the PVR register.  */
+   for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
+     switch (av->a_type)
+       {
+       case AT_DCACHEBSIZE:
++	if (__LINUX_KERNEL_VERSION >= 0x020218)
++	  {
++	    unsigned pvr = 0;
++
++	    asm ("mfspr %0, 287" : "=r" (pvr) :);
++	    if ((pvr & 0xffff0000) == 0x00500000)
++	      break;
++	  }
+ 	__cache_line_size = av->a_un.a_val;
+ 	break;
+       }
diff --git a/recipes-core/glibc/glibc/eglibc-resolv-dynamic.patch b/recipes-core/glibc/glibc/eglibc-resolv-dynamic.patch
new file mode 100644
index 0000000..a73bceb
--- /dev/null
+++ b/recipes-core/glibc/glibc/eglibc-resolv-dynamic.patch
@@ -0,0 +1,54 @@
+cherry-picked from http://www.eglibc.org/archives/patches/msg00772.html
+
+It hasnt yet been merged into glibc
+
+Signed-off-by: Khem Raj
+
+Upstream-Status: Pending
+
+Index: git/resolv/res_libc.c
+===================================================================
+--- git.orig/resolv/res_libc.c	2014-08-27 18:35:15.492070587 +0000
++++ git/resolv/res_libc.c	2014-08-27 18:35:19.204070587 +0000
+@@ -22,12 +22,13 @@
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ #include <bits/libc-lock.h>
+-
++#include <sys/stat.h>
+ 
+ /* The following bit is copied from res_data.c (where it is #ifdef'ed
+    out) since res_init() should go into libc.so but the rest of that
+    file should not.  */
+ 
++__libc_lock_define_initialized (static, lock);
+ extern unsigned long long int __res_initstamp attribute_hidden;
+ /* We have atomic increment operations on 64-bit platforms.  */
+ #if __WORDSIZE == 64
+@@ -35,7 +36,6 @@
+ # define atomicincunlock(lock) (void) 0
+ # define atomicinc(var) catomic_increment (&(var))
+ #else
+-__libc_lock_define_initialized (static, lock);
+ # define atomicinclock(lock) __libc_lock_lock (lock)
+ # define atomicincunlock(lock) __libc_lock_unlock (lock)
+ # define atomicinc(var) ++var
+@@ -94,7 +94,18 @@
+ int
+ __res_maybe_init (res_state resp, int preinit)
+ {
++	static time_t last_mtime;
++	struct stat statbuf;
++	int ret;
++
+ 	if (resp->options & RES_INIT) {
++		ret = stat (_PATH_RESCONF, &statbuf);
++		__libc_lock_lock (lock);
++		if ((ret == 0) && (last_mtime != statbuf.st_mtime)) {
++			last_mtime = statbuf.st_mtime;
++			atomicinc (__res_initstamp);
++		}
++		__libc_lock_unlock (lock);
+ 		if (__res_initstamp != resp->_u._ext.initstamp) {
+ 			if (resp->nscount > 0)
+ 				__res_iclose (resp, true);
diff --git a/recipes-core/glibc/glibc/eglibc-sh4-fpscr_values.patch b/recipes-core/glibc/glibc/eglibc-sh4-fpscr_values.patch
new file mode 100644
index 0000000..bfb813e
--- /dev/null
+++ b/recipes-core/glibc/glibc/eglibc-sh4-fpscr_values.patch
@@ -0,0 +1,42 @@
+2010-09-29  Nobuhiro Iwamatsu  <iwamatsu@nigauri.org>
+            Andrew Stubbs  <ams@codesourcery.com>
+
+        Resolve SH's __fpscr_values to symbol in libc.so.
+
+        * sysdeps/sh/sh4/fpu/fpu_control.h: Add C++ __set_fpscr prototype.
+        * sysdeps/unix/sysv/linux/sh/Versions (GLIBC_2.2): Add __fpscr_values.
+        * sysdeps/unix/sysv/linux/sh/sysdep.S (___fpscr_values): New constant.
+
+Upstream-Status: Pending
+
+Index: git/sysdeps/unix/sysv/linux/sh/sysdep.S
+===================================================================
+--- git.orig/sysdeps/unix/sysv/linux/sh/sysdep.S	2014-08-27 18:49:24.036070587 +0000
++++ git/sysdeps/unix/sysv/linux/sh/sysdep.S	2014-08-27 18:49:27.332070587 +0000
+@@ -30,3 +30,14 @@
+ 
+ #define __syscall_error __syscall_error_1
+ #include <sysdeps/unix/sh/sysdep.S>
++
++       .data
++       .align 3
++       .globl ___fpscr_values
++       .type ___fpscr_values, @object
++       .size ___fpscr_values, 8
++___fpscr_values:
++       .long 0
++       .long 0x80000
++weak_alias (___fpscr_values, __fpscr_values)
++
+Index: git/sysdeps/unix/sysv/linux/sh/Versions
+===================================================================
+--- git.orig/sysdeps/unix/sysv/linux/sh/Versions	2014-08-27 18:49:24.028070587 +0000
++++ git/sysdeps/unix/sysv/linux/sh/Versions	2014-08-27 18:49:27.332070587 +0000
+@@ -2,6 +2,7 @@
+   GLIBC_2.2 {
+     # functions used in other libraries
+     __xstat64; __fxstat64; __lxstat64;
++    __fpscr_values;
+ 
+     # a*
+     alphasort64;
diff --git a/recipes-core/glibc/glibc/eglibc-use-option-groups.patch b/recipes-core/glibc/glibc/eglibc-use-option-groups.patch
new file mode 100644
index 0000000..7390ab6
--- /dev/null
+++ b/recipes-core/glibc/glibc/eglibc-use-option-groups.patch
@@ -0,0 +1,16546 @@
+Forward port eglibc options groups support
+
+Upstream-Status: Pending
+
+Index: git/argp/argp-fmtstream.c
+===================================================================
+--- git.orig/argp/argp-fmtstream.c	2014-08-29 20:00:42.976070587 -0700
++++ git/argp/argp-fmtstream.c	2014-08-29 20:01:15.188070587 -0700
+@@ -42,6 +42,7 @@
+ #ifdef _LIBC
+ # include <wchar.h>
+ # include <libio/libioP.h>
++# include <gnu/option-groups.h>
+ # define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
+ #endif
+ 
+@@ -100,7 +101,11 @@
+   __argp_fmtstream_update (fs);
+   if (fs->p > fs->buf)
+     {
++#ifdef _LIBC
+       __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
++#else
++      fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
++#endif
+     }
+   free (fs->buf);
+   free (fs);
+@@ -145,9 +150,17 @@
+ 	      size_t i;
+ 	      for (i = 0; i < pad; i++)
+ 		{
++#ifdef _LIBC
+ 		  if (_IO_fwide (fs->stream, 0) > 0)
+-		    putwc_unlocked (L' ', fs->stream);
++                    {
++#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++                      putwc_unlocked (L' ', fs->stream);
++#else
++                      abort ();
++#endif
++                    }
+ 		  else
++#endif
+ 		    putc_unlocked (' ', fs->stream);
+ 		}
+ 	    }
+@@ -308,9 +321,17 @@
+ 	      *nl++ = ' ';
+ 	  else
+ 	    for (i = 0; i < fs->wmargin; ++i)
++#ifdef _LIBC
+ 	      if (_IO_fwide (fs->stream, 0) > 0)
+-		putwc_unlocked (L' ', fs->stream);
++                {
++#ifdef OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++                  putwc_unlocked (L' ', fs->stream);
++#else
++                  abort ();
++#endif
++                }
+ 	      else
++#endif
+ 		putc_unlocked (' ', fs->stream);
+ 
+ 	  /* Copy the tail of the original buffer into the current buffer
+Index: git/argp/argp-help.c
+===================================================================
+--- git.orig/argp/argp-help.c	2014-08-29 20:00:42.976070587 -0700
++++ git/argp/argp-help.c	2014-08-29 20:01:15.188070587 -0700
+@@ -51,6 +51,7 @@
+ #ifdef _LIBC
+ # include <../libio/libioP.h>
+ # include <wchar.h>
++# include <gnu/option-groups.h>
+ #endif
+ 
+ #ifndef _
+@@ -1702,7 +1703,7 @@
+ }
+ 
+ char *
+-__argp_short_program_name (void)
++(__argp_short_program_name) (void)
+ {
+ # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+   return program_invocation_short_name;
+@@ -1873,9 +1874,17 @@
+ #endif
+ 	    }
+ 
++#ifdef _LIBC
+ 	  if (_IO_fwide (stream, 0) > 0)
+-	    putwc_unlocked (L'\n', stream);
++            {
++#if ! _LIBC || __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++              putwc_unlocked (L'\n', stream);
++#else
++              abort ();
++#endif
++            }
+ 	  else
++#endif
+ 	    putc_unlocked ('\n', stream);
+ 
+ #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+Index: git/argp/argp-namefrob.h
+===================================================================
+--- git.orig/argp/argp-namefrob.h	2014-08-29 20:00:42.976070587 -0700
++++ git/argp/argp-namefrob.h	2014-08-29 20:01:15.192070587 -0700
+@@ -76,10 +76,12 @@
+ #undef __argp_fmtstream_wmargin
+ #define __argp_fmtstream_wmargin argp_fmtstream_wmargin
+ 
++#if 0
+ #include "mempcpy.h"
+ #include "strcase.h"
+ #include "strchrnul.h"
+ #include "strndup.h"
++#endif
+ 
+ /* normal libc functions we call */
+ #undef __flockfile
+Index: git/argp/Makefile
+===================================================================
+--- git.orig/argp/Makefile	2014-08-29 20:00:42.976070587 -0700
++++ git/argp/Makefile	2014-08-29 20:01:15.192070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for argp.
+ #
++include ../option-groups.mak
++
+ subdir	:= argp
+ 
+ include ../Makeconfig
+Index: git/catgets/Makefile
+===================================================================
+--- git.orig/catgets/Makefile	2014-08-29 20:00:43.008070587 -0700
++++ git/catgets/Makefile	2014-08-29 20:01:15.192070587 -0700
+@@ -22,20 +22,23 @@
+ 
+ include ../Makeconfig
+ 
++include ../option-groups.mak
++
+ headers		= nl_types.h
+-routines	= catgets open_catalog
+-others		= gencat
+-install-bin	= gencat
+-extra-objs	= $(gencat-modules:=.o)
++routines-$(OPTION_EGLIBC_CATGETS)    := catgets open_catalog
++others-$(OPTION_EGLIBC_CATGETS)      := gencat
++install-bin-$(OPTION_EGLIBC_CATGETS) := gencat
++extra-objs-$(OPTION_EGLIBC_CATGETS)  := $(gencat-modules:=.o)
+ 
+-tests = tst-catgets
+-test-srcs = test-gencat
++tests-$(OPTION_EGLIBC_CATGETS)       := tst-catgets
++test-srcs-$(OPTION_EGLIBC_CATGETS)   := test-gencat
+ 
++ifeq (y,$(OPTION_EGLIBC_CATGETS))
+ ifeq ($(run-built-tests),yes)
+ tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
+ 		 $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out
+ endif
+-
++endif
+ gencat-modules	= xmalloc
+ 
+ # To find xmalloc.c
+Index: git/crypt/crypt-entry.c
+===================================================================
+--- git.orig/crypt/crypt-entry.c	2014-08-29 20:00:43.028070587 -0700
++++ git/crypt/crypt-entry.c	2014-08-29 20:01:15.192070587 -0700
+@@ -27,6 +27,7 @@
+ #include <stdio.h>
+ #endif
+ #include <string.h>
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <fips-private.h>
+ 
+@@ -76,9 +77,11 @@
+      const char *salt;
+      struct crypt_data * __restrict data;
+ {
++#if __OPTION_EGLIBC_CRYPT_UFC
+   ufc_long res[4];
+   char ktab[9];
+   ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
++#endif /*__OPTION_EGLIBC_CRYPT_UFC*/
+ 
+ #ifdef _LIBC
+   /* Try to find out whether we have to use MD5 encryption replacement.  */
+@@ -105,6 +108,7 @@
+ 			     sizeof (struct crypt_data));
+ #endif
+ 
++#if __OPTION_EGLIBC_CRYPT_UFC
+   /*
+    * Hack DES tables according to salt
+    */
+@@ -144,6 +148,10 @@
+    */
+   _ufc_output_conversion_r (res[0], res[1], salt, data);
+   return data->crypt_3_buf;
++#else /* __OPTION_EGLIBC_CRYPT_UFC */
++  __set_errno (ENOSYS);
++  return NULL;
++#endif /* __OPTION_EGLIBC_CRYPT_UFC */
+ }
+ weak_alias (__crypt_r, crypt_r)
+ 
+@@ -168,7 +176,12 @@
+     return __sha512_crypt (key, salt);
+ #endif
+ 
++#if __OPTION_EGLIBC_CRYPT_UFC
+   return __crypt_r (key, salt, &_ufc_foobar);
++#else /* __OPTION_EGLIBC_CRYPT_UFC */
++  __set_errno (ENOSYS);
++  return NULL;
++#endif /* __OPTION_EGLIBC_CRYPT_UFC */
+ }
+ 
+ 
+Index: git/crypt/Makefile
+===================================================================
+--- git.orig/crypt/Makefile	2014-08-29 20:00:43.024070587 -0700
++++ git/crypt/Makefile	2014-08-29 20:01:15.192070587 -0700
+@@ -18,21 +18,25 @@
+ #
+ #	Sub-makefile for crypt() portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= crypt
+ 
+ include ../Makeconfig
+ 
+ headers := crypt.h
+ 
+-extra-libs := libcrypt
+-extra-libs-others := $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_CRYPT) := libcrypt
++extra-libs-others-y := $(extra-libs-y)
+ 
+-libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
+-		     crypt_util
++libcrypt-routines :=crypt-entry  md5-crypt sha256-crypt sha512-crypt crypt_common
++libcrypt-routines-$(OPTION_EGLIBC_CRYPT_UFC) := crypt crypt_util
++libcrypt-routines += $(libcrypt-routines-y)
+ 
+-tests := cert md5c-test sha256c-test sha512c-test badsalttest
++tests-$(OPTION_EGLIBC_CRYPT) := md5c-test sha256c-test sha512c-test badsalttest
++tests-$(OPTION_EGLIBC_CRYPT_UFC) += cert
+ 
+-ifeq ($(crypt-in-libc),yes)
++ifeq ($(crypt-in-libc)$(OPTION_EGLIBC_CRYPT),yesy)
+ routines += $(libcrypt-routines)
+ endif
+ 
+@@ -44,7 +48,7 @@
+ else
+ libcrypt-routines += md5 sha256 sha512
+ 
+-tests += md5test sha256test sha512test
++tests-$(OPTION_EGLIBC_CRYPT) += md5test sha256test sha512test
+ 
+ # The test md5test-giant uses up to 400 MB of RSS and runs on a fast
+ # machine over a minute.
+@@ -64,8 +68,10 @@
+ $(objpfx)sha512test: $(patsubst %, $(objpfx)%.o,$(sha512-routines))
+ endif
+ 
++ifeq ($(OPTION_EGLIBC_CRYPT),y)
+ ifeq (yes,$(build-shared))
+ $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.so
+ else
+ $(addprefix $(objpfx),$(tests)): $(objpfx)libcrypt.a
+ endif
++endif # eglibc: OPTION_EGLIBC_CRYPT
+Index: git/csu/Makefile
+===================================================================
+--- git.orig/csu/Makefile	2014-08-29 20:00:43.032070587 -0700
++++ git/csu/Makefile	2014-08-29 20:01:15.192070587 -0700
+@@ -22,6 +22,8 @@
+ # crtn.o, special "initializer" and "finalizer" files used in the link
+ # to make the .init and .fini sections work right.
+ 
++include ../option-groups.mak
++
+ subdir := csu
+ 
+ include ../Makeconfig
+Index: git/debug/Makefile
+===================================================================
+--- git.orig/debug/Makefile	2014-08-29 20:00:43.036070587 -0700
++++ git/debug/Makefile	2014-08-29 20:01:15.192070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for debug portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= debug
+ 
+ include ../Makeconfig
+@@ -27,7 +29,7 @@
+ # Note that ptsname_r_chk and getlogin_r are not here, but in
+ # login/Makefile instead.  If that subdir is omitted from the
+ # build, its _FORTIFY_SOURCE support will be too.
+-routines  = backtrace backtracesyms backtracesymsfd noophooks \
++routines  = noophooks \
+ 	    memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk \
+ 	    strcat_chk strcpy_chk strncat_chk strncpy_chk stpncpy_chk \
+ 	    sprintf_chk vsprintf_chk snprintf_chk vsnprintf_chk \
+@@ -36,20 +38,27 @@
+ 	    read_chk pread_chk pread64_chk recv_chk recvfrom_chk \
+ 	    readlink_chk readlinkat_chk getwd_chk getcwd_chk \
+ 	    realpath_chk fread_chk fread_u_chk \
+-	    wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \
+-	    wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \
+-	    wcpncpy_chk \
+-	    swprintf_chk vswprintf_chk wprintf_chk fwprintf_chk \
+-	    vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk \
+ 	    confstr_chk getgroups_chk ttyname_r_chk \
+-	    gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \
+-	    wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \
+-	    wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \
++	    gethostname_chk getdomainname_chk \
++	    asprintf_chk vasprintf_chk dprintf_chk \
+ 	    vdprintf_chk obprintf_chk \
+ 	    longjmp_chk ____longjmp_chk \
+ 	    fdelt_chk poll_chk ppoll_chk \
+ 	    stack_chk_fail fortify_fail \
+ 	    $(static-only-routines)
++routines-$(OPTION_EGLIBC_BACKTRACE) += backtrace backtracesyms backtracesymsfd
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)			\
++	 += wprintf_chk fwprintf_chk				\
++	    vwprintf_chk vfwprintf_chk fgetws_chk fgetws_u_chk
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR)				\
++	 += wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk	\
++	    wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk	\
++	    wcpncpy_chk							\
++	    swprintf_chk vswprintf_chk					\
++	    wcrtomb_chk mbsnrtowcs_chk					\
++	    wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk	\
++	    wcstombs_chk
++
+ static-only-routines := warning-nop stack_chk_fail_local
+ 
+ CFLAGS-backtrace.c = -fno-omit-frame-pointer
+@@ -129,11 +138,15 @@
+ LDFLAGS-tst-backtrace5 = -rdynamic
+ LDFLAGS-tst-backtrace6 = -rdynamic
+ 
+-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
+-	tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
+-	tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
+-	tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
+-	tst-backtrace5 tst-backtrace6
++tests = tst-longjmp_chk test-strcpy_chk test-stpcpy_chk tst-longjmp_chk2
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++      += tst-chk1 tst-chk2 tst-chk3 tst-lfschk1 tst-lfschk2 tst-lfschk3
++tests-$(OPTION_EGLIBC_BACKTRACE) \
++      += backtrace-tst tst-backtrace2 tst-backtrace3 tst-backtrace4 \
++         tst-backtrace5 tst-backtrace6
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_EGLIBC_CXX_TESTS))
++tests += tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6
++endif
+ 
+ tests-ifunc := $(stpcpy_chk strcpy_chk:%=test-%-ifunc)
+ tests += $(tests-ifunc)
+Index: git/debug/segfault.c
+===================================================================
+--- git.orig/debug/segfault.c	2014-08-29 20:00:46.280070587 -0700
++++ git/debug/segfault.c	2014-08-29 20:01:15.192070587 -0700
+@@ -30,6 +30,7 @@
+ #include <unistd.h>
+ #include <_itoa.h>
+ #include <ldsodefs.h>
++#include <gnu/option-groups.h>
+ 
+ /* This file defines macros to access the content of the sigcontext element
+    passed up by the signal handler.  */
+@@ -91,6 +92,7 @@
+   REGISTER_DUMP;
+ #endif
+ 
++#if __OPTION_EGLIBC_BACKTRACE
+   WRITE_STRING ("\nBacktrace:\n");
+ 
+   /* Get the backtrace.  */
+@@ -113,6 +115,7 @@
+ 
+   /* Now generate nicely formatted output.  */
+   __backtrace_symbols_fd (arr + i, cnt - i, fd);
++#endif
+ 
+ #ifdef HAVE_PROC_SELF
+   /* Now the link map.  */
+Index: git/debug/tst-chk1.c
+===================================================================
+--- git.orig/debug/tst-chk1.c	2014-08-29 20:00:46.288070587 -0700
++++ git/debug/tst-chk1.c	2014-08-29 20:01:15.192070587 -0700
+@@ -31,6 +31,7 @@
+ #include <sys/select.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ #define obstack_chunk_alloc malloc
+@@ -307,6 +308,7 @@
+   snprintf (buf + 8, l0 + 3, "%d", num2);
+   CHK_FAIL_END
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   CHK_FAIL_START
+   swprintf (wbuf + 8, 3, L"%d", num1);
+   CHK_FAIL_END
+@@ -314,6 +316,7 @@
+   CHK_FAIL_START
+   swprintf (wbuf + 8, l0 + 3, L"%d", num1);
+   CHK_FAIL_END
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ # endif
+ 
+   memcpy (buf, str1 + 2, l0 + 9);
+@@ -381,6 +384,7 @@
+   CHK_FAIL_END
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+ 
+   /* These ops can be done without runtime checking of object size.  */
+   wmemcpy (wbuf, L"abcdefghij", 10);
+@@ -605,6 +609,7 @@
+   CHK_FAIL_END
+ #endif
+ 
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   /* Now checks for %n protection.  */
+ 
+@@ -1192,6 +1197,7 @@
+ # endif
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
+     {
+       assert (MB_CUR_MAX <= 10);
+@@ -1348,6 +1354,7 @@
+       puts ("cannot set locale");
+       ret = 1;
+     }
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   int fd = posix_openpt (O_RDWR);
+   if (fd != -1)
+Index: git/dlfcn/Makefile
+===================================================================
+--- git.orig/dlfcn/Makefile	2014-08-29 20:00:46.312070587 -0700
++++ git/dlfcn/Makefile	2014-08-29 20:01:15.192070587 -0700
+@@ -15,6 +15,8 @@
+ # License along with the GNU C Library; if not, see
+ # <http://www.gnu.org/licenses/>.
+ 
++include ../option-groups.mak
++
+ subdir		:= dlfcn
+ 
+ include ../Makeconfig
+@@ -36,7 +38,9 @@
+ ifeq (yes,$(build-shared))
+ tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
+ 	bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
+-	bug-atexit3 tstatexit bug-dl-leaf
++	tstatexit bug-dl-leaf
++
++tests-$(OPTION_EGLIBC_CXX_TESTS) += bug-atexit3
+ endif
+ modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
+ 		defaultmod2 errmsg1mod modatexit modcxaatexit \
+Index: git/elf/dl-support.c
+===================================================================
+--- git.orig/elf/dl-support.c	2014-08-29 20:00:46.384070587 -0700
++++ git/elf/dl-support.c	2014-08-29 20:01:15.192070587 -0700
+@@ -19,6 +19,7 @@
+ /* This file defines some things that for the dynamic linker are defined in
+    rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */
+ 
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <libintl.h>
+ #include <stdlib.h>
+@@ -42,7 +43,9 @@
+ const char *_dl_platform;
+ size_t _dl_platformlen;
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ int _dl_debug_mask;
++#endif
+ int _dl_lazy;
+ ElfW(Addr) _dl_use_load_bias = -2;
+ int _dl_dynamic_weak;
+Index: git/elf/rtld.c
+===================================================================
+--- git.orig/elf/rtld.c	2014-08-29 20:01:14.708070587 -0700
++++ git/elf/rtld.c	2014-08-29 20:01:15.196070587 -0700
+@@ -16,6 +16,7 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
+ #include <errno.h>
+ #include <dlfcn.h>
+ #include <fcntl.h>
+@@ -2200,6 +2201,7 @@
+ 		    objname, errstring);
+ }
+ \f
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ /* Nonzero if any of the debugging options is enabled.  */
+ static int any_debug attribute_relro;
+ 
+@@ -2309,6 +2311,7 @@
+       _exit (0);
+     }
+ }
++#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
+ \f
+ static void
+ process_dl_audit (char *str)
+@@ -2376,12 +2379,14 @@
+ 	  break;
+ 
+ 	case 5:
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	  /* Debugging of the dynamic linker?  */
+ 	  if (memcmp (envline, "DEBUG", 5) == 0)
+ 	    {
+ 	      process_dl_debug (&envline[6]);
+ 	      break;
+ 	    }
++#endif
+ 	  if (memcmp (envline, "AUDIT", 5) == 0)
+ 	    process_dl_audit (&envline[6]);
+ 	  break;
+@@ -2490,7 +2495,9 @@
+ 	    {
+ 	      mode = trace;
+ 	      GLRO(dl_verbose) = 1;
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	      GLRO_dl_debug_mask |= DL_DEBUG_PRELINK;
++#endif
+ 	      GLRO(dl_trace_prelink) = &envline[17];
+ 	    }
+ 	  break;
+@@ -2537,12 +2544,15 @@
+       if (__access ("/etc/suid-debug", F_OK) != 0)
+ 	{
+ 	  unsetenv ("MALLOC_CHECK_");
++#if __OPTION_EGLIBC_RTLD_DEBUG
+ 	  GLRO_dl_debug_mask = 0;
++#endif
+ 	}
+ 
+       if (mode != normal)
+ 	_exit (5);
+     }
++#if __OPTION_EGLIBC_RTLD_DEBUG
+   /* If we have to run the dynamic linker in debugging mode and the
+      LD_DEBUG_OUTPUT environment variable is given, we write the debug
+      messages to this file.  */
+@@ -2567,6 +2577,7 @@
+ 	/* We use standard output if opening the file failed.  */
+ 	GLRO(dl_debug_fd) = STDOUT_FILENO;
+     }
++#endif /* __OPTION_EGLIBC_RTLD_DEBUG */
+ }
+ 
+ 
+Index: git/extra-lib.mk
+===================================================================
+--- git.orig/extra-lib.mk	2014-08-29 20:00:46.544070587 -0700
++++ git/extra-lib.mk	2014-08-29 20:01:15.196070587 -0700
+@@ -25,7 +25,9 @@
+ extra-objs := $(extra-objs)
+ 
+ # The modules that go in $(lib).
+-all-$(lib)-routines := $($(lib)-routines) $($(lib)-sysdep_routines)
++all-$(lib)-routines := $($(lib)-routines)		\
++	               $($(lib)-routines-y)		\
++		       $($(lib)-sysdep_routines)
+ 
+ # Add each flavor of library to the lists of things to build and install.
+ install-lib += $(foreach o,$(object-suffixes-$(lib)),$(lib:lib%=$(libtype$o)))
+@@ -101,7 +103,7 @@
+ endif
+ 
+ # This will define `libof-ROUTINE := LIB' for each of the routines.
+-cpp-srcs-left := $($(lib)-routines) $($(lib)-sysdep_routines)
++cpp-srcs-left := $(all-$(lib)-routines)
+ ifneq (,$(cpp-srcs-left))
+ include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
+ endif
+Index: git/grp/Makefile
+===================================================================
+--- git.orig/grp/Makefile	2014-08-29 20:00:46.556070587 -0700
++++ git/grp/Makefile	2014-08-29 20:01:15.196070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for grp portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= grp
+ 
+ include ../Makeconfig
+@@ -29,6 +31,9 @@
+ 	    getgrent_r getgrgid_r getgrnam_r fgetgrent_r
+ 
+ tests := testgrp
++ifneq (y,$(OPTION_EGLIBC_NSSWITCH))
++LDLIBS-testgrp += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
++endif
+ 
+ ifeq (yes,$(build-shared))
+ test-srcs :=  tst_fgetgrent
+Index: git/hesiod/Makefile
+===================================================================
+--- git.orig/hesiod/Makefile	2014-08-29 20:00:46.580070587 -0700
++++ git/hesiod/Makefile	2014-08-29 20:01:15.196070587 -0700
+@@ -18,12 +18,14 @@
+ #
+ #	Sub-makefile for hesiod portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= hesiod
+ 
+ include ../Makeconfig
+ 
+-extra-libs := libnss_hesiod
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_INET) += libnss_hesiod
++extra-libs-others-y += $(extra-libs-y)
+ 
+ subdir-dirs = nss_hesiod
+ vpath %.c nss_hesiod
+Index: git/iconv/gconv_db.c
+===================================================================
+--- git.orig/iconv/gconv_db.c	2014-08-29 20:00:46.604070587 -0700
++++ git/iconv/gconv_db.c	2014-08-29 20:01:15.196070587 -0700
+@@ -25,6 +25,7 @@
+ #include <sys/param.h>
+ #include <bits/libc-lock.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ 
+ #include <dlfcn.h>
+ #include <gconv_int.h>
+@@ -828,9 +829,11 @@
+ /* Free all resources if necessary.  */
+ libc_freeres_fn (free_mem)
+ {
++#if __OPTION_EGLIBC_LOCALE_CODE
+   /* First free locale memory.  This needs to be done before freeing derivations,
+      as ctype cleanup functions dereference steps arrays which we free below.  */
+   _nl_locale_subfreeres ();
++#endif
+ 
+   /* finddomain.c has similar problem.  */
+   extern void _nl_finddomain_subfreeres (void) attribute_hidden;
+Index: git/iconv/gconv_trans.c
+===================================================================
+--- git.orig/iconv/gconv_trans.c	2014-08-29 20:00:46.612070587 -0700
++++ git/iconv/gconv_trans.c	2014-08-29 20:01:15.196070587 -0700
+@@ -23,6 +23,7 @@
+ #include <stdint.h>
+ #include <string.h>
+ #include <stdlib.h>
++#include <gnu/option-groups.h>
+ 
+ #include <bits/libc-lock.h>
+ #include "gconv_int.h"
+@@ -59,6 +60,7 @@
+     PTR_DEMANGLE (fct);
+ #endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   /* If there is no transliteration information in the locale don't do
+      anything and return the error.  */
+   size = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_TAB_SIZE);
+@@ -194,6 +196,7 @@
+              sorted.  */
+ 	  break;
+     }
++#endif
+ 
+   /* One last chance: use the default replacement.  */
+   if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN) != 0)
+Index: git/iconv/iconv_prog.c
+===================================================================
+--- git.orig/iconv/iconv_prog.c	2014-08-29 20:00:46.612070587 -0700
++++ git/iconv/iconv_prog.c	2014-08-29 20:01:15.196070587 -0700
+@@ -35,6 +35,7 @@
+ #ifdef _POSIX_MAPPED_FILES
+ # include <sys/mman.h>
+ #endif
++#include <gnu/option-groups.h>
+ #include <charmap.h>
+ #include <gconv_int.h>
+ #include "iconv_prog.h"
+@@ -221,10 +222,17 @@
+ 	      bool to_wrong =
+ 		(iconv_open (to_code, "UTF-8") == (iconv_t) -1
+ 		 && errno == EINVAL);
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	      const char *from_pretty =
+ 		(from_code[0] ? from_code : nl_langinfo (CODESET));
+ 	      const char *to_pretty =
+ 		(orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET));
++#else
++	      const char *from_pretty =
++		(from_code[0] ? from_code : "ANSI_X3.4-1968");
++	      const char *to_pretty =
++                 (orig_to_code[0] ? orig_to_code : "ANSI_X3.4-1968");
++#endif
+ 
+ 	      if (from_wrong)
+ 		{
+Index: git/iconv/Makefile
+===================================================================
+--- git.orig/iconv/Makefile	2014-08-29 20:00:46.600070587 -0700
++++ git/iconv/Makefile	2014-08-29 20:01:15.196070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for iconv.
+ #
++include ../option-groups.mak
++
+ subdir	:= iconv
+ 
+ include ../Makeconfig
+@@ -57,6 +59,9 @@
+ CPPFLAGS-strtab = -DNOT_IN_libc
+ CPPFLAGS-charmap = -DNOT_IN_libc
+ CPPFLAGS-charmap-dir = -DNOT_IN_libc
++ifneq (y,$(OPTION_EGLIBC_SPAWN))
++CPPFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
++endif
+ 
+ ifeq ($(run-built-tests),yes)
+ xtests-special += $(objpfx)test-iconvconfig.out
+Index: git/iconvdata/Makefile
+===================================================================
+--- git.orig/iconvdata/Makefile	2014-08-29 20:00:46.628070587 -0700
++++ git/iconvdata/Makefile	2014-08-29 20:01:15.196070587 -0700
+@@ -18,12 +18,15 @@
+ #
+ #	Makefile for iconv data and code.
+ #
++include ../option-groups.mak
++
+ subdir	:= iconvdata
+ 
+ include ../Makeconfig
+ 
+ # Names of all the shared objects which implement the transformations.
+-modules	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
++modules-$(OPTION_EGLIBC_CHARSETS)					 \
++	:= ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5		 \
+ 	   ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10		 \
+ 	   ISO8859-11 ISO8859-13 ISO8859-14 ISO8859-15 ISO8859-16	 \
+ 	   T.61 ISO_6937 SJIS KOI-8 HP-ROMAN8 HP-ROMAN9 EBCDIC-AT-DE	 \
+@@ -63,11 +66,13 @@
+ 	   MAC-CENTRALEUROPE KOI8-RU ISO8859-9E				 \
+ 	   CP770 CP771 CP772 CP773 CP774
+ 
+-modules.so := $(addsuffix .so, $(modules))
++modules.so := $(addsuffix .so, $(modules-y))
+ 
+ ifeq (yes,$(build-shared))
+ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
+-	tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9
++	tst-iconv6 bug-iconv5 bug-iconv8 bug-iconv9
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += bug-iconv6 tst-iconv7
++
+ ifeq ($(have-thread-library),yes)
+ tests += bug-iconv3
+ endif
+@@ -130,13 +135,13 @@
+ # Rule to generate the shared objects.
+ charmaps = ../localedata/charmaps
+ -include $(objpfx)iconv-rules
+-extra-modules-left := $(modules)
++extra-modules-left := $(modules-y)
+ include extra-module.mk
+ 
+ 
+ extra-objs	+= $(modules.so)
+-install-others	= $(addprefix $(inst_gconvdir)/, $(modules.so))	\
+-		  $(inst_gconvdir)/gconv-modules
++install-others-y += $(addprefix $(inst_gconvdir)/, $(modules.so))
++install-others-$(OPTION_EGLIBC_CHARSETS) += $(inst_gconvdir)/gconv-modules
+ 
+ # We can build the conversion tables for numerous charsets automatically.
+ 
+@@ -204,7 +209,7 @@
+ ifndef avoid-generated
+ $(objpfx)iconv-rules: Makefile
+ 	$(make-target-directory)
+-	{ echo $(filter-out lib%, $(modules)); \
++	{ echo $(filter-out lib%, $(modules-y)); \
+ 	  echo 8bit $(gen-8bit-modules); \
+ 	  echo 8bit-gap $(gen-8bit-gap-modules); } | \
+ 	LC_ALL=C \
+@@ -247,7 +252,7 @@
+ 	$(do-install-program)
+ $(inst_gconvdir)/gconv-modules: gconv-modules $(+force)
+ 	$(do-install)
+-ifeq (no,$(cross-compiling))
++# eglibc: ifeq (no,$(cross-compiling))
+ # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary
+ # if this libc has more gconv modules than the previously installed one.
+ 	if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \
+@@ -256,9 +261,9 @@
+ 	   $(common-objpfx)iconv/iconvconfig \
+ 	     $(addprefix --prefix=,$(install_root)); \
+ 	fi
+-else
+-	@echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
+-endif
++# eglibc: else
++# eglibc:	@echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache'
++# eglibc: endif
+ 
+ endif # build-shared = yes
+ 
+Index: git/include/netdb.h
+===================================================================
+--- git.orig/include/netdb.h	2014-08-29 20:00:47.152070587 -0700
++++ git/include/netdb.h	2014-08-29 20:01:15.196070587 -0700
+@@ -232,6 +232,10 @@
+ 		       (const char *name, int af, struct hostent *host,	      \
+ 			char *buffer, size_t buflen, int *errnop,	      \
+ 			int *h_errnop);					      \
++extern enum nss_status _nss_ ## service ## _gethostbyname3_r		      \
++		       (const char *name, int af, struct hostent *result,     \
++			char *buffer, size_t buflen, int *errnop,	      \
++			int *h_errnop, int32_t *ttlp, char **canonp);         \
+ extern enum nss_status _nss_ ## service ## _gethostbyname_r		      \
+ 		       (const char *name, struct hostent *host, char *buffer, \
+ 			size_t buflen, int *errnop, int *h_errnop);	      \
+Index: git/inet/Makefile
+===================================================================
+--- git.orig/inet/Makefile	2014-08-29 20:00:47.176070587 -0700
++++ git/inet/Makefile	2014-08-29 20:01:15.200070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for inet portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= inet
+ 
+ include ../Makeconfig
+@@ -27,7 +29,8 @@
+ 	   netinet/tcp.h netinet/ip.h $(wildcard arpa/*.h protocols/*.h) \
+ 	   aliases.h ifaddrs.h netinet/ip6.h netinet/icmp6.h bits/in.h
+ 
+-routines := htonl htons		\
++routines-$(OPTION_EGLIBC_INET) \
++	 += htonl htons \
+ 	    inet_lnaof inet_mkadr	\
+ 	    inet_netof inet_ntoa inet_net herrno herrno-loc \
+ 	    gethstbyad gethstbyad_r gethstbynm gethstbynm2 gethstbynm2_r \
+@@ -41,18 +44,23 @@
+ 	    getrpcent_r getrpcbyname_r getrpcbynumber_r \
+ 	    ether_aton ether_aton_r ether_hton ether_line \
+ 	    ether_ntoa ether_ntoa_r ether_ntoh \
+-	    rcmd rexec ruserpass \
+ 	    getnetgrent_r getnetgrent \
+-	    getaliasent_r getaliasent getaliasname getaliasname_r \
+-	    in6_addr getnameinfo if_index ifaddrs inet6_option \
++	    in6_addr getnameinfo if_index ifaddrs \
+ 	    getipv4sourcefilter setipv4sourcefilter \
+-	    getsourcefilter setsourcefilter inet6_opt inet6_rth
++	    getsourcefilter setsourcefilter
++routines-$(OPTION_EGLIBC_RCMD) \
++	 += rcmd rexec ruserpass
++routines-$(OPTION_EGLIBC_DB_ALIASES) \
++	 += getaliasent_r getaliasent getaliasname getaliasname_r
++routines-$(OPTION_EGLIBC_ADVANCED_INET6) \
++	 += inet6_option inet6_opt inet6_rth
+ 
+-aux := check_pf check_native ifreq
++aux-$(OPTION_EGLIBC_INET) += check_pf check_native ifreq
+ 
+ tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
+-	 tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
++	 tst-gethnm test-ifaddrs bug-if1 tst-ether_line \
+ 	 tst-getni1 tst-getni2 tst-inet6_rth tst-checks
++tests-$(OPTION_EGLIBC_ADVANCED_INET6) += test-inet6_opt
+ 
+ include ../Rules
+ 
+Index: git/intl/dcigettext.c
+===================================================================
+--- git.orig/intl/dcigettext.c
++++ git/intl/dcigettext.c
+@@ -100,11 +100,15 @@ extern int errno;
+ # include "libgnuintl.h"
+ #endif
+ #include "hash-string.h"
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
+ 
+ /* Handle multi-threaded applications.  */
+ #ifdef _LIBC
+ # include <bits/libc-lock.h>
+ # define gl_rwlock_define_initialized __libc_rwlock_define_initialized
++# define gl_rwlock_define __libc_rwlock_define
+ # define gl_rwlock_rdlock __libc_rwlock_rdlock
+ # define gl_rwlock_wrlock __libc_rwlock_wrlock
+ # define gl_rwlock_unlock __libc_rwlock_unlock
+@@ -523,8 +527,10 @@ DCIGETTEXT (const char *domainname, cons
+   saved_errno = errno;
+ 
+ #ifdef _LIBC
+-  __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
+-  __libc_rwlock_rdlock (__libc_setlocale_lock);
++# if __OPTION_EGLIBC_LOCALE_CODE
++  gl_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
++  gl_rwlock_rdlock (__libc_setlocale_lock);
++# endif
+ #endif
+ 
+   gl_rwlock_rdlock (_nl_state_lock);
+@@ -550,7 +556,11 @@ DCIGETTEXT (const char *domainname, cons
+ #ifdef HAVE_PER_THREAD_LOCALE
+ # ifndef IN_LIBGLOCALE
+ #  ifdef _LIBC
+-  localename = strdupa (__current_locale_name (category));
++#   if __OPTION_EGLIBC_LOCALE_CODE
++      localename = strdupa (__current_locale_name (category));
++#   else
++      localename = "C";
++#   endif
+ #  else
+   categoryname = category_to_name (category);
+ #   define CATEGORYNAME_INITIALIZED
+@@ -581,10 +591,12 @@ DCIGETTEXT (const char *domainname, cons
+       else
+ 	retval = (char *) (*foundp)->translation;
+ 
+-      gl_rwlock_unlock (_nl_state_lock);
+ # ifdef _LIBC
+-      __libc_rwlock_unlock (__libc_setlocale_lock);
++#  if __OPTION_EGLIBC_LOCALE_CODE
++      gl_rwlock_unlock (__libc_setlocale_lock);
++#  endif
+ # endif
++      gl_rwlock_unlock (_nl_state_lock);
+       __set_errno (saved_errno);
+       return retval;
+     }
+@@ -838,10 +850,13 @@ DCIGETTEXT (const char *domainname, cons
+ 	      if (plural)
+ 		retval = plural_lookup (domain, n, retval, retlen);
+ 
+-	      gl_rwlock_unlock (_nl_state_lock);
+ #ifdef _LIBC
+-	      __libc_rwlock_unlock (__libc_setlocale_lock);
++# if __OPTION_EGLIBC_LOCALE_CODE
++
++	      gl_rwlock_unlock (__libc_setlocale_lock);
++# endif
+ #endif
++	      gl_rwlock_unlock (_nl_state_lock);
+ 	      return retval;
+ 	    }
+ 	}
+@@ -850,10 +865,12 @@ DCIGETTEXT (const char *domainname, cons
+  return_untranslated:
+   /* Return the untranslated MSGID.  */
+   FREE_BLOCKS (block_list);
+-  gl_rwlock_unlock (_nl_state_lock);
+ #ifdef _LIBC
+-  __libc_rwlock_unlock (__libc_setlocale_lock);
++# if __OPTION_EGLIBC_LOCALE_CODE
++   gl_rwlock_unlock (__libc_setlocale_lock);
++# endif
+ #endif
++  gl_rwlock_unlock (_nl_state_lock);
+ #ifndef _LIBC
+   if (!ENABLE_SECURE)
+     {
+@@ -1550,7 +1567,11 @@ guess_category_value (int category, cons
+      `LC_xxx', and `LANG'.  On some systems this can be done by the
+      `setlocale' function itself.  */
+ # ifdef _LIBC
++#  if __OPTION_EGLIBC_LOCALE_CODE
+   locale = __current_locale_name (category);
++#  else
++  locale = "C";
++#  endif
+ # else
+   locale_defaulted = 0;
+ #  if HAVE_USELOCALE
+Index: git/intl/Makefile
+===================================================================
+--- git.orig/intl/Makefile	2014-08-29 20:00:47.220070587 -0700
++++ git/intl/Makefile	2014-08-29 20:01:15.200070587 -0700
+@@ -16,6 +16,7 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ # Makefile for intl subdirectory: message handling code from GNU gettext.
++include ../option-groups.mak
+ 
+ subdir = intl
+ 
+@@ -48,7 +49,7 @@
+ $(objpfx)plural.o: plural.c
+ 
+ ifeq ($(run-built-tests),yes)
+-ifeq (yes,$(build-shared))
++ifeq (yyyes,$(OPTION_EGLIBC_LOCALES)$(OPTION_EGLIBC_LOCALE_CODE)$(build-shared))
+ ifneq ($(strip $(MSGFMT)),:)
+ tests-special += $(objpfx)tst-translit.out $(objpfx)tst-gettext.out \
+ 		 $(objpfx)tst-gettext2.out $(objpfx)tst-codeset.out \
+Index: git/io/Makefile
+===================================================================
+--- git.orig/io/Makefile	2014-08-29 20:00:47.244070587 -0700
++++ git/io/Makefile	2014-08-29 20:01:15.200070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for I/O portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= io
+ 
+ include ../Makeconfig
+@@ -36,7 +38,7 @@
+ 	fxstatat fxstatat64						\
+ 	statfs fstatfs statfs64 fstatfs64				\
+ 	statvfs fstatvfs statvfs64 fstatvfs64				\
+-	umask chmod fchmod lchmod fchmodat				\
++	umask chmod fchmod fchmodat					\
+ 	mkdir mkdirat							\
+ 	open open_2 open64 open64_2 openat openat_2 openat64 openat64_2	\
+ 	read write lseek lseek64 access euidaccess faccessat		\
+@@ -49,11 +51,13 @@
+ 	ttyname ttyname_r isatty					\
+ 	link linkat symlink symlinkat readlink readlinkat		\
+ 	unlink unlinkat rmdir						\
+-	ftw ftw64 fts poll ppoll					\
++	poll ppoll							\
+ 	posix_fadvise posix_fadvise64					\
+ 	posix_fallocate posix_fallocate64				\
+ 	sendfile sendfile64 \
+ 	utimensat futimens
++routines-$(OPTION_EGLIBC_BSD) += lchmod
++routines-$(OPTION_EGLIBC_FTRAVERSE) += ftw ftw64 fts
+ 
+ aux := have_o_cloexec
+ 
+@@ -64,18 +68,22 @@
+ 		       fstatat fstatat64 mknod mknodat
+ 
+ others		:= pwd
+-test-srcs	:= ftwtest
++test-srcs-$(OPTION_EGLIBC_FTRAVERSE) := ftwtest
+ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
+-		   tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \
++		   tst-fcntl tst-statvfs \
+ 		   tst-openat tst-unlinkat tst-fstatat tst-futimesat \
+ 		   tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
+ 		   tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
+-		   tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
++		   tst-mknodat tst-mkfifoat tst-ttyname_r \
+ 		   tst-posix_fallocate
++tests-$(OPTION_EGLIBC_FTRAVERSE) += bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 \
++				    bug-ftw5
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_EGLIBC_FTRAVERSE))
+ tests-special += $(objpfx)ftwtest.out
+ endif
++endif
+ 
+ include ../Rules
+ 
+Index: git/libidn/Makefile
+===================================================================
+--- git.orig/libidn/Makefile	2014-08-29 20:00:47.316070587 -0700
++++ git/libidn/Makefile	2014-08-29 20:01:15.200070587 -0700
+@@ -16,6 +16,7 @@
+ # <http://www.gnu.org/licenses/>.
+ 
+ # Makefile for libidn subdirectory of GNU C Library.
++include ../option-groups.mak
+ 
+ subdir	:= libidn
+ 
+@@ -23,8 +24,8 @@
+ 
+ routines = idn-stub
+ 
+-extra-libs		= libcidn
+-extra-libs-others	= $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_IDN) = libcidn
++extra-libs-others-y = $(extra-libs-y)
+ 
+ libcidn-routines := punycode toutf8 nfkc stringprep rfc3454 profiles idna \
+ 		    iconvme
+Index: git/libidn/toutf8.c
+===================================================================
+--- git.orig/libidn/toutf8.c	2014-08-29 20:00:47.332070587 -0700
++++ git/libidn/toutf8.c	2014-08-29 20:01:15.200070587 -0700
+@@ -33,6 +33,11 @@
+ /* Get strlen. */
+ #include <string.h>
+ 
++/* Get __OPTION_EGLIBC_LOCALE_CODE.  */
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ /* Get iconv_string. */
+ #include "iconvme.h"
+ 
+@@ -47,7 +52,11 @@
+ #endif
+ 
+ #ifdef _LIBC
+-# define stringprep_locale_charset() nl_langinfo (CODESET)
++# if __OPTION_EGLIBC_LOCALE_CODE
++#  define stringprep_locale_charset() nl_langinfo (CODESET)
++# else
++#  define stringprep_locale_charset() "ANSI_X3.4-1968"
++# endif
+ #else
+ /**
+  * stringprep_locale_charset - return charset used in current locale
+Index: git/libio/fileops.c
+===================================================================
+--- git.orig/libio/fileops.c	2014-08-29 20:00:47.352070587 -0700
++++ git/libio/fileops.c	2014-08-29 20:01:15.200070587 -0700
+@@ -38,6 +38,7 @@
+ #include <string.h>
+ #include <errno.h>
+ #include <unistd.h>
++#include <gnu/option-groups.h>
+ #include <stdlib.h>
+ #if _LIBC
+ # include "../wcsmbs/wcsmbsload.h"
+@@ -174,7 +175,7 @@
+ 
+   /* Free buffer. */
+ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
+-  if (fp->_mode > 0)
++  if (_IO_is_wide (fp))
+     {
+       if (_IO_have_wbackup (fp))
+ 	_IO_free_wbackup_area (fp);
+@@ -359,6 +360,7 @@
+       cs = strstr (last_recognized + 1, ",ccs=");
+       if (cs != NULL)
+ 	{
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ 	  /* Yep.  Load the appropriate conversions and set the orientation
+ 	     to wide.  */
+ 	  struct gconv_fcts fcts;
+@@ -423,6 +425,12 @@
+ 
+ 	  /* Set the mode now.  */
+ 	  result->_mode = 1;
++#else
++          /* Treat this as if we couldn't find the given character set.  */
++          (void) _IO_file_close_it (fp);
++          __set_errno (EINVAL);
++          return NULL;
++#endif
+ 	}
+     }
+ 
+Index: git/libio/__fpurge.c
+===================================================================
+--- git.orig/libio/__fpurge.c	2014-08-29 20:00:47.336070587 -0700
++++ git/libio/__fpurge.c	2014-08-29 20:01:15.200070587 -0700
+@@ -21,7 +21,7 @@
+ void
+ __fpurge (FILE *fp)
+ {
+-  if (fp->_mode > 0)
++  if (_IO_is_wide (fp))
+     {
+       /* Wide-char stream.  */
+       if (_IO_in_backup (fp))
+Index: git/libio/iofwide.c
+===================================================================
+--- git.orig/libio/iofwide.c	2014-08-29 20:00:47.360070587 -0700
++++ git/libio/iofwide.c	2014-08-29 20:01:15.200070587 -0700
+@@ -26,6 +26,7 @@
+ 
+ #include <libioP.h>
+ #ifdef _LIBC
++# include <gnu/option-groups.h>
+ # include <dlfcn.h>
+ # include <wchar.h>
+ #endif
+@@ -43,6 +44,8 @@
+ #endif
+ 
+ 
++#if ! defined _LIBC || __OPTION_POSIX_C_LANG_WIDE_CHAR
++
+ /* Prototypes of libio's codecvt functions.  */
+ static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
+ 				     __mbstate_t *statep,
+@@ -513,3 +516,26 @@
+   return MB_CUR_MAX;
+ #endif
+ }
++
++#else
++/* OPTION_POSIX_C_LANG_WIDE_CHAR is disabled.  */
++
++#undef _IO_fwide
++int
++_IO_fwide (fp, mode)
++     _IO_FILE *fp;
++     int mode;
++{
++  /* Die helpfully if the user tries to create a wide stream; I
++     disbelieve that most users check the return value from
++     'fwide (fp, 1)'.  */
++  assert (mode <= 0);
++
++  /* We can only make streams byte-oriented, which is trivial.  */
++  if (mode < 0)
++    fp->_mode = -1;
++
++  return fp->_mode;
++}
++
++#endif
+Index: git/libio/ioseekoff.c
+===================================================================
+--- git.orig/libio/ioseekoff.c	2014-08-29 20:00:47.364070587 -0700
++++ git/libio/ioseekoff.c	2014-08-29 20:01:15.200070587 -0700
+@@ -60,7 +60,7 @@
+ 	  else
+ 	    abort ();
+ 	}
+-      if (_IO_fwide (fp, 0) < 0)
++      if (! _IO_is_wide (fp))
+ 	_IO_free_backup_area (fp);
+       else
+ 	_IO_free_wbackup_area (fp);
+Index: git/libio/ioseekpos.c
+===================================================================
+--- git.orig/libio/ioseekpos.c	2014-08-29 20:00:47.364070587 -0700
++++ git/libio/ioseekpos.c	2014-08-29 20:01:15.200070587 -0700
+@@ -35,7 +35,7 @@
+   /* If we have a backup buffer, get rid of it, since the __seekoff
+      callback may not know to do the right thing about it.
+      This may be over-kill, but it'll do for now. TODO */
+-  if (_IO_fwide (fp, 0) <= 0)
++  if (! _IO_is_wide (fp))
+     {
+       if (_IO_have_backup (fp))
+ 	_IO_free_backup_area (fp);
+Index: git/libio/iosetbuffer.c
+===================================================================
+--- git.orig/libio/iosetbuffer.c	2014-08-29 20:00:47.364070587 -0700
++++ git/libio/iosetbuffer.c	2014-08-29 20:01:15.204070587 -0700
+@@ -24,6 +24,8 @@
+    This exception applies to code released by its copyright holders
+    in files containing the exception.  */
+ 
++#include <gnu/option-groups.h>
++
+ #include "libioP.h"
+ 
+ void
+@@ -38,9 +40,11 @@
+   if (!buf)
+     size = 0;
+   (void) _IO_SETBUF (fp, buf, size);
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp))
+     /* We also have to set the buffer using the wide char function.  */
+     (void) _IO_WSETBUF (fp, buf, size);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+   _IO_release_lock (fp);
+ }
+ libc_hidden_def (_IO_setbuffer)
+Index: git/libio/libioP.h
+===================================================================
+--- git.orig/libio/libioP.h	2014-08-29 20:00:47.372070587 -0700
++++ git/libio/libioP.h	2014-08-29 20:01:15.204070587 -0700
+@@ -42,6 +42,10 @@
+ /*# include <comthread.h>*/
+ #endif
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #include <math_ldbl_opt.h>
+ 
+ #include "iolibio.h"
+@@ -508,8 +512,20 @@
+ 
+ 
+ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
++
++/* _IO_is_wide (fp) is roughly equivalent to '_IO_fwide (fp, 0) > 0',
++   except that when OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, it
++   expands to a constant, allowing the compiler to realize that it can
++   eliminate code that references wide stream handling functions.
++   This, in turn, allows us to omit them.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define _IO_is_wide(_f) ((_f)->_mode > 0)
++#else
++# define _IO_is_wide(_f) (0)
++#endif
++
+ # define _IO_do_flush(_f) \
+-  ((_f)->_mode <= 0							      \
++  (! _IO_is_wide (_f)                                                         \
+    ? _IO_do_write(_f, (_f)->_IO_write_base,				      \
+ 		  (_f)->_IO_write_ptr-(_f)->_IO_write_base)		      \
+    : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base,		      \
+Index: git/libio/Makefile
+===================================================================
+--- git.orig/libio/Makefile	2014-08-29 20:00:47.332070587 -0700
++++ git/libio/Makefile	2014-08-29 20:01:15.204070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Specific makefile for libio.
+ #
++include ../option-groups.mak
++
+ subdir	:= libio
+ 
+ include ../Makeconfig
+@@ -27,16 +29,13 @@
+ 
+ routines	:=							      \
+ 	filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
+-	iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc	      \
++	iofopncook iofputs iofread iofsetpos ioftell			      \
+ 	iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs	      \
+ 	ioseekoff ioseekpos iosetbuffer iosetvbuf ioungetc		      \
+ 	iovsprintf iovsscanf						      \
+ 	iofgetpos64 iofopen64 iofsetpos64				      \
+-	fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
+-	iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u	      \
+-	putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf      \
+-	wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops   \
+-	wstrops wfileops iofwide fwide wmemstream			      \
++	putchar putchar_u						      \
++	iofwide								      \
+ 									      \
+ 	clearerr feof ferror fileno fputc freopen fseek getc getchar	      \
+ 	memstream pclose putc putchar rewind setbuf setlinebuf vasprintf      \
+@@ -47,25 +46,48 @@
+ 	__fpurge __fpending __fsetlocking				      \
+ 									      \
+ 	libc_fatal fmemopen
+-
+-tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
+-	tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \
+-	tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf	      \
+-	tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof          \
+-	tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
+-	tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \
+-	tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \
+-	bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \
+-	tst-memstream1 tst-memstream2 \
+-	tst-wmemstream1 tst-wmemstream2 \
+-	bug-memstream1 bug-wmemstream1 \
+-	tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
+-	tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
+-	tst-ftell-append
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	wfiledoalloc							      \
++	iowpadn								      \
++	swprintf							      \
++	vswprintf iovswscanf swscanf wgenops				      \
++	wstrops wfileops wmemstream
++routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) +=	      \
++	wdummyfileops
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) +=				      \
++	fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
++	iofputws iofputws_u iogetwline ioungetwc putwc putwc_u		      \
++	putwchar putwchar_u fwprintf vwprintf				      \
++	wprintf wscanf fwscanf vwscanf					      \
++	fwide
++
++tests = test-fmemopen tst-ext tst-ext2				\
++	tst-mmap-setvbuf tst-atime tst-eof			\
++	tst-freopen bug-ungetc bug-fseek			\
++	tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush	\
++	tst-mmap2-eofsync tst-mmap-offend bug-fopena+		\
++	bug-ungetc2 bug-ungetc3 bug-ungetc4			\
++	tst-memstream1 tst-memstream2				\
++	bug-memstream1 tst-popen1 tst-fwrite-error              \
++	tst-ftell-active-handler tst-ftell-append
++tests-$(OPTION_EGLIBC_LOCALE_CODE)				\
++     += tst-swscanf tst-fgetws tst-setvbuf1			\
++	tst-ungetwc1 tst-ungetwc2 bug-ftell bug-ungetwc2	\
++	tst-widetext
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)		\
++     += bug-rewind bug-rewind2 bug-ungetwc1		\
++	bug-wfflush bug-wmemstream1 tst-fopenloc2	\
++	tst_getwc					\
++	tst_putwc tst_wprintf tst_wprintf2 tst_wscanf	\
++	tst-fgetwc bug-wsetpos tst-fseek tst-ftell-partial-wide
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR)			\
++     += tst_swprintf tst_swscanf			\
++	tst-sscanf					\
++	tst-wmemstream1 tst-wmemstream2
+ ifeq (yes,$(build-shared))
+ # Add test-fopenloc only if shared library is enabled since it depends on
+ # shared localedata objects.
+-tests += tst-fopenloc
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-fopenloc
+ endif
+ test-srcs = test-freopen
+ 
+@@ -164,13 +186,17 @@
+ 		       oldiofsetpos64
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
+ tests-special += $(objpfx)test-freopen.out
++endif
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ ifeq (yes,$(build-shared))
+ # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
+ # library is enabled since they depend on tst-fopenloc.out.
+ tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out
+ endif
+ endif
++endif
+ 
+ include ../Rules
+ 
+Index: git/libio/wdummyfileops.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/libio/wdummyfileops.c	2014-08-29 20:01:15.204070587 -0700
+@@ -0,0 +1,161 @@
++/* 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.
++
++   As a special exception, if you link the code in this file with
++   files compiled with a GNU compiler to produce an executable,
++   that does not cause the resulting executable to be covered by
++   the GNU Lesser General Public License.  This exception does not
++   however invalidate any other reasons why the executable file
++   might be covered by the GNU Lesser General Public License.
++   This exception applies to code released by its copyright holders
++   in files containing the exception.  */
++
++#include <assert.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <libioP.h>
++
++static void __THROW __attribute__ ((__noreturn__))
++_IO_wfile_wide_char_support_disabled (void)
++{
++  static const char errstr[]
++    = ("The application tried to use wide character I/O, but libc.so"
++       " was compiled\n"
++       "with the OPTION_POSIX_C_LANG_WIDE_CHAR option group disabled.\n");
++  __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
++  abort ();
++}
++
++static void
++_IO_wfile_disabled_void_int (_IO_FILE *fp, int x)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_int_int (_IO_FILE *fp, int x)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_int_none (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_size_t
++_IO_wfile_disabled_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_size_t
++_IO_wfile_disabled_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seekoff (_IO_FILE *fp, _IO_off64_t off, int dir, int mode)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seekpos (_IO_FILE *fp, _IO_off64_t pos, int flags)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_FILE *
++_IO_wfile_disabled_setbuf (_IO_FILE *fp, char *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_ssize_t
++_IO_wfile_disabled_read (_IO_FILE *fp, void *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_ssize_t
++_IO_wfile_disabled_write (_IO_FILE *fp, const void *buffer, _IO_ssize_t length)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static _IO_off64_t
++_IO_wfile_disabled_seek (_IO_FILE *fp, _IO_off64_t offset, int mode)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_close (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_stat (_IO_FILE *fp, void *buf)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static int
++_IO_wfile_disabled_showmanyc (_IO_FILE *fp)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static void
++_IO_wfile_disabled_imbue (_IO_FILE *fp, void *locale)
++{
++  _IO_wfile_wide_char_support_disabled ();
++}
++
++static const struct _IO_jump_t _IO_wfile_jumps_disabled =
++{
++  JUMP_INIT_DUMMY,
++  JUMP_INIT(finish, _IO_wfile_disabled_void_int),
++  JUMP_INIT(overflow, _IO_wfile_disabled_int_int),
++  JUMP_INIT(underflow, _IO_wfile_disabled_int_none),
++  JUMP_INIT(uflow, _IO_wfile_disabled_int_none),
++  JUMP_INIT(pbackfail, _IO_wfile_disabled_int_int),
++  JUMP_INIT(xsputn, _IO_wfile_disabled_xsputn),
++  JUMP_INIT(xsgetn, _IO_wfile_disabled_xsgetn),
++  JUMP_INIT(seekoff, _IO_wfile_disabled_seekoff),
++  JUMP_INIT(seekpos, _IO_wfile_disabled_seekpos),
++  JUMP_INIT(setbuf, _IO_wfile_disabled_setbuf),
++  JUMP_INIT(sync, _IO_wfile_disabled_int_none),
++  JUMP_INIT(doallocate, _IO_wfile_disabled_int_none),
++  JUMP_INIT(read, _IO_wfile_disabled_read),
++  JUMP_INIT(write, _IO_wfile_disabled_write),
++  JUMP_INIT(seek, _IO_wfile_disabled_seek),
++  JUMP_INIT(close, _IO_wfile_disabled_close),
++  JUMP_INIT(stat, _IO_wfile_disabled_stat),
++  JUMP_INIT(showmanyc, _IO_wfile_disabled_showmanyc),
++  JUMP_INIT(imbue, _IO_wfile_disabled_imbue)
++};
++
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps)
++libc_hidden_data_def (_IO_wfile_jumps)
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_mmap)
++strong_alias (_IO_wfile_jumps_disabled, _IO_wfile_jumps_maybe_mmap)
+Index: git/locale/catnames.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/locale/catnames.c	2014-08-29 20:01:15.204070587 -0700
+@@ -0,0 +1,48 @@
++/* Copyright (C) 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 "localeinfo.h"
++
++/* Define an array of category names (also the environment variable names).  */
++const union catnamestr_t _nl_category_names attribute_hidden =
++  {
++    {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++      category_name,
++#include "categories.def"
++#undef DEFINE_CATEGORY
++    }
++  };
++
++const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
++  {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
++#include "categories.def"
++#undef DEFINE_CATEGORY
++  };
++
++/* An array of their lengths, for convenience.  */
++const uint8_t _nl_category_name_sizes[] attribute_hidden =
++  {
++#define DEFINE_CATEGORY(category, category_name, items, a) \
++    [category] = sizeof (category_name) - 1,
++#include "categories.def"
++#undef	DEFINE_CATEGORY
++    [LC_ALL] = sizeof ("LC_ALL") - 1
++  };
+Index: git/locale/C-ctype.c
+===================================================================
+--- git.orig/locale/C-ctype.c	2014-08-29 20:00:47.396070587 -0700
++++ git/locale/C-ctype.c	2014-08-29 20:01:15.204070587 -0700
+@@ -19,8 +19,11 @@
+ #include "localeinfo.h"
+ #include <endian.h>
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ #include "C-translit.h"
++#endif
+ 
+ /* This table's entries are taken from POSIX.2 Table 2-6
+    ``LC_CTYPE Category Definition in the POSIX Locale''.
+@@ -647,6 +650,7 @@
+     { .word = L'7' },
+     { .word = L'8' },
+     { .word = L'9' },
++#if __OPTION_EGLIBC_LOCALE_CODE
+     /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
+     { .word = NTRANSLIT },
+     /* _NL_CTYPE_TRANSLIT_FROM_IDX */
+@@ -657,6 +661,22 @@
+     { .wstr = translit_to_idx },
+     /* _NL_CTYPE_TRANSLIT_TO_TBL */
+     { .wstr = (uint32_t *) translit_to_tbl },
++#else
++    /* If the locale code isn't enabled, we don't have the
++       transliteration code in iconv/gconv_trans.c anyway, so there's
++       no need for the transliteration tables here.  We'll fall back
++       on the default missing replacement, '?'.  */
++    /* _NL_CTYPE_TRANSLIT_TAB_SIZE */
++    { .word = 0 },
++    /* _NL_CTYPE_TRANSLIT_FROM_IDX */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_FROM_TBL */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_TO_IDX */
++    { .wstr = NULL },
++    /* _NL_CTYPE_TRANSLIT_TO_TBL */
++    { .wstr = NULL },
++#endif
+     /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN */
+     { .word = 1 },
+     /* _NL_CTYPE_TRANSLIT_DEFAULT_MISSING */
+Index: git/locale/dummy-setlocale.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/locale/dummy-setlocale.c	2014-08-29 20:01:15.204070587 -0700
+@@ -0,0 +1,33 @@
++/* Copyright (C) 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 <string.h>
++#include <locale.h>
++
++char *
++setlocale (int category, const char *locale)
++{
++  if (! locale
++      || locale[0] == '\0'
++      || strcmp (locale, "C") == 0
++      || strcmp (locale, "POSIX") == 0)
++    return (char *) "C";
++  else
++    return NULL;
++}
++libc_hidden_def (setlocale)
+Index: git/locale/localeinfo.h
+===================================================================
+--- git.orig/locale/localeinfo.h	2014-08-29 20:00:47.404070587 -0700
++++ git/locale/localeinfo.h	2014-08-29 20:01:15.204070587 -0700
+@@ -224,7 +224,7 @@
+    unused.  We can manage this playing some tricks with weak references.
+    But with thread-local locale settings, it becomes quite ungainly unless
+    we can use __thread variables.  So only in that case do we attempt this.  */
+-#ifndef SHARED
++#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF
+ # include <tls.h>
+ # define NL_CURRENT_INDIRECT	1
+ #endif
+Index: git/locale/Makefile
+===================================================================
+--- git.orig/locale/Makefile	2014-08-29 20:00:47.400070587 -0700
++++ git/locale/Makefile	2014-08-29 20:01:15.204070587 -0700
+@@ -18,27 +18,43 @@
+ #
+ #	Makefile for locales.
+ #
++include ../option-groups.mak
++
+ subdir	:= locale
+ 
+ include ../Makeconfig
+ 
+ headers		= locale.h bits/locale.h langinfo.h xlocale.h
+-routines	= setlocale findlocale loadlocale loadarchive \
+-		  localeconv nl_langinfo nl_langinfo_l mb_cur_max \
+-		  newlocale duplocale freelocale uselocale
+-tests		= tst-C-locale tst-locname tst-duplocale
++# catnames is needed by OPTION_EGLIBC_LOCALE_CODE and by the 'intl' code.
++# If we put the latter in an option group, too, we can omit catnames
++# when both option groups are disabled.  libstdc++-v3 needs mb_cur_max.
++routines-y      := catnames mb_cur_max
++routines-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= setlocale findlocale loadlocale loadarchive \
++		   localeconv nl_langinfo nl_langinfo_l \
++		   newlocale duplocale freelocale uselocale
++ifneq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++routines-y	+= dummy-setlocale
++endif
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-C-locale tst-locname tst-duplocale
+ categories	= ctype messages monetary numeric time paper name \
+ 		  address telephone measurement identification collate
+-aux		= $(categories:%=lc-%) $(categories:%=C-%) SYS_libc C_name \
+-		  xlocale localename global-locale coll-lookup
+-others		= localedef locale
++# C-messages belongs in an intl option group.
++aux-y		:= C-ctype C-time \
++		   SYS_libc C_name xlocale global-locale coll-lookup
++aux-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= $(filter-out $(aux-y), \
++	                        $(categories:%=lc-%) $(categories:%=C-%)) \
++	           localename
++others-$(OPTION_EGLIBC_LOCALE_CODE) = localedef locale
+ #others-static	= localedef locale
+-install-bin	= localedef locale
+-extra-objs	= $(localedef-modules:=.o) $(localedef-aux:=.o) \
++install-bin	= $(others-y)
++extra-objs-$(OPTION_EGLIBC_LOCALE_CODE) \
++		= $(localedef-modules:=.o) $(localedef-aux:=.o) \
+ 		  $(locale-modules:=.o) $(lib-modules:=.o)
+ 
+-extra-libs	= libBrokenLocale
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_LOCALE_CODE) = libBrokenLocale
++extra-libs-others = $(extra-libs-y)
+ 
+ libBrokenLocale-routines = broken_cur_max
+ 
+@@ -94,6 +110,9 @@
+ CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts
+ CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts
+ CFLAGS-charmap-dir.c = -Wno-write-strings
++ifneq (y,$(OPTION_EGLIBC_SPAWN))
++CFLAGS-charmap-dir.c += -DNO_UNCOMPRESS
++endif
+ 
+ # This makes sure -DNOT_IN_libc et al are passed for all these modules.
+ cpp-srcs-left := $(addsuffix .c,$(localedef-modules) $(localedef-aux) \
+Index: git/locale/programs/charmap-dir.c
+===================================================================
+--- git.orig/locale/programs/charmap-dir.c	2014-08-29 20:00:47.408070587 -0700
++++ git/locale/programs/charmap-dir.c	2014-08-29 20:01:15.204070587 -0700
+@@ -19,7 +19,9 @@
+ #include <error.h>
+ #include <fcntl.h>
+ #include <libintl.h>
++#ifndef NO_UNCOMPRESS
+ #include <spawn.h>
++#endif
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -156,6 +158,7 @@
+   return closedir (dir);
+ }
+ 
++#ifndef NO_UNCOMPRESS
+ /* Creates a subprocess decompressing the given pathname, and returns
+    a stream reading its output (the decompressed data).  */
+ static
+@@ -204,6 +207,7 @@
+     }
+   return NULL;
+ }
++#endif
+ 
+ /* Opens a charmap for reading, given its name (not an alias name).  */
+ FILE *
+@@ -226,6 +230,7 @@
+   if (stream != NULL)
+     return stream;
+ 
++#ifndef NO_UNCOMPRESS
+   memcpy (p, ".gz", 4);
+   stream = fopen_uncompressed (pathname, "gzip");
+   if (stream != NULL)
+@@ -235,6 +240,7 @@
+   stream = fopen_uncompressed (pathname, "bzip2");
+   if (stream != NULL)
+     return stream;
++#endif
+ 
+   return NULL;
+ }
+@@ -263,8 +269,8 @@
+       char *alias = NULL;
+       char junk[BUFSIZ];
+ 
+-      if (fscanf (stream, " <code_set_name> %ms", &alias) == 1
+-          || fscanf (stream, "%% alias %ms", &alias) == 1)
++      if (fscanf (stream, " <code_set_name> %as", &alias) == 1
++          || fscanf (stream, "%% alias %as", &alias) == 1)
+         {
+           aliases = (char **) xrealloc (aliases,
+                                         (naliases + 2) * sizeof (char *));
+Index: git/locale/programs/ld-collate.c
+===================================================================
+--- git.orig/locale/programs/ld-collate.c	2014-08-29 20:00:47.408070587 -0700
++++ git/locale/programs/ld-collate.c	2014-08-29 20:01:15.208070587 -0700
+@@ -350,7 +350,7 @@
+     }
+   if (wcs != NULL)
+     {
+-      size_t nwcs = wcslen ((wchar_t *) wcs);
++      size_t nwcs = wcslen_uint32 (wcs);
+       uint32_t zero = 0;
+       /* Handle <U0000> as a single character.  */
+       if (nwcs == 0)
+@@ -1776,8 +1776,7 @@
+ 
+ 	      if ((*eptr)->nwcs == runp->nwcs)
+ 		{
+-		  int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
+-				   (wchar_t *) runp->wcs, runp->nwcs);
++		  int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs);
+ 
+ 		  if (c == 0)
+ 		    {
+@@ -2010,9 +2009,9 @@
+ 	     one consecutive entry.  */
+ 	  if (runp->wcnext != NULL
+ 	      && runp->nwcs == runp->wcnext->nwcs
+-	      && wmemcmp ((wchar_t *) runp->wcs,
+-			  (wchar_t *)runp->wcnext->wcs,
+-			  runp->nwcs - 1) == 0
++	      && wmemcmp_uint32 (runp->wcs,
++				 runp->wcnext->wcs,
++				 runp->nwcs - 1) == 0
+ 	      && (runp->wcs[runp->nwcs - 1]
+ 		  == runp->wcnext->wcs[runp->nwcs - 1] + 1))
+ 	    {
+@@ -2036,9 +2035,9 @@
+ 		runp = runp->wcnext;
+ 	      while (runp->wcnext != NULL
+ 		     && runp->nwcs == runp->wcnext->nwcs
+-		     && wmemcmp ((wchar_t *) runp->wcs,
+-				 (wchar_t *)runp->wcnext->wcs,
+-				 runp->nwcs - 1) == 0
++		     && wmemcmp_uint32 (runp->wcs,
++					runp->wcnext->wcs,
++					runp->nwcs - 1) == 0
+ 		     && (runp->wcs[runp->nwcs - 1]
+ 			 == runp->wcnext->wcs[runp->nwcs - 1] + 1));
+ 
+Index: git/locale/programs/ld-ctype.c
+===================================================================
+--- git.orig/locale/programs/ld-ctype.c	2014-08-29 20:00:47.408070587 -0700
++++ git/locale/programs/ld-ctype.c	2014-08-29 20:01:15.208070587 -0700
+@@ -957,7 +957,7 @@
+   allocate_arrays (ctype, charmap, ctype->repertoire);
+ 
+   default_missing_len = (ctype->default_missing
+-			 ? wcslen ((wchar_t *) ctype->default_missing)
++			 ? wcslen_uint32 (ctype->default_missing)
+ 			 : 0);
+ 
+   init_locale_data (&file, nelems);
+@@ -1968,7 +1968,7 @@
+ 	    ignore = 1;
+ 	  else
+ 	    /* This value is usable.  */
+-	    obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4);
++	    obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4);
+ 
+ 	  first = 0;
+ 	}
+@@ -2516,8 +2516,8 @@
+ 	    }
+ 
+ 	handle_tok_digit:
+-	  class_bit = _ISwdigit;
+-	  class256_bit = _ISdigit;
++	  class_bit = BITw (tok_digit);
++	  class256_bit = BIT (tok_digit);
+ 	  handle_digits = 1;
+ 	  goto read_charclass;
+ 
+@@ -4001,8 +4001,7 @@
+ 
+ 	  while (idx < number)
+ 	    {
+-	      int res = wcscmp ((const wchar_t *) sorted[idx]->from,
+-				(const wchar_t *) runp->from);
++	      int res = wcscmp_uint32 (sorted[idx]->from, runp->from);
+ 	      if (res == 0)
+ 		{
+ 		  replace = 1;
+@@ -4039,11 +4038,11 @@
+       for (cnt = 0; cnt < number; ++cnt)
+ 	{
+ 	  struct translit_to_t *srunp;
+-	  from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
++	  from_len += wcslen_uint32 (sorted[cnt]->from) + 1;
+ 	  srunp = sorted[cnt]->to;
+ 	  while (srunp != NULL)
+ 	    {
+-	      to_len += wcslen ((const wchar_t *) srunp->str) + 1;
++	      to_len += wcslen_uint32 (srunp->str) + 1;
+ 	      srunp = srunp->next;
+ 	    }
+ 	  /* Plus one for the extra NUL character marking the end of
+@@ -4067,18 +4066,18 @@
+ 	  ctype->translit_from_idx[cnt] = from_len;
+ 	  ctype->translit_to_idx[cnt] = to_len;
+ 
+-	  len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
+-	  wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len],
+-		   (const wchar_t *) sorted[cnt]->from, len);
++	  len = wcslen_uint32 (sorted[cnt]->from) + 1;
++	  wmemcpy_uint32 (&ctype->translit_from_tbl[from_len],
++			  sorted[cnt]->from, len);
+ 	  from_len += len;
+ 
+ 	  ctype->translit_to_idx[cnt] = to_len;
+ 	  srunp = sorted[cnt]->to;
+ 	  while (srunp != NULL)
+ 	    {
+-	      len = wcslen ((const wchar_t *) srunp->str) + 1;
+-	      wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len],
+-		       (const wchar_t *) srunp->str, len);
++	      len = wcslen_uint32 (srunp->str) + 1;
++	      wmemcpy_uint32 (&ctype->translit_to_tbl[to_len],
++			      srunp->str, len);
+ 	      to_len += len;
+ 	      srunp = srunp->next;
+ 	    }
+Index: git/locale/programs/ld-messages.c
+===================================================================
+--- git.orig/locale/programs/ld-messages.c	2014-08-29 20:00:47.412070587 -0700
++++ git/locale/programs/ld-messages.c	2014-08-29 20:01:15.208070587 -0700
+@@ -25,6 +25,7 @@
+ #include <string.h>
+ #include <stdint.h>
+ #include <sys/uio.h>
++#include <gnu/option-groups.h>
+ 
+ #include <assert.h>
+ 
+@@ -124,6 +125,7 @@
+     }
+   else
+     {
++#if __OPTION_POSIX_REGEXP
+       int result;
+       regex_t re;
+ 
+@@ -140,6 +142,7 @@
+ 	}
+       else if (result != 0)
+ 	regfree (&re);
++#endif
+     }
+ 
+   if (messages->noexpr == NULL)
+@@ -158,6 +161,7 @@
+     }
+   else
+     {
++#if __OPTION_POSIX_REGEXP
+       int result;
+       regex_t re;
+ 
+@@ -174,6 +178,7 @@
+ 	}
+       else if (result != 0)
+ 	regfree (&re);
++#endif
+     }
+ }
+ 
+Index: git/locale/programs/ld-time.c
+===================================================================
+--- git.orig/locale/programs/ld-time.c	2014-08-29 20:00:47.412070587 -0700
++++ git/locale/programs/ld-time.c	2014-08-29 20:01:15.208070587 -0700
+@@ -215,8 +215,10 @@
+ 	}
+       else
+ 	{
++	  static const uint32_t wt_fmt_ampm[]
++	    = { '%','I',':','%','M',':','%','S',' ','%','p',0 };
+ 	  time->t_fmt_ampm = "%I:%M:%S %p";
+-	  time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
++	  time->wt_fmt_ampm = wt_fmt_ampm;
+ 	}
+     }
+ 
+@@ -226,7 +228,7 @@
+       const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
+ 				       31, 31, 30, 31 ,30, 31 };
+       size_t idx;
+-      wchar_t *wstr;
++      uint32_t *wstr;
+ 
+       time->era_entries =
+ 	(struct era_data *) xmalloc (time->num_era
+@@ -464,18 +466,18 @@
+ 	    }
+ 
+ 	  /* Now generate the wide character name and format.  */
+-	  wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end offset */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end start */
+-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end end */
++	  wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */
++	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */
+ 	  if (wstr != NULL)
+ 	    {
+-	      time->era_entries[idx].wname = (uint32_t *) wstr + 1;
+-	      wstr = wcschr (wstr + 1, L':');	/* end name */
++	      time->era_entries[idx].wname = wstr + 1;
++	      wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */
+ 	      if (wstr != NULL)
+ 		{
+ 		  *wstr = L'\0';
+-		  time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
++		  time->era_entries[idx].wformat = wstr + 1;
+ 		}
+ 	      else
+ 		time->era_entries[idx].wname =
+@@ -530,7 +532,16 @@
+   if (time->date_fmt == NULL)
+     time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
+   if (time->wdate_fmt == NULL)
+-    time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
++    {
++      static const uint32_t wdate_fmt[] =
++	{ '%','a',' ',
++	  '%','b',' ',
++	  '%','e',' ',
++	  '%','H',':','%','M',':','%','S',' ',
++	  '%','Z',' ',
++	  '%','Y',0 };
++      time->wdate_fmt = wdate_fmt;
++    }
+ }
+ 
+ 
+Index: git/locale/programs/linereader.c
+===================================================================
+--- git.orig/locale/programs/linereader.c	2014-08-29 20:00:47.412070587 -0700
++++ git/locale/programs/linereader.c	2014-08-29 20:01:15.208070587 -0700
+@@ -595,7 +595,7 @@
+ {
+   int return_widestr = lr->return_widestr;
+   char *buf;
+-  wchar_t *buf2 = NULL;
++  uint32_t *buf2 = NULL;
+   size_t bufact;
+   size_t bufmax = 56;
+ 
+Index: git/locale/programs/localedef.c
+===================================================================
+--- git.orig/locale/programs/localedef.c	2014-08-29 20:00:47.416070587 -0700
++++ git/locale/programs/localedef.c	2014-08-29 20:01:15.208070587 -0700
+@@ -114,6 +114,7 @@
+ #define OPT_LIST_ARCHIVE 309
+ #define OPT_LITTLE_ENDIAN 400
+ #define OPT_BIG_ENDIAN 401
++#define OPT_UINT32_ALIGN 402
+ 
+ /* Definitions of arguments for argp functions.  */
+ static const struct argp_option options[] =
+@@ -150,6 +151,8 @@
+     N_("Generate little-endian output") },
+   { "big-endian", OPT_BIG_ENDIAN, NULL, 0,
+     N_("Generate big-endian output") },
++  { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0,
++    N_("Set the target's uint32_t alignment in bytes (default 4)") },
+   { NULL, 0, NULL, 0, NULL }
+ };
+ 
+@@ -239,12 +242,14 @@
+      ctype locale.  (P1003.2 4.35.5.2)  */
+   setlocale (LC_CTYPE, "POSIX");
+ 
++#ifndef NO_SYSCONF
+   /* Look whether the system really allows locale definitions.  POSIX
+      defines error code 3 for this situation so I think it must be
+      a fatal error (see P1003.2 4.35.8).  */
+   if (sysconf (_SC_2_LOCALEDEF) < 0)
+     WITH_CUR_LOCALE (error (3, 0, _("\
+ FATAL: system does not define `_POSIX2_LOCALEDEF'")));
++#endif
+ 
+   /* Process charmap file.  */
+   charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1);
+@@ -338,6 +343,9 @@
+     case OPT_BIG_ENDIAN:
+       set_big_endian (true);
+       break;
++    case OPT_UINT32_ALIGN:
++      uint32_align_mask = strtol (arg, NULL, 0) - 1;
++      break;
+     case 'c':
+       force_output = 1;
+       break;
+Index: git/locale/programs/locfile.c
+===================================================================
+--- git.orig/locale/programs/locfile.c	2014-08-29 20:00:47.432070587 -0700
++++ git/locale/programs/locfile.c	2014-08-29 20:01:15.208070587 -0700
+@@ -544,6 +544,9 @@
+    machine running localedef.  */
+ bool swap_endianness_p;
+ 
++/* The target's value of __align__(uint32_t) - 1.  */
++unsigned int uint32_align_mask = 3;
++
+ /* When called outside a start_locale_structure/end_locale_structure
+    or start_locale_prelude/end_locale_prelude block, record that the
+    next byte in FILE's obstack will be the first byte of a new element.
+@@ -621,7 +624,7 @@
+ void
+ add_locale_wstring (struct locale_file *file, const uint32_t *string)
+ {
+-  add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
++  add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1);
+ }
+ 
+ /* Record that FILE's next element is the 32-bit integer VALUE.  */
+Index: git/locale/programs/locfile.h
+===================================================================
+--- git.orig/locale/programs/locfile.h	2014-08-29 20:00:47.432070587 -0700
++++ git/locale/programs/locfile.h	2014-08-29 20:01:15.208070587 -0700
+@@ -71,6 +71,8 @@
+ 
+ extern bool swap_endianness_p;
+ 
++extern unsigned int uint32_align_mask;
++
+ /* Change the output to be big-endian if BIG_ENDIAN is true and
+    little-endian otherwise.  */
+ static inline void
+@@ -275,4 +277,49 @@
+ 				   const struct charmap_t *charmap,
+ 				   const char *output_path);
+ 
++static inline size_t
++wcslen_uint32 (const uint32_t *str)
++{
++  size_t len = 0;
++  while (str[len] != 0)
++    len++;
++  return len;
++}
++
++static inline int
++wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n)
++{
++  while (n-- != 0)
++    {
++      int diff = *s1++ - *s2++;
++      if (diff != 0)
++	return diff;
++    }
++  return 0;
++}
++
++static inline int
++wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2)
++{
++  while (*s1 != 0 && *s1 == *s2)
++    s1++, s2++;
++  return *s1 - *s2;
++}
++
++static inline uint32_t *
++wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n)
++{
++  return memcpy (s1, s2, n * sizeof (uint32_t));
++}
++
++static inline uint32_t *
++wcschr_uint32 (const uint32_t *s, uint32_t ch)
++{
++  do
++    if (*s == ch)
++      return (uint32_t *) s;
++  while (*s++ != 0);
++  return 0;
++}
++
+ #endif /* locfile.h */
+Index: git/locale/setlocale.c
+===================================================================
+--- git.orig/locale/setlocale.c	2014-08-29 20:00:47.432070587 -0700
++++ git/locale/setlocale.c	2014-08-29 20:01:15.208070587 -0700
+@@ -64,36 +64,6 @@
+ #endif
+ 
+ 
+-/* Define an array of category names (also the environment variable names).  */
+-const union catnamestr_t _nl_category_names attribute_hidden =
+-  {
+-    {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-      category_name,
+-#include "categories.def"
+-#undef DEFINE_CATEGORY
+-    }
+-  };
+-
+-const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
+-  {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
+-#include "categories.def"
+-#undef DEFINE_CATEGORY
+-  };
+-
+-/* An array of their lengths, for convenience.  */
+-const uint8_t _nl_category_name_sizes[] attribute_hidden =
+-  {
+-#define DEFINE_CATEGORY(category, category_name, items, a) \
+-    [category] = sizeof (category_name) - 1,
+-#include "categories.def"
+-#undef	DEFINE_CATEGORY
+-    [LC_ALL] = sizeof ("LC_ALL") - 1
+-  };
+-
+-
+ #ifdef NL_CURRENT_INDIRECT
+ # define WEAK_POSTLOAD(postload) weak_extern (postload)
+ #else
+Index: git/locale/xlocale.c
+===================================================================
+--- git.orig/locale/xlocale.c	2014-08-29 20:00:47.436070587 -0700
++++ git/locale/xlocale.c	2014-08-29 20:01:15.208070587 -0700
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <locale.h>
++#include <gnu/option-groups.h>
+ #include "localeinfo.h"
+ 
+ #define DEFINE_CATEGORY(category, category_name, items, a) \
+@@ -25,6 +26,19 @@
+ #include "categories.def"
+ #undef	DEFINE_CATEGORY
+ 
++/* If the locale support code isn't enabled, don't generate strong
++   reference to the C locale_data structures here; let the Makefile
++   decide which ones to include.  (In the static linking case, the
++   strong reference to the 'class', 'toupper', and 'tolower' tables
++   will cause C-ctype.o to be brought in, as it should be, even when
++   the reference to _nl_C_LC_CTYPE will be weak.)  */
++#if ! __OPTION_EGLIBC_LOCALE_CODE
++# define DEFINE_CATEGORY(category, category_name, items, a) \
++  weak_extern (_nl_C_##category)
++# include "categories.def"
++# undef	DEFINE_CATEGORY
++#endif
++
+ /* Defined in locale/C-ctype.c.  */
+ extern const char _nl_C_LC_CTYPE_class[] attribute_hidden;
+ extern const char _nl_C_LC_CTYPE_toupper[] attribute_hidden;
+@@ -52,3 +66,26 @@
+     .__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
+     .__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
+   };
++
++
++#if ! __OPTION_EGLIBC_LOCALE_CODE
++/* When locale code is enabled, these are each defined in the
++   appropriate lc-CATEGORY.c file, so that static links (when __thread
++   is supported) bring in only those lc-CATEGORY.o files for
++   categories the program actually uses; look for NL_CURRENT_INDIRECT
++   in localeinfo.h.
++
++   When locale code is disabled, the _nl_C_CATEGORY objects are the
++   only possible referents.  At the moment, there isn't a way to get
++   __OPTION_EGLIBC_LOCALE_CODE defined in every compilation unit that
++   #includes localeinfo.h, so we can't just turn off
++   NL_CURRENT_INDIRECT.  So we'll define the _nl_current_CATEGORY
++   pointers here.  */
++#if defined (NL_CURRENT_INDIRECT)
++#define DEFINE_CATEGORY(category, category_name, items, a)      \
++  __thread struct __locale_data * const *_nl_current_##category   \
++  attribute_hidden = &_nl_C_locobj.__locales[category];
++#include "categories.def"
++#undef DEFINE_CATEGORY
++#endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+Index: git/localedata/Makefile
+===================================================================
+--- git.orig/localedata/Makefile	2014-08-29 20:00:47.444070587 -0700
++++ git/localedata/Makefile	2014-08-29 20:01:15.212070587 -0700
+@@ -21,12 +21,22 @@
+ 
+ include ../Makeconfig
+ 
+-# List with all available character set descriptions.
+-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
++include ../option-groups.mak
+ 
+ # List with all available character set descriptions.
+-locales := $(wildcard locales/*)
++all-charmaps := $(wildcard charmaps/[A-I]*) $(wildcard charmaps/[J-Z]*)
++
++all-locales := $(wildcard locales/*)
+ 
++# If the EGLIBC_LOCALES option group is not enabled, trim the
++# list of charmap and locale source files.
++ifeq ($(OPTION_EGLIBC_LOCALES),y)
++charmaps := $(all-charmaps)
++locales  := $(all-locales)
++else
++charmaps :=
++locales  := locales/POSIX
++endif
+ 
+ subdir-dirs = tests-mbwc
+ vpath %.c tests-mbwc
+@@ -71,14 +81,20 @@
+ 		     tst_wcsxfrm tst_wctob tst_wctomb tst_wctrans      \
+ 		     tst_wctype tst_wcwidth
+ 
+-tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
++# Since these tests build their own locale files, they're not
++# dependent on the OPTION_EGLIBC_LOCALES option group.  But they do
++# need the locale functions to be present.
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++     += $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
+ 	tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \
+ 	tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
+ 	tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \
+ 	tst-wctype
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ tests-static = bug-setlocale1-static
+ tests += $(tests-static)
+-ifeq (yes,$(build-shared))
++endif
++ifeq (yesy,$(build-shared)$(OPTION_EGLIBC_LOCALE_CODE))
+ ifneq (no,$(PERL))
+ tests-special += $(objpfx)mtrace-tst-leaks.out
+ endif
+@@ -92,12 +108,14 @@
+ 
+ tests: $(objdir)/iconvdata/gconv-modules
+ 
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
+ tests-special += $(objpfx)sort-test.out $(objpfx)tst-fmon.out \
+ 		 $(objpfx)tst-locale.out $(objpfx)tst-rpmatch.out \
+ 		 $(objpfx)tst-trans.out $(objpfx)tst-ctype.out \
+ 		 $(objpfx)tst-langinfo.out $(objpfx)tst-langinfo-static.out \
+ 		 $(objpfx)tst-numeric.out
+ tests-static += tst-langinfo-static
++endif
+ 
+ ifeq ($(run-built-tests),yes)
+ # We have to generate locales
+@@ -213,6 +231,11 @@
+ 
+ include SUPPORTED
+ 
++# Only install locale data if OPTION_EGLIBC_LOCALES is selected.
++ifneq ($(OPTION_EGLIBC_LOCALES),y)
++SUPPORTED-LOCALES :=
++endif
++
+ INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES))
+ 
+ # Sometimes the whole collection of locale files should be installed.
+Index: git/login/Makefile
+===================================================================
+--- git.orig/login/Makefile	2014-08-29 20:00:47.736070587 -0700
++++ git/login/Makefile	2014-08-29 20:01:15.212070587 -0700
+@@ -18,6 +18,7 @@
+ #
+ #	Sub-makefile for login portion of the library.
+ #
++include ../option-groups.mak
+ 
+ subdir	:= login
+ 
+@@ -25,14 +26,16 @@
+ 
+ headers	:= utmp.h bits/utmp.h lastlog.h pty.h
+ 
+-routines := getlogin getlogin_r setlogin getlogin_r_chk \
+-	    getutent getutent_r getutid getutline getutid_r getutline_r \
+-	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
+-	    ptsname_r_chk
++routines := getpt grantpt unlockpt ptsname ptsname_r_chk
++routines-$(OPTION_EGLIBC_UTMP) \
++	 += getutent getutent_r getutid getutline getutid_r getutline_r \
++	    utmp_file utmpname updwtmp
++routines-$(OPTION_EGLIBC_GETLOGIN) += getlogin getlogin_r getlogin_r_chk
++routines-$(OPTION_EGLIBC_BSD) += setlogin
+ 
+ CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"'
+ 
+-others = utmpdump
++others-$(OPTION_EGLIBC_UTMP) += utmpdump
+ 
+ ifeq (yes,$(build-pt-chown))
+ others += pt_chown
+@@ -46,8 +49,8 @@
+ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname
+ 
+ # Build the -lutil library with these extra functions.
+-extra-libs      := libutil
+-extra-libs-others := $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_UTMP) := libutil
++extra-libs-others := $(extra-libs-y)
+ 
+ libutil-routines:= login login_tty logout logwtmp openpty forkpty
+ 
+Index: git/Makeconfig
+===================================================================
+--- git.orig/Makeconfig	2014-08-29 20:00:42.956070587 -0700
++++ git/Makeconfig	2014-08-29 20:01:15.212070587 -0700
+@@ -582,7 +582,7 @@
+ # and run on the build system, causes that program with those
+ # arguments to be run on the host for which the library is built.
+ ifndef test-wrapper
+-test-wrapper =
++test-wrapper = $(cross-test-wrapper)
+ endif
+ # Likewise, but the name of the program is preceded by
+ # <variable>=<value> assignments for environment variables.
+@@ -1057,6 +1057,24 @@
+ libm = $(common-objpfx)math/libm.a
+ endif
+ 
++# Generate a header file that #defines preprocessor symbols indicating
++# which option groups are enabled.  Note that the option-groups.config file
++# may not exist at all.
++before-compile += $(common-objpfx)gnu/option-groups.h
++common-generated += gnu/option-groups.h gnu/option-groups.stmp
++headers += gnu/option-groups.h
++$(common-objpfx)gnu/option-groups.h: $(common-objpfx)gnu/option-groups.stmp; @:
++$(common-objpfx)gnu/option-groups.stmp:					\
++		$(..)scripts/option-groups.awk				\
++		$(..)option-groups.defaults				\
++		$(wildcard $(common-objpfx)option-groups.config)
++	$(make-target-directory)
++	@rm -f ${@:stmp=T} $@
++	LC_ALL=C $(AWK) -f $^ > ${@:stmp=T}
++	$(move-if-change) ${@:stmp=T} ${@:stmp=h}
++	touch $@
++
++
+ # These are the subdirectories containing the library source.  The order
+ # is more or less arbitrary.  The sorting step will take care of the
+ # dependencies.
+Index: git/Makerules
+===================================================================
+--- git.orig/Makerules	2014-08-29 20:00:42.960070587 -0700
++++ git/Makerules	2014-08-29 20:01:15.212070587 -0700
+@@ -379,6 +379,25 @@
+ endef
+ endif
+ \f
++# Include targets in the selected option groups.
++aux                  += $(aux-y)
++extra-libs           += $(extra-libs-y)
++extra-libs-others    += $(extra-libs-others-y)
++extra-objs           += $(extra-objs-y)
++install-bin          += $(install-bin-y)
++install-others       += $(install-others-y)
++install-sbin         += $(install-sbin-y)
++modules              += $(modules-y)
++others               += $(others-y)
++others-pie           += $(others-pie-y)
++routines             += $(routines-y)
++static-only-routines += $(static-only-routines-y)
++sysdep_routines      += $(sysdep_routines-y)
++test-srcs            += $(test-srcs-y)
++tests                += $(tests-y)
++xtests               += $(xtests-y)
++
++\f
+ # Modify the list of routines we build for different targets
+ 
+ ifeq (yes,$(build-shared))
+Index: git/malloc/Makefile
+===================================================================
+--- git.orig/malloc/Makefile	2014-08-29 20:00:47.760070587 -0700
++++ git/malloc/Makefile	2014-08-29 20:01:15.212070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for malloc routines
+ #
++include ../option-groups.mak
++
+ subdir	:= malloc
+ 
+ include ../Makeconfig
+@@ -36,9 +38,15 @@
+ non-lib.a := libmcheck.a
+ 
+ # Additional library.
++ifeq ($(OPTION_EGLIBC_MEMUSAGE),y)
+ extra-libs = libmemusage
+ extra-libs-others = $(extra-libs)
+ 
++ifdef OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++CPPFLAGS-memusage += -D__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE=$(OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE)
++endif
++endif
++
+ libmemusage-routines = memusage
+ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
+ 
+@@ -67,7 +75,7 @@
+ # Unless we get a test for the availability of libgd which also works
+ # for cross-compiling we disable the memusagestat generation in this
+ # situation.
+-ifneq ($(cross-compiling),yes)
++ifeq ($(cross-compiling)$(OPTION_EGLIBC_MEMUSAGE),noy)
+ # If the gd library is available we build the `memusagestat' program.
+ ifneq ($(LIBGD),no)
+ others: $(objpfx)memusage
+Index: git/malloc/memusage.c
+===================================================================
+--- git.orig/malloc/memusage.c	2014-08-29 20:00:47.768070587 -0700
++++ git/malloc/memusage.c	2014-08-29 20:01:15.212070587 -0700
+@@ -33,6 +33,7 @@
+ #include <stdint.h>
+ #include <sys/mman.h>
+ #include <sys/time.h>
++#include <gnu/option-groups.h>
+ 
+ #include <memusage.h>
+ 
+@@ -93,7 +94,11 @@
+ #define peak_stack      peak_use[1]
+ #define peak_total      peak_use[2]
+ 
+-#define DEFAULT_BUFFER_SIZE     32768
++#ifndef __OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++# define DEFAULT_BUFFER_SIZE	32768
++#else
++# define DEFAULT_BUFFER_SIZE	__OPTION_EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++#endif
+ static size_t buffer_size;
+ 
+ static int fd = -1;
+Index: git/malloc/memusage.sh
+===================================================================
+--- git.orig/malloc/memusage.sh	2014-08-29 20:00:47.768070587 -0700
++++ git/malloc/memusage.sh	2014-08-29 20:01:15.212070587 -0700
+@@ -35,7 +35,7 @@
+ 
+ # Print help message
+ do_help() {
+-  echo $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
++  printf $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
+ Profile memory usage of PROGRAM.
+ 
+    -n,--progname=NAME     Name of the program file to profile
+Index: git/math/Makefile
+===================================================================
+--- git.orig/math/Makefile	2014-08-29 20:00:47.836070587 -0700
++++ git/math/Makefile	2014-08-29 20:01:15.212070587 -0700
+@@ -21,6 +21,8 @@
+ 
+ include ../Makeconfig
+ 
++include ../option-groups.mak
++
+ # Installed header files.
+ headers		:= math.h bits/mathcalls.h bits/mathinline.h bits/huge_val.h \
+ 		   bits/huge_valf.h bits/huge_vall.h bits/inf.h bits/nan.h \
+@@ -33,8 +35,8 @@
+ 
+ # Build the -lm library.
+ 
+-extra-libs	:= libm
+-extra-libs-others = $(extra-libs)
++extra-libs-$(OPTION_EGLIBC_LIBM) := libm
++extra-libs-others-$(OPTION_EGLIBC_LIBM) = $(extra-libs-$(OPTION_EGLIBC_LIBM))
+ 
+ libm-support = k_standard s_lib_version s_matherr s_signgam		\
+ 	       fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg		\
+Index: git/misc/err.c
+===================================================================
+--- git.orig/misc/err.c	2014-08-29 20:00:48.232070587 -0700
++++ git/misc/err.c	2014-08-29 20:01:15.212070587 -0700
+@@ -22,6 +22,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <stdio.h>
++#include <gnu/option-groups.h>
+ 
+ #include <wchar.h>
+ #define flockfile(s) _IO_flockfile (s)
+@@ -37,6 +38,7 @@
+   va_end (ap);								      \
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ static void
+ convert_and_print (const char *format, __gnuc_va_list ap)
+ {
+@@ -81,6 +83,7 @@
+ 
+   __vfwprintf (stderr, wformat, ap);
+ }
++#endif
+ 
+ void
+ vwarnx (const char *format, __gnuc_va_list ap)
+@@ -88,9 +91,13 @@
+   flockfile (stderr);
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       __fwprintf (stderr, L"%s: ", __progname);
+       convert_and_print (format, ap);
+       putwc_unlocked (L'\n', stderr);
++#else
++      abort ();
++#endif
+     }
+   else
+     {
+@@ -111,6 +118,7 @@
+   flockfile (stderr);
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       __fwprintf (stderr, L"%s: ", __progname);
+       if (format)
+ 	{
+@@ -119,6 +127,9 @@
+ 	}
+       __set_errno (error);
+       __fwprintf (stderr, L"%m\n");
++#else
++      abort ();
++#endif
+     }
+   else
+     {
+Index: git/misc/error.c
+===================================================================
+--- git.orig/misc/error.c	2014-08-29 20:00:48.232070587 -0700
++++ git/misc/error.c	2014-08-29 20:01:15.212070587 -0700
+@@ -35,6 +35,7 @@
+ #endif
+ 
+ #ifdef _LIBC
++# include <gnu/option-groups.h>
+ # include <libintl.h>
+ # include <stdbool.h>
+ # include <stdint.h>
+@@ -205,6 +206,7 @@
+ #if _LIBC
+   if (_IO_fwide (stderr, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       size_t len = strlen (message) + 1;
+       wchar_t *wmessage = NULL;
+       mbstate_t st;
+@@ -265,6 +267,9 @@
+ 
+       if (use_malloc)
+ 	free (wmessage);
++#else
++      abort ();
++#endif
+     }
+   else
+ #endif
+Index: git/misc/Makefile
+===================================================================
+--- git.orig/misc/Makefile	2014-08-29 20:00:48.232070587 -0700
++++ git/misc/Makefile	2014-08-29 20:01:15.212070587 -0700
+@@ -19,6 +19,10 @@
+ #	Sub-makefile for misc portion of the library.
+ #
+ 
++# Some system-dependent implementations of these functions use option
++# groups (see sysdeps/unix/sysv/linux/Makefile, for example).
++include ../option-groups.mak
++
+ subdir	:= misc
+ 
+ include ../Makeconfig
+@@ -46,40 +50,47 @@
+ 	    select pselect \
+ 	    acct chroot fsync sync fdatasync syncfs reboot \
+ 	    gethostid sethostid \
+-	    revoke vhangup \
++	    vhangup \
+ 	    swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
+ 	    mkostemp mkostemp64 mkstemps mkstemps64 mkostemps mkostemps64 \
+ 	    ualarm usleep \
+ 	    gtty stty \
+ 	    ptrace \
+-	    fstab mntent mntent_r \
++	    mntent mntent_r \
+ 	    utimes lutimes futimes futimesat \
+ 	    truncate ftruncate truncate64 ftruncate64 \
+-	    chflags fchflags \
+ 	    insremque getttyent getusershell getpass ttyslot \
+ 	    syslog syscall daemon \
+ 	    mmap mmap64 munmap mprotect msync madvise mincore remap_file_pages\
+ 	    mlock munlock mlockall munlockall \
+-	    efgcvt efgcvt_r qefgcvt qefgcvt_r \
+ 	    hsearch hsearch_r tsearch lsearch \
+ 	    err error ustat \
+-	    getsysstats dirname regexp \
++	    getsysstats dirname \
+ 	    getloadavg getclktck \
+ 	    fgetxattr flistxattr fremovexattr fsetxattr getxattr \
+ 	    listxattr lgetxattr llistxattr lremovexattr lsetxattr \
+ 	    removexattr setxattr getauxval ifunc-impl-list
+ 
++routines-$(OPTION_POSIX_REGEXP) += regexp
++routines-$(OPTION_EGLIBC_FSTAB) += fstab
++routines-$(OPTION_EGLIBC_BSD) += chflags fchflags revoke
++routines-$(OPTION_EGLIBC_FCVT) += efgcvt efgcvt_r qefgcvt qefgcvt_r
++
+ generated += tst-error1.mtrace tst-error1-mem.out
+ 
+ aux := init-misc
+ install-lib := libg.a
+ gpl2lgpl := error.c error.h
+ 
+-tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
+-	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
++tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
++	 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += tst-error1
++tests-$(OPTION_EGLIBC_FCVT) += tst-efgcvt
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO))
+ tests-special += $(objpfx)tst-error1-mem.out
+ endif
++endif
+ 
+ CFLAGS-select.c = -fexceptions -fasynchronous-unwind-tables
+ CFLAGS-tsearch.c = $(uses-callbacks)
+Index: git/misc/tst-efgcvt.c
+===================================================================
+--- git.orig/misc/tst-efgcvt.c	2014-08-29 20:00:52.652070587 -0700
++++ git/misc/tst-efgcvt.c	2014-08-29 20:01:15.216070587 -0700
+@@ -59,7 +59,7 @@
+   { 123.01, -4, 3, "" },
+   { 126.71, -4, 3, "" },
+   { 0.0, 4, 1, "0000" },
+-#if DBL_MANT_DIG == 53
++#if DBL_MANT_DIG == 53 && !(defined __powerpc__ && defined __NO_FPRS__ && !defined _SOFT_FLOAT && !defined _SOFT_DOUBLE)
+   { 0x1p-1074, 3, -323, "494" },
+   { -0x1p-1074, 3, -323, "494" },
+ #endif
+Index: git/nis/Makefile
+===================================================================
+--- git.orig/nis/Makefile	2014-08-29 20:00:52.660070587 -0700
++++ git/nis/Makefile	2014-08-29 20:01:15.216070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for NIS/NIS+ part.
+ #
++include ../option-groups.mak
++
+ subdir	:= nis
+ 
+ include ../Makeconfig
+@@ -30,19 +32,26 @@
+ 
+ # These are the databases available for the nis (and perhaps later nisplus)
+ # service.  This must be a superset of the services in nss.
+-databases		= proto service hosts network grp pwd rpc ethers \
+-			  spwd netgrp alias publickey
++databases-y		:= proto service hosts network grp pwd rpc ethers \
++			   spwd netgrp publickey
++databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
+ 
+ # Specify rules for the nss_* modules.
+-services		:= nis nisplus compat
++# The 'compat' module includes nis support, and the 'nss' directory
++# includes a bare-bones "files" library, so we'll include 'compat' in
++# OPTION_EGLIBC_NIS.
++services-y		:=
++services-$(OPTION_EGLIBC_NIS) += nis nisplus compat
++
++extra-libs-$(OPTION_EGLIBC_NIS) += libnsl
++extra-libs-y		+= $(services-y:%=libnss_%)
+ 
+-extra-libs		= libnsl $(services:%=libnss_%)
+ # These libraries will be built in the `others' pass rather than
+ # the `lib' pass, because they depend on libc.so being built already.
+-extra-libs-others	= $(extra-libs)
++extra-libs-others-y	+= $(extra-libs-y)
+ 
+ # The sources are found in the appropriate subdir.
+-subdir-dirs = $(services:%=nss_%)
++subdir-dirs = $(services-y:%=nss_%)
+ vpath %.c $(subdir-dirs)
+ 
+ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
+@@ -60,11 +69,11 @@
+ libnss_compat-routines	:= $(addprefix compat-,grp pwd spwd initgroups)
+ libnss_compat-inhibit-o	= $(filter-out .os,$(object-suffixes))
+ 
+-libnss_nis-routines	:= $(addprefix nis-,$(databases)) nis-initgroups \
++libnss_nis-routines	:= $(addprefix nis-,$(databases-y)) nis-initgroups \
+ 			   nss-nis
+ libnss_nis-inhibit-o	= $(filter-out .os,$(object-suffixes))
+ 
+-libnss_nisplus-routines	:= $(addprefix nisplus-,$(databases)) nisplus-parser \
++libnss_nisplus-routines	:= $(addprefix nisplus-,$(databases-y)) nisplus-parser \
+ 			   nss-nisplus nisplus-initgroups
+ libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes))
+ 
+@@ -80,12 +89,12 @@
+ # Target-specific variable setting to link objects using deprecated
+ # RPC interfaces with the version of libc.so that makes them available
+ # for new links:
+-$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
++$(services-y:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
+   libc-for-link = $(libnsl-libc)
+ 
+ 
+ ifeq ($(build-shared),yes)
+-$(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
++$(others-y:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
+ else
+-$(others:%=$(objpfx)%): $(objpfx)libnsl.a
++$(others-y:%=$(objpfx)%): $(objpfx)libnsl.a
+ endif
+Index: git/nptl/Makefile
+===================================================================
+--- git.orig/nptl/Makefile	2014-08-29 20:00:52.704070587 -0700
++++ git/nptl/Makefile	2014-08-29 20:01:15.216070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for NPTL portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= nptl
+ 
+ include ../Makeconfig
+@@ -116,7 +118,7 @@
+ 		      pt-raise pt-system \
+ 		      flockfile ftrylockfile funlockfile \
+ 		      sigaction \
+-		      herrno res pt-allocrtsig \
++		      pt-allocrtsig \
+ 		      pthread_kill_other_threads \
+ 		      pthread_getaffinity pthread_setaffinity \
+ 		      pthread_attr_getaffinity pthread_attr_setaffinity \
+@@ -136,6 +138,8 @@
+ #		      pthread_setgid pthread_setegid pthread_setregid \
+ #		      pthread_setresgid
+ 
++libpthread-routines-$(OPTION_EGLIBC_INET) := herrno res
++
+ libpthread-shared-only-routines = version pt-allocrtsig unwind-forcedunwind
+ libpthread-static-only-routines = pthread_atfork
+ 
+@@ -210,7 +214,7 @@
+ 	tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
+ 	tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
+ 	tst-mutexpi9 \
+-	tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
++	tst-spin1 tst-spin2 tst-spin3 \
+ 	tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
+ 	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
+ 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
+@@ -244,14 +248,14 @@
+ 	tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
+ 	tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
+ 	tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
+-	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
++	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel25 \
+ 	tst-cancel-self tst-cancel-self-cancelstate \
+ 	tst-cancel-self-canceltype tst-cancel-self-testcancel \
+ 	tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
+ 	tst-flock1 tst-flock2 \
+ 	tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
+ 	tst-signal6 tst-signal7 \
+-	tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
++	tst-exec2 tst-exec3 tst-exec4 \
+ 	tst-exit1 tst-exit2 tst-exit3 \
+ 	tst-stdio1 tst-stdio2 \
+ 	tst-stack1 tst-stack2 tst-stack3 tst-pthread-getattr \
+@@ -259,13 +263,12 @@
+ 	tst-unload \
+ 	tst-dlsym1 \
+ 	tst-sysconf \
+-	tst-locale1 tst-locale2 \
++	tst-locale2 \
+ 	tst-umask1 \
+ 	tst-popen1 \
+ 	tst-clock1 \
+ 	tst-context1 \
+ 	tst-sched1 \
+-	tst-backtrace1 \
+ 	tst-abstime \
+ 	tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
+ 	tst-getpid1 tst-getpid2 tst-getpid3 \
+@@ -275,6 +278,17 @@
+ 	tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
+ test-srcs = tst-oddstacklimit
+ 
++# This test uses the posix_spawn functions.
++tests-$(OPTION_EGLIBC_SPAWN) += tst-exec1
++
++# This test uses the 'backtrace' functions.
++tests-$(OPTION_EGLIBC_BACKTRACE) += tst-backtrace1
++
++# This test is written in C++.
++tests-$(OPTION_EGLIBC_CXX_TESTS) += tst-cancel24
++
++tests-$(OPTION_EGLIBC_LOCALE_CODE) += tst-locale1
++
+ # Files which must not be linked with libpthread.
+ tests-nolibpthread = tst-unload
+ 
+Index: git/nptl/pthread_create.c
+===================================================================
+--- git.orig/nptl/pthread_create.c	2014-08-29 20:00:52.764070587 -0700
++++ git/nptl/pthread_create.c	2014-08-29 20:01:15.216070587 -0700
+@@ -31,6 +31,7 @@
+ #include <kernel-features.h>
+ #include <exit-thread.h>
+ 
++#include <gnu/option-groups.h>
+ #include <shlib-compat.h>
+ 
+ #include <stap-probe.h>
+@@ -240,8 +241,10 @@
+   THREAD_SETMEM (pd, cpuclock_offset, now);
+ #endif
+ 
++#if __OPTION_EGLIBC_INET
+   /* Initialize resolver state pointer.  */
+   __resp = &pd->res;
++#endif
+ 
+   /* Initialize pointers to locale data.  */
+   __ctype_init ();
+@@ -322,8 +325,10 @@
+   /* Run the destructor for the thread-local data.  */
+   __nptl_deallocate_tsd ();
+ 
++#if __OPTION_EGLIBC_INET
+   /* Clean up any state libc stored in thread-local variables.  */
+   __libc_thread_freeres ();
++#endif
+ 
+   /* If this is the last thread we terminate the process now.  We
+      do not notify the debugger, it might just irritate it if there
+Index: git/nscd/Makefile
+===================================================================
+--- git.orig/nscd/Makefile	2014-08-29 20:00:52.948070587 -0700
++++ git/nscd/Makefile	2014-08-29 20:01:15.216070587 -0700
+@@ -18,14 +18,17 @@
+ #
+ #	Sub-makefile for nscd portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= nscd
+ 
+ include ../Makeconfig
+ 
+ ifneq ($(use-nscd),no)
+-routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
++routines-$(OPTION_EGLIBC_INET) += \
++	     nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
+ 	    nscd_initgroups nscd_getserv_r nscd_netgroup
+-aux	:= nscd_helper
++aux-$(OPTION_EGLIBC_INET) += nscd_helper
+ endif
+ 
+ # To find xmalloc.c
+@@ -37,14 +40,18 @@
+ 		dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
+ 		xmalloc xstrdup aicache initgrcache gai res_hconf \
+ 		netgroupcache
+-
++ifneq (y,$(OPTION_EGLIBC_NIS))
++# If we haven't build libnsl.so, then we'll need to include our
++# own copy of nis_hash.
++nscd-modules += nis_hash
++endif
+ ifeq ($(build-nscd)$(have-thread-library),yesyes)
+ 
+-others += nscd
+-others-pie += nscd
+-install-sbin := nscd
++others-$(OPTION_EGLIBC_INET) += nscd
++others-pie-$(OPTION_EGLIBC_INET) += nscd
++install-sbin-$(OPTION_EGLIBC_INET) += nscd
+ 
+-extra-objs = $(nscd-modules:=.o)
++extra-objs-$(OPTION_EGLIBC_INET) += $(nscd-modules:=.o)
+ 
+ endif
+ 
+@@ -101,7 +108,15 @@
+ $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o)
+ 
+ ifeq ($(build-shared),yes)
+-$(objpfx)nscd: $(shared-thread-library) $(common-objpfx)nis/libnsl.so
++$(objpfx)nscd: $(shared-thread-library)
++else
++$(objpfx)nscd: $(static-thread-library)
++endif
++
++ifeq (y,$(OPTION_EGLIBC_NIS))
++ifeq ($(build-shared),yes)
++$(objpfx)nscd: $(common-objpfx)nis/libnsl.so
+ else
+-$(objpfx)nscd: $(static-thread-library) $(common-objpfx)nis/libnsl.a
++$(objpfx)nscd: $(common-objpfx)nis/libnsl.a
++endif
+ endif
+Index: git/nscd/nis_hash.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/nscd/nis_hash.c	2014-08-29 20:01:15.216070587 -0700
+@@ -0,0 +1,3 @@
++/* If OPTION_EGLIBC_NIS is disabled, nscd can't get this from libnsl.so;
++   we need our own copy.  */
++#include "../nis/nis_hash.c"
+Index: git/nss/fixed-nsswitch.conf
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/nss/fixed-nsswitch.conf	2014-08-29 20:01:15.216070587 -0700
+@@ -0,0 +1,22 @@
++# /etc/nsswitch.conf
++#
++# Example configuration for fixed name service.
++# See the description of OPTION_EGLIBC_NSSWITCH in option-groups.def
++# for details.
++#
++
++aliases:        files
++
++passwd:         files
++group:          files
++shadow:         files
++
++hosts:          files dns
++networks:       files dns
++
++protocols:      files
++services:       files
++ethers:         files
++rpc:            files
++
++netgroup:       files
+Index: git/nss/fixed-nsswitch.functions
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/nss/fixed-nsswitch.functions	2014-08-29 20:01:15.216070587 -0700
+@@ -0,0 +1,121 @@
++/* List of functions defined for fixed NSS in GNU C Library.
++   Copyright (C) 1996, 1997, 1998, 2005 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   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.  */
++
++/* When OPTION_EGLIBC_NSSWITCH is disabled (see option-groups.def),
++   EGLIBC does not use the 'dlopen' and 'dlsym' functions to look for
++   database query functions in the individual name service libraries.
++   Instead, it uses a set of functions chosen at compile time, as
++   directed by the OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS file.  This
++   file is a sample of what you might use there.
++
++   This file is C source code; it should only contain invocations of
++   the following macros:
++
++   - DEFINE_ENT (DATABASE, SERVICE, X)
++
++     Declare the 'setXent', 'getXent_r', and 'endXent' functions that
++     query DATABASE using the service library 'libnss_SERVICE.so.2'.
++     DATABASE should be the full name of the database as it appears in
++     'nsswitch.conf', like 'passwd' or 'aliases'.
++
++     (The non-reentrant 'getXent' functions are implemented in terms
++     of the reentrant 'getXent_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++   - DEFINE_GETBY (DATABASE, SERVICE, X, KEY)
++
++     Declare the 'getXbyKEY_r' functions that query DATABASE using
++     SERVICE.  DATABASE and SERVICE are as described above.
++
++     (The non-reentrant 'getXbyKEY' functions are implemented in terms
++     of the reentrant 'getXbyKEY_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++     Use the special key 'name3' for the service library function that
++     implements the 'getaddrinfo' function.
++
++   - DEFINE_GET (DATABASE, SERVICE, QUERY)
++
++     Declare the 'getQUERY_r' functions that query DATABASE using
++     SERVICE.  This is used for functions like 'getpwnam'.
++
++     (The non-reentrant 'getQUERY' functions are implemented in terms
++     of the reentrant 'getQUERY_r' functions, so there is no need to
++     refer to them explicitly here.)
++
++   This sample file only includes functions that consult the files in
++   '/etc', and the Domain Name System (DNS).  */
++
++/* aliases */
++DEFINE_ENT (aliases, files, alias)
++DEFINE_GETBY (aliases, files, alias, name)
++
++/* ethers */
++DEFINE_ENT (ethers, files, ether)
++
++/* group */
++DEFINE_ENT (group, files, gr)
++DEFINE_GET (group, files, grgid)
++DEFINE_GET (group, files, grnam)
++
++/* hosts */
++DEFINE_ENT (hosts, files, host)
++DEFINE_GETBY (hosts, files, host, addr)
++DEFINE_GETBY (hosts, files, host, name)
++DEFINE_GETBY (hosts, files, host, name2)
++DEFINE_GET (hosts, files, hostton)
++DEFINE_GET (hosts, files, ntohost)
++DEFINE_GETBY (hosts, dns, host, addr)
++DEFINE_GETBY (hosts, dns, host, name)
++DEFINE_GETBY (hosts, dns, host, name2)
++DEFINE_GETBY (hosts, dns, host, name3)
++
++/* netgroup */
++DEFINE_ENT (netgroup, files, netgr)
++
++/* networks */
++DEFINE_ENT (networks, files, net)
++DEFINE_GETBY (networks, files, net, name)
++DEFINE_GETBY (networks, files, net, addr)
++DEFINE_GETBY (networks, dns, net, name)
++DEFINE_GETBY (networks, dns, net, addr)
++
++/* protocols */
++DEFINE_ENT (protocols, files, proto)
++DEFINE_GETBY (protocols, files, proto, name)
++DEFINE_GETBY (protocols, files, proto, number)
++
++/* passwd */
++DEFINE_ENT (passwd, files, pw)
++DEFINE_GET (passwd, files, pwnam)
++DEFINE_GET (passwd, files, pwuid)
++
++/* rpc */
++DEFINE_ENT (rpc, files, rpc)
++DEFINE_GETBY (rpc, files, rpc, name)
++DEFINE_GETBY (rpc, files, rpc, number)
++
++/* services */
++DEFINE_ENT (services, files, serv)
++DEFINE_GETBY (services, files, serv, name)
++DEFINE_GETBY (services, files, serv, port)
++
++/* shadow */
++DEFINE_ENT (shadow, files, sp)
++DEFINE_GET (shadow, files, spnam)
+Index: git/nss/gen-fixed-nsswitch.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/nss/gen-fixed-nsswitch.c	2014-08-29 20:01:15.216070587 -0700
+@@ -0,0 +1,803 @@
++/* gen-fixed-nsswitch.c --- generate fixed name service data structures
++   Copyright (C) 1996-1999, 2001-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.  */
++
++#define _GNU_SOURCE
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <errno.h>
++#include <string.h>
++#include <stdarg.h>
++#include <assert.h>
++#include <ctype.h>
++
++#include "gnu/lib-names.h"
++#include "nss.h"
++
++/* Provide a fallback definition to allow this file to be compiled outside
++   libc.  */
++#ifndef internal_function
++# define internal_function
++#endif
++
++\f
++/* Simple utilities.  */
++
++void __attribute__ ((noreturn))
++error (const char *message)
++{
++  fprintf (stderr, "%s\n", message);
++  exit (1);
++}
++
++
++void *
++check_alloc (void *p)
++{
++  if (p)
++    return p;
++  else
++    error ("out of memory");
++}
++
++void *
++xmalloc (size_t size)
++{
++  return check_alloc (malloc (size));
++}
++
++
++/* Format ARGS according to FORMAT, and return the result as a
++   malloc'ed string.  */
++char *
++saprintf (const char *format, ...)
++{
++  va_list args;
++  size_t len;
++  char *buf;
++
++  va_start (args, format);
++  len = vsnprintf (NULL, 0, format, args);
++  va_end (args);
++
++  buf = xmalloc (len + 1);
++  va_start (args, format);
++  assert (len == vsnprintf (buf, len + 1, format, args));
++  va_end (args);
++
++  return buf;
++}
++
++
++\f
++/* Data structures representing the configuration file in memory.  */
++
++/* These are copied from nsswitch.h.
++
++   We could simply #include that file, but this program runs on the
++   build machine and links against the build machine's libraries,
++   whereas that header is meant for use by target code; it uses
++   'libc_hidden_proto', 'internal_function', and related hair.  Since
++   we've copied the parsing code, we might as well copy the data
++   structure definitions as well.  */
++
++/* Actions performed after lookup finished.  */
++typedef enum
++{
++  NSS_ACTION_CONTINUE,
++  NSS_ACTION_RETURN
++} lookup_actions;
++
++
++typedef struct service_library
++{
++  /* Name of service (`files', `dns', `nis', ...).  */
++  const char *name;
++  /* Pointer to the loaded shared library.  */
++  void *lib_handle;
++  /* And the link to the next entry.  */
++  struct service_library *next;
++} service_library;
++
++
++/* For mapping a function name to a function pointer.  It is known in
++   nsswitch.c:nss_lookup_function that a string pointer for the lookup key
++   is the first member.  */
++typedef struct
++{
++  const char *fct_name;
++  void *fct_ptr;
++} known_function;
++
++
++typedef struct service_user
++{
++  /* And the link to the next entry.  */
++  struct service_user *next;
++  /* Action according to result.  */
++  lookup_actions actions[5];
++  /* Link to the underlying library object.  */
++  service_library *library;
++  /* Collection of known functions.
++
++     With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
++     'tsearch'-style tree.
++
++     With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
++     pointers to known_function structures, NULL-terminated.  */
++  union
++  {
++    void *tree;
++    const known_function **array;
++  } known;
++  /* Name of the service (`files', `dns', `nis', ...).  */
++  const char *name;
++} service_user;
++
++/* To access the action based on the status value use this macro.  */
++#define nss_next_action(ni, status) ((ni)->actions[2 + status])
++
++
++typedef struct name_database_entry
++{
++  /* And the link to the next entry.  */
++  struct name_database_entry *next;
++  /* List of service to be used.  */
++  service_user *service;
++  /* Name of the database.  */
++  const char *name;
++} name_database_entry;
++
++
++typedef struct name_database
++{
++  /* List of all known databases.  */
++  name_database_entry *entry;
++  /* List of libraries with service implementation.  */
++  service_library *library;
++} name_database;
++
++
++\f
++/* Gathering the contents of the FIXED_FUNCTIONS file.  */
++
++/* It should be possible to generate this list automatically by
++   looking at the services and databases used in the nsswitch.conf
++   file, and having a hard-coded set of queries supported on each
++   database.  */
++
++/* We #include the FIXED_FUNCTIONS file several times to build an
++   array of function structures holding its data.  */
++enum function_kind {
++  fk_end = 0,                   /* Last entry.  */
++  fk_setent,                    /* Like setpwent.  */
++  fk_getent,                    /* Like getpwent.  */
++  fk_endent,                    /* Like endpwent.  */
++  fk_getby,                     /* Like gethostbyname.  */
++  fk_get                        /* Like getpwnam.  */
++};
++
++
++struct function {
++  /* What kind of function this is.  */
++  enum function_kind kind;
++
++  /* The database and service of the function being hardwired in.  */
++  char *database, *service;
++
++  /* The kind of entry being queried, for 'fk_setent', 'fk_getent',
++     'fk_endent', and 'fk_getby' functions.  */
++  char *entry;
++
++  /* The key, for 'fk_getby' entries.  */
++  char *key;
++
++  /* The value and key, for 'fk_get' entries.  */
++  char *value_and_key;
++};
++
++
++const struct function functions[] =
++  {
++
++#define DEFINE_ENT(database, service, entry)    \
++    { fk_setent, #database, #service, #entry }, \
++    { fk_getent, #database, #service, #entry }, \
++    { fk_endent, #database, #service, #entry },
++#define DEFINE_GETBY(database, service, entry, key)   \
++    { fk_getby, #database, #service, #entry, #key },
++#define DEFINE_GET(database, service, value_and_key)     \
++    { fk_get, #database, #service, NULL, NULL, #value_and_key },
++
++#include FIXED_FUNCTIONS
++
++#undef DEFINE_ENT
++#undef DEFINE_GETBY
++#undef DEFINE_GET
++
++    { fk_end }
++  };
++
++\f
++/* Parsing the config file.  Functions copied from nsswitch.c.  */
++
++#define __strchrnul strchrnul
++#define __getline getline
++#define __strncasecmp strncasecmp
++
++/* Prototypes for the local functions.  */
++static name_database *nss_parse_file (const char *fname) internal_function;
++static name_database_entry *nss_getline (char *line) internal_function;
++static service_user *nss_parse_service_list (const char *line)
++     internal_function;
++
++static name_database *
++internal_function
++nss_parse_file (const char *fname)
++{
++  FILE *fp;
++  name_database *result;
++  name_database_entry *last;
++  char *line;
++  size_t len;
++
++  /* Open the configuration file.  */
++  fp = fopen (fname, "rc");
++  if (fp == NULL)
++    return NULL;
++
++  // /* No threads use this stream.  */
++  // __fsetlocking (fp, FSETLOCKING_BYCALLER);
++
++  result = (name_database *) xmalloc (sizeof (name_database));
++
++  result->entry = NULL;
++  result->library = NULL;
++  last = NULL;
++  line = NULL;
++  len = 0;
++  do
++    {
++      name_database_entry *this;
++      ssize_t n;
++
++      n = __getline (&line, &len, fp);
++      if (n < 0)
++	break;
++      if (line[n - 1] == '\n')
++	line[n - 1] = '\0';
++
++      /* Because the file format does not know any form of quoting we
++	 can search forward for the next '#' character and if found
++	 make it terminating the line.  */
++      *__strchrnul (line, '#') = '\0';
++
++      /* If the line is blank it is ignored.  */
++      if (line[0] == '\0')
++	continue;
++
++      /* Each line completely specifies the actions for a database.  */
++      this = nss_getline (line);
++      if (this != NULL)
++	{
++	  if (last != NULL)
++	    last->next = this;
++	  else
++	    result->entry = this;
++
++	  last = this;
++	}
++    }
++  while (!feof_unlocked (fp));
++
++  /* Free the buffer.  */
++  free (line);
++  /* Close configuration file.  */
++  fclose (fp);
++
++  return result;
++}
++
++
++/* Read the source names:
++	`( <source> ( "[" "!"? (<status> "=" <action> )+ "]" )? )*'
++   */
++static service_user *
++internal_function
++nss_parse_service_list (const char *line)
++{
++  service_user *result = NULL, **nextp = &result;
++
++  while (1)
++    {
++      service_user *new_service;
++      const char *name;
++
++      while (isspace (line[0]))
++	++line;
++      if (line[0] == '\0')
++	/* No source specified.  */
++	return result;
++
++      /* Read <source> identifier.  */
++      name = line;
++      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
++	++line;
++      if (name == line)
++	return result;
++
++
++      new_service = (service_user *) xmalloc (sizeof (*new_service));
++      new_service->name = (char *) xmalloc (line - name + 1);
++
++      *((char *) __mempcpy ((char *) new_service->name, name, line - name))
++        = '\0';
++
++      /* Set default actions.  */
++      new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE;
++      new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
++      new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
++      new_service->library = NULL;
++      new_service->known.tree = NULL;
++      new_service->next = NULL;
++
++      while (isspace (line[0]))
++	++line;
++
++      if (line[0] == '[')
++	{
++	  /* Read criterions.  */
++	  do
++	    ++line;
++	  while (line[0] != '\0' && isspace (line[0]));
++
++	  do
++	    {
++	      int not;
++	      enum nss_status status;
++	      lookup_actions action;
++
++	      /* Grok ! before name to mean all statii but that one.  */
++	      not = line[0] == '!';
++	      if (not)
++		++line;
++
++	      /* Read status name.  */
++	      name = line;
++	      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
++		     && line[0] != ']')
++		++line;
++
++	      /* Compare with known statii.  */
++	      if (line - name == 7)
++		{
++		  if (__strncasecmp (name, "SUCCESS", 7) == 0)
++		    status = NSS_STATUS_SUCCESS;
++		  else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
++		    status = NSS_STATUS_UNAVAIL;
++		  else
++		    return result;
++		}
++	      else if (line - name == 8)
++		{
++		  if (__strncasecmp (name, "NOTFOUND", 8) == 0)
++		    status = NSS_STATUS_NOTFOUND;
++		  else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
++		    status = NSS_STATUS_TRYAGAIN;
++		  else
++		    return result;
++		}
++	      else
++		return result;
++
++	      while (isspace (line[0]))
++		++line;
++	      if (line[0] != '=')
++		return result;
++	      do
++		++line;
++	      while (isspace (line[0]));
++
++	      name = line;
++	      while (line[0] != '\0' && !isspace (line[0]) && line[0] != '='
++		     && line[0] != ']')
++		++line;
++
++	      if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
++		action = NSS_ACTION_RETURN;
++	      else if (line - name == 8
++		       && __strncasecmp (name, "CONTINUE", 8) == 0)
++		action = NSS_ACTION_CONTINUE;
++	      else
++		return result;
++
++	      if (not)
++		{
++		  /* Save the current action setting for this status,
++		     set them all to the given action, and reset this one.  */
++		  const lookup_actions save = new_service->actions[2 + status];
++		  new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action;
++		  new_service->actions[2 + NSS_STATUS_UNAVAIL] = action;
++		  new_service->actions[2 + NSS_STATUS_NOTFOUND] = action;
++		  new_service->actions[2 + NSS_STATUS_SUCCESS] = action;
++		  new_service->actions[2 + status] = save;
++		}
++	      else
++		new_service->actions[2 + status] = action;
++
++	      /* Skip white spaces.  */
++	      while (isspace (line[0]))
++		++line;
++	    }
++	  while (line[0] != ']');
++
++	  /* Skip the ']'.  */
++	  ++line;
++	}
++
++      *nextp = new_service;
++      nextp = &new_service->next;
++    }
++}
++
++static name_database_entry *
++internal_function
++nss_getline (char *line)
++{
++  const char *name;
++  name_database_entry *result;
++  size_t len;
++
++  /* Ignore leading white spaces.  ATTENTION: this is different from
++     what is implemented in Solaris.  The Solaris man page says a line
++     beginning with a white space character is ignored.  We regard
++     this as just another misfeature in Solaris.  */
++  while (isspace (line[0]))
++    ++line;
++
++  /* Recognize `<database> ":"'.  */
++  name = line;
++  while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':')
++    ++line;
++  if (line[0] == '\0' || name == line)
++    /* Syntax error.  */
++    return NULL;
++  *line++ = '\0';
++
++  len = strlen (name) + 1;
++
++  result = (name_database_entry *) xmalloc (sizeof (*result));
++  result->name = (char *) xmalloc (len);
++
++  /* Save the database name.  */
++  memcpy ((char *) result->name, name, len);
++
++  /* Parse the list of services.  */
++  result->service = nss_parse_service_list (line);
++
++  result->next = NULL;
++  return result;
++}
++
++
++\f
++/* Generating code for statically initialized nsswitch structures.  */
++
++
++/* Return the service-neutral suffix of the name of the service
++   library function referred to by the function F.  The result is
++   allocated with malloc.  */
++char *
++known_function_suffix (const struct function *f)
++{
++  switch (f->kind)
++    {
++    case fk_setent:
++      return saprintf ("set%sent", f->entry);
++
++    case fk_getent:
++      return saprintf ("get%sent_r", f->entry);
++
++    case fk_endent:
++      return saprintf ("end%sent", f->entry);
++
++    case fk_getby:
++      return saprintf ("get%sby%s_r", f->entry, f->key);
++
++    case fk_get:
++      return saprintf ("get%s_r", f->value_and_key);
++
++    default:
++      abort ();
++    }
++}
++
++
++/* Return the name of the service library function referred to by the
++   function F.  The result is allocated with malloc.  */
++char *
++known_function_name (const struct function *f)
++{
++  return saprintf ("_nss_%s_%s", f->service, known_function_suffix (f));
++}
++
++
++/* Write initialized known_function structures to OUT for
++   all the functions we'll use.  */
++void
++generate_known_functions (FILE *out)
++{
++  int i;
++
++  /* First, generate weak references to the functions.  The service
++     libraries depend on libc, and if these references weren't weak,
++     we'd be making libc depend circularly on the service
++     libraries.  */
++  for (i = 0; functions[i].kind; i++)
++    {
++      char *name = known_function_name (&functions[i]);
++      fprintf (out, "typeof (%s) %s __attribute__ ((weak));\n",
++               name, name);
++    }
++  fputs ("\n", out);
++
++  /* Then, a table mapping names to functions.  */
++  fputs ("static const known_function fixed_known_functions[] = {\n",
++         out);
++  for (i = 0; functions[i].kind; i++)
++    {
++      const struct function *f = &functions[i];
++      char *suffix = known_function_suffix (f);
++
++      fprintf (out, "  /* %2d */ { \"%s\", _nss_%s_%s },\n",
++               i, suffix, f->service, suffix);
++    }
++  fputs ("};\n", out);
++  fputs ("\n", out);
++}
++
++
++/* Print code to OUT for an initialized array of pointers to the
++   'known_function' structures needed for USER, which is for
++   DATABASE.  Return its name, allocated with malloc.  */
++char *
++generate_known_function_list (FILE *out,
++                              const name_database_entry *database,
++                              const service_user *user)
++{
++  char *list_name = saprintf ("fixed_%s_%s_known_funcs",
++                              database->name, user->name);
++  fprintf (out, "static const known_function *%s[] = {\n",
++           list_name);
++  int i;
++  for (i = 0; functions[i].kind; i++)
++    if (strcmp (functions[i].database, database->name) == 0
++        && strcmp (functions[i].service, user->name) == 0)
++      fprintf (out, "  &fixed_known_functions[%d], /* %s */\n",
++               i, known_function_name (&functions[i]));
++  fputs ("  NULL\n", out);
++  fputs ("};\n", out);
++  fputs ("\n", out);
++
++  return list_name;
++}
++
++
++/* Return the name of the status value STATUS, as a statically
++   allocated string.  */
++const char *
++lookup_status_name (enum nss_status status)
++{
++  switch (status)
++    {
++    case NSS_STATUS_TRYAGAIN: return "NSS_STATUS_TRYAGAIN";
++    case NSS_STATUS_UNAVAIL: return "NSS_STATUS_UNAVAIL";
++    case NSS_STATUS_NOTFOUND: return "NSS_STATUS_NOTFOUND";
++    case NSS_STATUS_SUCCESS: return "NSS_STATUS_SUCCESS";
++    case NSS_STATUS_RETURN: return "NSS_STATUS_RETURN";
++    default: abort ();
++    };
++}
++
++
++/* Return the name of ACTION as a statically allocated string.  */
++const char *
++lookup_action_name (lookup_actions action)
++{
++  switch (action)
++    {
++    case NSS_ACTION_CONTINUE: return "NSS_ACTION_CONTINUE";
++    case NSS_ACTION_RETURN: return "NSS_ACTION_RETURN";
++    default: abort ();
++    }
++}
++
++
++/* Print code to OUT for the list of service_user structures starting
++   with USER, which are all for DATABASE.  Return the name of the
++   first structure in that list, or zero if USER is NULL.  */
++char *
++generate_service_user_list (FILE *out,
++                            name_database_entry *database,
++                            service_user *user)
++{
++  if (user)
++    {
++      /* Generate the tail of the list.  */
++      char *next_name = generate_service_user_list (out, database, user->next);
++      /* Generate our known function list.  */
++      char *known_function_list_name =
++        generate_known_function_list (out, database, user);
++
++      char *name = saprintf ("fixed_%s_%s_user", database->name, user->name);
++
++      fprintf (out, "static const service_user %s = {\n", name);
++      if (next_name)
++        fprintf (out, "  (service_user *) &%s,\n", next_name);
++      else
++        fprintf (out, "  NULL, /* no next entry */\n");
++      fputs ("  {\n", out);
++      int i;
++      for (i = 0; i < sizeof (user->actions) / sizeof (user->actions[0]); i++)
++        fprintf (out, "    %s, /* %s */\n",
++                 lookup_action_name (user->actions[i]),
++                 lookup_status_name (i - 2));
++      fputs ("  },\n", out);
++      fprintf (out, "  NULL,  /* we never need the service library */\n");
++      fprintf (out, "  { .array = %s },\n", known_function_list_name);
++      fprintf (out, "  \"%s\"\n", user->name);
++      fputs ("};\n", out);
++      fputs ("\n", out);
++
++      return name;
++    }
++  else
++    return NULL;
++}
++
++
++/* Print code to OUT for the list of name_database_entry structures
++   starting with DATABASE.  Return the name of the first structure
++   in that list, or zero if DATABASE is NULL.  */
++char *
++generate_name_database_entries (FILE *out, name_database_entry *database)
++{
++  if (database)
++    {
++      char *next_name = generate_name_database_entries (out, database->next);
++      char *service_user_name
++        = generate_service_user_list (out, database, database->service);
++      char *name = saprintf ("fixed_%s_name_database", database->name);
++
++      fprintf (out, "static const name_database_entry %s = {\n", name);
++
++      if (next_name)
++        fprintf (out, "  (name_database_entry *) &%s,\n", next_name);
++      else
++        fprintf (out, "  NULL,\n");
++
++      if (service_user_name)
++        fprintf (out, "  (service_user *) &%s,\n", service_user_name);
++      else
++        fprintf (out, "  NULL,\n");
++
++      fprintf (out, "  \"%s\"\n", database->name);
++      fprintf (out, "};\n");
++      fputs ("\n", out);
++
++      return name;
++    }
++  else
++    return NULL;
++}
++
++
++void
++generate_name_database (FILE *out, name_database *service_table)
++{
++  /* Produce a linked list of the known name_database_entry
++     structures.  */
++  char *entries = generate_name_database_entries (out, service_table->entry);
++
++  /* Now produce the main structure that points to them all.  */
++  fprintf (out, "static const name_database fixed_name_database = {\n");
++  if (entries)
++    fprintf (out, "  (name_database_entry *) &%s,\n", entries);
++  else
++    fprintf (out, "  NULL,\n");
++  fputs ("  NULL /* we don't need the libraries */\n"
++         "};\n",
++         out);
++}
++
++
++\f
++/* Generating the list of service libraries we generate references to.  */
++
++/* String with revision number of the shared object files.  */
++static const char *const nss_shlib_revision = LIBNSS_FILES_SO + 15;
++
++void
++generate_service_lib_list (FILE *out, name_database *service_table)
++{
++  int i, j;
++  int printed_any = 0;
++
++  for (i = 0; functions[i].kind; i++)
++    {
++      /* Mention each service library only once.  */
++      for (j = 0; j < i; j++)
++        if (strcmp (functions[i].service, functions[j].service) == 0)
++          break;
++
++      if (j >= i)
++        {
++          if (printed_any)
++            putc (' ', out);
++          fprintf (out, "-lnss_%s",
++                   functions[i].service,
++                   nss_shlib_revision);
++          printed_any = 1;
++        }
++    }
++}
++
++\f
++/* Main.  */
++
++int
++main (int argc, char **argv)
++{
++  if (argc != 4)
++    {
++      fprintf (stderr, "usage: gen-fixed-nsswitch HEADER SERVLIBS CONFIG\n");
++      exit (1);
++    }
++
++  name_database *service_table = nss_parse_file (argv[3]);
++
++  FILE *header = fopen (argv[1], "w");
++  if (! header)
++    {
++      fprintf (stderr,
++               "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
++               argv[1], strerror (errno));
++      exit (1);
++    }
++  fputs ("/* Generated by nss/gen-fixed-nsswitch.c.  */\n", header);
++  fputs ("\n", header);
++  generate_known_functions (header);
++  generate_name_database (header, service_table);
++  fclose (header);
++
++  FILE *service_lib_list = fopen (argv[2], "w");
++  if (! service_lib_list)
++    {
++      fprintf (stderr,
++               "gen-fixed-nsswitch: couldn't open output file %s: %s\n",
++               argv[2], strerror (errno));
++      exit (1);
++    }
++  generate_service_lib_list (service_lib_list, service_table);
++  fclose (service_lib_list);
++
++  return 0;
++}
+Index: git/nss/getent.c
+===================================================================
+--- git.orig/nss/getent.c	2014-08-29 20:00:52.976070587 -0700
++++ git/nss/getent.c	2014-08-29 20:01:15.216070587 -0700
+@@ -39,6 +39,7 @@
+ #include <netinet/ether.h>
+ #include <netinet/in.h>
+ #include <sys/socket.h>
++#include <gnu/option-groups.h>
+ 
+ /* Get libc version number.  */
+ #include <version.h>
+@@ -91,6 +92,7 @@
+   fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
+ }
+ 
++#if __OPTION_EGLIBC_DB_ALIASES
+ /* This is for aliases */
+ static void
+ print_aliases (struct aliasent *alias)
+@@ -135,7 +137,9 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_DB_ALIASES */
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for ethers */
+ static int
+ ethers_keys (int number, char *key[])
+@@ -179,6 +183,7 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* This is for group */
+ static void
+@@ -301,6 +306,7 @@
+   return result;
+ }
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for hosts */
+ static void
+ print_hosts (struct hostent *host)
+@@ -598,6 +604,7 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* Now is all for passwd */
+ static void
+@@ -650,6 +657,7 @@
+   return result;
+ }
+ 
++#if __OPTION_EGLIBC_INET
+ /* This is for protocols */
+ static void
+ print_protocols (struct protoent *proto)
+@@ -805,6 +813,7 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+ /* This is for shadow */
+ static void
+@@ -871,21 +880,34 @@
+   } databases[] =
+   {
+ #define D(name) { #name, name ## _keys },
+-D(ahosts)
+-D(ahostsv4)
+-D(ahostsv6)
+-D(aliases)
+-D(ethers)
++
++#if __OPTION_EGLIBC_INET
++#define DN(name) D(name)
++#else
++#define DN(name)
++#endif
++
++#if __OPTION_EGLIBC_DB_ALIASES
++#define DA(name) D(name)
++#else
++#define DA(name)
++#endif
++
++DN(ahosts)
++DN(ahostsv4)
++DN(ahostsv6)
++DA(aliases)
++DN(ethers)
+ D(group)
+ D(gshadow)
+-D(hosts)
++DN(hosts)
+-D(initgroups)
++DN(initgroups)
+-D(netgroup)
+-D(networks)
++DN(netgroup)
++DN(networks)
+ D(passwd)
+-D(protocols)
+-D(rpc)
+-D(services)
++DN(protocols)
++DN(rpc)
++DN(services)
+ D(shadow)
+ #undef D
+     { NULL, NULL }
+Index: git/nss/getnssent_r.c
+===================================================================
+--- git.orig/nss/getnssent_r.c	2014-08-29 20:00:52.976070587 -0700
++++ git/nss/getnssent_r.c	2014-08-29 20:01:15.220070587 -0700
+@@ -16,6 +16,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <errno.h>
++#include <gnu/option-groups.h>
+ #include <netdb.h>
+ #include "nsswitch.h"
+ 
+@@ -59,11 +60,13 @@
+   } fct;
+   int no_more;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       __set_h_errno (NETDB_INTERNAL);
+       return;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Cycle through the services and run their `setXXent' functions until
+      we find an available service.  */
+@@ -101,11 +104,13 @@
+   } fct;
+   int no_more;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       __set_h_errno (NETDB_INTERNAL);
+       return;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Cycle through all the services and run their endXXent functions.  */
+   no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
+@@ -141,12 +146,14 @@
+   int no_more;
+   enum nss_status status;
+ 
++#if __OPTION_EGLIBC_INET
+   if (res && __res_maybe_init (&_res, 0) == -1)
+     {
+       *h_errnop = NETDB_INTERNAL;
+       *result = NULL;
+       return errno;
+     }
++#endif /* __OPTION_EGLIBC_INET */
+ 
+   /* Initialize status to return if no more functions are found.  */
+   status = NSS_STATUS_NOTFOUND;
+@@ -161,7 +168,7 @@
+       int is_last_nip = *nip == *last_nip;
+ 
+       status = DL_CALL_FCT (fct.f,
+-			    (resbuf, buffer, buflen, &errno, &h_errno));
++			    (resbuf, buffer, buflen, &errno, h_errnop));
+ 
+       /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
+ 	 provided buffer is too small.  In this case we should give
+Index: git/nss/Makefile
+===================================================================
+--- git.orig/nss/Makefile	2014-08-29 20:00:52.972070587 -0700
++++ git/nss/Makefile	2014-08-29 20:01:15.220070587 -0700
+@@ -18,29 +18,36 @@
+ #
+ #	Makefile for name service switch.
+ #
++include ../option-groups.mak
++
+ subdir	:= nss
+ 
+ include ../Makeconfig
+ 
+ headers			:= nss.h
+ 
+-# This is the trivial part which goes into libc itself.
+-routines		= nsswitch getnssent getnssent_r digits_dots \
+-			  $(addsuffix -lookup,$(databases))
+-
+ # These are the databases that go through nss dispatch.
+ # Caution: if you add a database here, you must add its real name
+ # in databases.def, too.
+-databases		= proto service hosts network grp pwd rpc ethers \
+-			  spwd netgrp key alias sgrp
++databases-y		= grp pwd spwd sgrp
++databases-$(OPTION_EGLIBC_INET) \
++			+= proto service hosts network rpc ethers \
++			   netgrp key
++databases-$(OPTION_EGLIBC_DB_ALIASES) += alias
++
++# This is the trivial part which goes into libc itself.
++routines-y		+= nsswitch getnssent getnssent_r \
++			  $(addsuffix -lookup,$(databases-y))
++routines-$(OPTION_EGLIBC_INET) += digits_dots
+ 
+ others                  := getent makedb
+ install-bin             := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs		+= $(makedb-modules:=.o)
+ 
+-tests			= test-netdb tst-nss-test1 test-digits-dots
+-xtests			= bug-erange
++tests			= tst-nss-test1
++tests-$(OPTION_EGLIBC_INET) += test-netdb test-digits-dots
++xtests-$(OPTION_EGLIBC_INET) += bug-erange
+ 
+ # Specify rules for the nss_* modules.  We have some services.
+ services		:= files db
+@@ -55,7 +62,7 @@
+ vpath %.c $(subdir-dirs) ../locale/programs ../intl
+ 
+ 
+-libnss_files-routines	:= $(addprefix files-,$(databases)) \
++libnss_files-routines	:= $(addprefix files-,$(databases-y)) \
+ 			   files-initgroups files-have_o_cloexec files-init
+ 
+ libnss_db-dbs		:= $(addprefix db-,\
+@@ -78,6 +85,45 @@
+ tests			+= $(tests-static)
+ endif
+ 
++ifneq ($(OPTION_EGLIBC_NSSWITCH),y)
++
++ifndef OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG
++$(error OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG variable left unset)
++endif
++
++ifndef OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS
++$(error OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS variable left unset)
++endif
++
++ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)))
++$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed config file)
++$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG))
++endif
++
++ifeq (,$(wildcard $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)))
++$(warning OPTION_EGLIBC_NSSWITCH is disabled, but fixed functions file)
++$(error does not exist: $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS))
++endif
++
++before-compile := $(objpfx)fixed-nsswitch.h
++generated := fixed-nsswitch.h
++$(objpfx)fixed-nsswitch.h $(objfpx)fixed-nsswitch-libs:	\
++    $(objpfx)gen-fixed-nsswitch				\
++    $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
++	$< $(objpfx)fixed-nsswitch.h			\
++	   $(objpfx)fixed-nsswitch-libs			\
++	   $(OPTION_EGLIBC_NSSWITCH_FIXED_CONFIG)
++
++$(objpfx)gen-fixed-nsswitch: gen-fixed-nsswitch.c	\
++    $(common-objpfx)option-groups.config		\
++    $(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)
++	$(native-compile)
++gen-fixed-nsswitch-CFLAGS =						\
++	-g3 -O -Wall							\
++	-I $(objpfx)							\
++	-DFIXED_FUNCTIONS='"$(OPTION_EGLIBC_NSSWITCH_FIXED_FUNCTIONS)"'
++endif
++
+ include ../Rules
+ 
+ ifeq (yes,$(have-selinux))
+Index: git/nss/nsswitch.c
+===================================================================
+--- git.orig/nss/nsswitch.c	2014-08-29 20:00:53.004070587 -0700
++++ git/nss/nsswitch.c	2014-08-29 20:01:15.220070587 -0700
+@@ -26,6 +26,7 @@
+ #include <stdio_ext.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ #include <aliases.h>
+ #include <grp.h>
+@@ -41,6 +42,15 @@
+ #include "../nscd/nscd_proto.h"
+ #include <sysdep.h>
+ 
++/* When OPTION_EGLIBC_NSSWITCH is disabled, we use fixed tables of
++   databases and services, generated at library build time.  Thus:
++   - We can't reconfigure individual databases, so we don't need a
++     name-to-database map.
++   - We never add databases or service libraries, or look up functions
++     at runtime, so there's no need for a lock to protect our tables.
++   See ../option-groups.def for the details.  */
++#if __OPTION_EGLIBC_NSSWITCH
++
+ /* Prototypes for the local functions.  */
+ static name_database *nss_parse_file (const char *fname) internal_function;
+ static name_database_entry *nss_getline (char *line) internal_function;
+@@ -79,6 +89,9 @@
+ 
+ __libc_lock_define_initialized (static, lock)
+ 
++#define lock_nsswitch __libc_lock_lock (lock)
++#define unlock_nsswitch __libc_lock_unlock (lock)
++
+ #if !defined DO_STATIC_NSS || defined SHARED
+ /* String with revision number of the shared object files.  */
+ static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
+@@ -93,6 +106,20 @@
+    __libc_freeres.  */
+ static name_database_entry *defconfig_entries;
+ 
++#else /* __OPTION_EGLIBC_NSSWITCH */
++
++/* Bring in the statically initialized service table we generated at
++   build time.  */
++#include "fixed-nsswitch.h"
++
++const static name_database *service_table = &fixed_name_database;
++
++/* Nothing ever changes, so there's no need to lock anything.  */
++#define lock_nsswitch (0)
++#define unlock_nsswitch (0)
++
++#endif /* __OPTION_EGLIBC_NSSWITCH */
++
+ 
+ #ifdef USE_NSCD
+ /* Nonzero if this is the nscd process.  */
+@@ -109,20 +136,22 @@
+ 		       const char *defconfig, service_user **ni)
+ {
+   /* Prevent multiple threads to change the service table.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Reconsider database variable in case some other thread called
+      `__nss_configure_lookup' while we waited for the lock.  */
+   if (*ni != NULL)
+     {
+-      __libc_lock_unlock (lock);
++      unlock_nsswitch;
+       return 0;
+     }
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+   /* Are we initialized yet?  */
+   if (service_table == NULL)
+     /* Read config file.  */
+     service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
++#endif
+ 
+   /* Test whether configuration data is available.  */
+   if (service_table != NULL)
+@@ -144,6 +173,7 @@
+ 	    *ni = entry->service;
+     }
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+   /* No configuration data is available, either because nsswitch.conf
+      doesn't exist or because it doesn't have a line for this database.
+ 
+@@ -166,13 +196,23 @@
+ 	    {
+ 	      entry->next = defconfig_entries;
+ 	      entry->service = *ni;
+-	      entry->name[0] = '\0';
++	      entry->name = "";
+ 	      defconfig_entries = entry;
+ 	    }
+ 	}
+     }
++#else
++  /* Without the dynamic behavior, we can't process defconfig.  The
++     databases the user specified at library build time are all you
++     get.  */
++  if (*ni == NULL)
++    {
++      unlock_nsswitch;
++      return -1;
++    }
++#endif
+ 
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return *ni != NULL ? 0 : -1;
+ }
+@@ -252,6 +292,7 @@
+ libc_hidden_def (__nss_next2)
+ 
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+ int
+ attribute_compat_text_section
+ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
+@@ -300,13 +341,13 @@
+     }
+ 
+   /* Prevent multiple threads to change the service table.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Install new rules.  */
+   *databases[cnt].dbp = new_db;
+   __nss_database_custom[cnt] = true;
+ 
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return 0;
+ }
+@@ -402,7 +443,7 @@
+   void **found, *result;
+ 
+   /* We now modify global data.  Protect it.  */
+-  __libc_lock_lock (lock);
++  lock_nsswitch;
+ 
+   /* Search the tree of functions previously requested.  Data in the
+      tree are `known_function' structures, whose first member is a
+@@ -413,7 +454,7 @@
+      enough to a pointer to our structure to use as a lookup key that
+      will be passed to `known_compare' (above).  */
+ 
+-  found = __tsearch (&fct_name, &ni->known, &known_compare);
++  found = __tsearch (&fct_name, &ni->known.tree, &known_compare);
+   if (found == NULL)
+     /* This means out-of-memory.  */
+     result = NULL;
+@@ -440,7 +481,7 @@
+ #endif
+ 	  /* Oops.  We can't instantiate this node properly.
+ 	     Remove it from the tree.  */
+-	  __tdelete (&fct_name, &ni->known, &known_compare);
++	  __tdelete (&fct_name, &ni->known.tree, &known_compare);
+ 	  free (known);
+ 	  result = NULL;
+ 	}
+@@ -520,13 +561,43 @@
+     }
+ 
+   /* Remove the lock.  */
+-  __libc_lock_unlock (lock);
++  unlock_nsswitch;
+ 
+   return result;
+ }
+ libc_hidden_def (__nss_lookup_function)
+ 
+ 
++#else /* below if ! __OPTION_EGLIBC_NSSWITCH */
++
++
++int
++__nss_configure_lookup (const char *dbname, const char *service_line)
++{
++  /* We can't dynamically configure lookup without
++     OPTION_EGLIBC_NSSWITCH.  */
++  __set_errno (EINVAL);
++  return -1;
++}
++
++
++void *
++__nss_lookup_function (service_user *ni, const char *fct_name)
++{
++  int i;
++  const known_function **known = ni->known.array;
++
++  for (i = 0; known[i]; i++)
++    if (strcmp (fct_name, known[i]->fct_name) == 0)
++      return known[i]->fct_ptr;
++
++  return NULL;
++}
++libc_hidden_def (__nss_lookup_function)
++#endif
++
++
++#if __OPTION_EGLIBC_NSSWITCH
+ static name_database *
+ internal_function
+ nss_parse_file (const char *fname)
+@@ -632,8 +703,10 @@
+ 					     + (line - name + 1));
+       if (new_service == NULL)
+ 	return result;
++      new_service->name = (char *) (new_service + 1);
+ 
+-      *((char *) __mempcpy (new_service->name, name, line - name)) = '\0';
++      *((char *) __mempcpy ((char *) new_service->name, name, line - name))
++        = '\0';
+ 
+       /* Set default actions.  */
+       new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE;
+@@ -642,7 +715,7 @@
+       new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
+       new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
+       new_service->library = NULL;
+-      new_service->known = NULL;
++      new_service->known.tree = NULL;
+       new_service->next = NULL;
+ 
+       while (isspace (line[0]))
+@@ -778,9 +851,10 @@
+   result = (name_database_entry *) malloc (sizeof (name_database_entry) + len);
+   if (result == NULL)
+     return NULL;
++  result->name = (char *) (result + 1);
+ 
+   /* Save the database name.  */
+-  memcpy (result->name, name, len);
++  memcpy ((char *) result->name, name, len);
+ 
+   /* Parse the list of services.  */
+   result->service = nss_parse_service_list (line);
+@@ -816,6 +890,7 @@
+   return *currentp;
+ }
+ #endif
++#endif /* __OPTION_EGLIBC_NSSWITCH */
+ 
+ 
+ #if defined SHARED && defined USE_NSCD
+@@ -834,6 +909,7 @@
+ }
+ 
+ 
++#if __OPTION_EGLIBC_INET
+ /* Called by nscd and nscd alone.  */
+ void
+ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
+@@ -857,8 +933,10 @@
+   __nss_not_use_nscd_services = -1;
+   __nss_not_use_nscd_netgroup = -1;
+ }
++#endif /* __OPTION_EGLIBC_INET */
+ #endif
+ 
++#if __OPTION_EGLIBC_NSSWITCH
+ static void
+ free_database_entries (name_database_entry *entry)
+ {
+@@ -871,8 +949,8 @@
+ 	{
+ 	  service_user *olds = service;
+ 
+-	  if (service->known != NULL)
+-	    __tdestroy (service->known, free);
++	  if (service->known.tree != NULL)
++	    __tdestroy (service->known.tree, free);
+ 
+ 	  service = service->next;
+ 	  free (olds);
+@@ -926,3 +1004,4 @@
+ 
+   free (top);
+ }
++#endif /* __OPTION_EGLIBC_NSSWITCH */
+Index: git/nss/nsswitch.h
+===================================================================
+--- git.orig/nss/nsswitch.h	2014-08-29 20:00:53.012070587 -0700
++++ git/nss/nsswitch.h	2014-08-29 20:01:15.220070587 -0700
+@@ -65,10 +65,20 @@
+   lookup_actions actions[5];
+   /* Link to the underlying library object.  */
+   service_library *library;
+-  /* Collection of known functions.  */
+-  void *known;
++  /* Collection of known functions.
++
++     With OPTION_EGLIBC_NSSWITCH enabled, this is the root of a
++     'tsearch'-style tree.
++
++     With OPTION_EGLIBC_NSSWITCH disabled, this is an array of
++     pointers to known_function structures, NULL-terminated.  */
++  union
++  {
++    void *tree;
++    const known_function **array;
++  } known;
+   /* Name of the service (`files', `dns', `nis', ...).  */
+-  char name[0];
++  const char *name;
+ } service_user;
+ 
+ /* To access the action based on the status value use this macro.  */
+@@ -82,7 +92,7 @@
+   /* List of service to be used.  */
+   service_user *service;
+   /* Name of the database.  */
+-  char name[0];
++  const char *name;
+ } name_database_entry;
+ 
+ 
+Index: git/posix/bug-regex1.c
+===================================================================
+--- git.orig/posix/bug-regex1.c	2014-08-29 20:00:53.184070587 -0700
++++ git/posix/bug-regex1.c	2014-08-29 20:01:15.220070587 -0700
+@@ -4,6 +4,7 @@
+ #include <string.h>
+ #include <regex.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ int
+ main (void)
+@@ -17,7 +18,9 @@
+   memset (&regex, '\0', sizeof (regex));
+ 
+   setlocale (LC_ALL, "de_DE.ISO-8859-1");
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+   fwide (stdout, -1);
++#endif
+ 
+   re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_DEBUG);
+ 
+Index: git/posix/bug-regex6.c
+===================================================================
+--- git.orig/posix/bug-regex6.c	2014-08-29 20:00:53.204070587 -0700
++++ git/posix/bug-regex6.c	2014-08-29 20:01:15.220070587 -0700
+@@ -22,6 +22,7 @@
+ #include <string.h>
+ #include <sys/types.h>
+ #include <regex.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -30,7 +31,12 @@
+   regex_t re;
+   regmatch_t mat[10];
+   int i, j, ret = 0;
+-  const char *locales[] = { "C", "de_DE.UTF-8" };
++  const char *locales[] = {
++    "C",
++#if __OPTION_EGLIBC_LOCALE_CODE
++    "de_DE.UTF-8"
++#endif
++  };
+   const char *string = "http://www.regex.com/pattern/matching.html#intro";
+   regmatch_t expect[10] = {
+     { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 },
+Index: git/posix/fnmatch.c
+===================================================================
+--- git.orig/posix/fnmatch.c	2014-08-29 20:00:53.208070587 -0700
++++ git/posix/fnmatch.c	2014-08-29 20:01:15.220070587 -0700
+@@ -30,6 +30,10 @@
+ #include <ctype.h>
+ #include <string.h>
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined STDC_HEADERS || defined _LIBC
+ # include <stdlib.h>
+ #endif
+@@ -131,7 +135,7 @@
+ #   define ISWCTYPE(WC, WT)	iswctype (WC, WT)
+ #  endif
+ 
+-#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
++#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS && _LIBC && __OPTION_EGLIBC_LOCALE_CODE)
+ /* In this case we are implementing the multibyte character handling.  */
+ #   define HANDLE_MULTIBYTE	1
+ #  endif
+Index: git/posix/fnmatch_loop.c
+===================================================================
+--- git.orig/posix/fnmatch_loop.c	2014-08-29 20:00:53.220070587 -0700
++++ git/posix/fnmatch_loop.c	2014-08-29 20:01:15.220070587 -0700
+@@ -15,6 +15,8 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
++
+ #include <stdint.h>
+ 
+ struct STRUCT
+@@ -54,10 +56,15 @@
+   const char *collseq = (const char *)
+     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+ # else
++#  if __OPTION_EGLIBC_LOCALE_CODE
+   const UCHAR *collseq = (const UCHAR *)
+     _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+-# endif
+-#endif
++#   define COLLSEQ_BYTE_LOOKUP(ix) (collseq[(ix)])
++#  else
++#   define COLLSEQ_BYTE_LOOKUP(ix) (ix)
++#  endif /* __OPTION_EGLIBC_LOCALE_CODE */
++# endif /* WIDE_CHAR_VERSION */
++#endif /* _LIBC */
+ 
+   while ((c = *p++) != L('\0'))
+     {
+@@ -277,7 +284,7 @@
+ 		    /* Leave room for the null.  */
+ 		    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
+ 		    size_t c1 = 0;
+-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
++#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ 		    wctype_t wt;
+ #endif
+ 		    const CHAR *startp = p;
+@@ -307,7 +314,7 @@
+ 		      }
+ 		    str[c1] = L('\0');
+ 
+-#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
++#if defined _LIBC ? __OPTION_POSIX_C_LANG_WIDE_CHAR : (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
+ 		    wt = IS_CHAR_CLASS (str);
+ 		    if (wt == 0)
+ 		      /* Invalid character class name.  */
+@@ -681,8 +688,10 @@
+ 			else
+ 			  lcollseq = __collseq_table_lookup (collseq, cold);
+ # else
+-			fcollseq = collseq[fn];
+-			lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
++			fcollseq = COLLSEQ_BYTE_LOOKUP (fn);
++			lcollseq = (is_seqval
++                                    ? cold
++                                    : COLLSEQ_BYTE_LOOKUP ((UCHAR) cold));
+ # endif
+ 
+ 			is_seqval = 0;
+@@ -858,7 +867,7 @@
+ 				    goto matched;
+ 				  }
+ # else
+-				hcollseq = collseq[cend];
++				hcollseq = COLLSEQ_BYTE_LOOKUP (cend);
+ # endif
+ 			      }
+ 
+Index: git/posix/glob.c
+===================================================================
+--- git.orig/posix/glob.c	2014-08-29 20:00:53.232070587 -0700
++++ git/posix/glob.c	2014-08-29 20:01:15.220070587 -0700
+@@ -25,6 +25,9 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stddef.h>
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
+ 
+ /* Outcomment the following line for production quality code.  */
+ /* #define NDEBUG 1 */
+@@ -607,6 +610,7 @@
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    home_dir = "c:/users/default"; /* poor default */
+ #  else
++#   if ! _LIBC || __OPTION_EGLIBC_GETLOGIN
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    {
+ 	      int success;
+@@ -623,19 +627,19 @@
+ 	      if (success)
+ 		{
+ 		  struct passwd *p;
+-#   if defined HAVE_GETPWNAM_R || defined _LIBC
++#    if defined HAVE_GETPWNAM_R || defined _LIBC
+ 		  long int pwbuflen = GETPW_R_SIZE_MAX ();
+ 		  char *pwtmpbuf;
+ 		  struct passwd pwbuf;
+ 		  int malloc_pwtmpbuf = 0;
+ 		  int save = errno;
+ 
+-#    ifndef _LIBC
++#     ifndef _LIBC
+ 		  if (pwbuflen == -1)
+ 		    /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
+ 		       Try a moderate value.  */
+ 		    pwbuflen = 1024;
+-#    endif
++#     endif
+ 		  if (__libc_use_alloca (alloca_used + pwbuflen))
+ 		    pwtmpbuf = alloca_account (pwbuflen, alloca_used);
+ 		  else
+@@ -682,9 +686,9 @@
+ 			}
+ 		      __set_errno (save);
+ 		    }
+-#   else
++#    else
+ 		  p = getpwnam (name);
+-#   endif
++#    endif
+ 		  if (p != NULL)
+ 		    {
+ 		      if (!malloc_pwtmpbuf)
+@@ -713,6 +717,7 @@
+ 		    }
+ 		}
+ 	    }
++#   endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    {
+ 	      if (flags & GLOB_TILDE_CHECK)
+Index: git/posix/Makefile
+===================================================================
+--- git.orig/posix/Makefile	2014-08-29 20:00:53.160070587 -0700
++++ git/posix/Makefile	2014-08-29 20:01:15.220070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for POSIX portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= posix
+ 
+ include ../Makeconfig
+@@ -43,13 +45,24 @@
+ 	getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid	      \
+ 	getresuid getresgid setresuid setresgid				      \
+ 	pathconf sysconf fpathconf					      \
+-	glob glob64 fnmatch regex					      \
++	glob glob64 fnmatch						      \
+ 	confstr								      \
+ 	getopt getopt1 getopt_init					      \
+ 	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
+ 	sched_primin sched_rr_gi sched_getaffinity sched_setaffinity	      \
+-	getaddrinfo gai_strerror wordexp				      \
+ 	pread pwrite pread64 pwrite64					      \
++	posix_madvise							      \
++	get_child_max sched_cpucount sched_cpualloc sched_cpufree
++
++routines-$(OPTION_EGLIBC_INET) += getaddrinfo gai_strerror
++
++ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
++routines-$(OPTION_POSIX_REGEXP) += regex
++else
++routines-$(OPTION_POSIX_REGEXP) += xregex
++endif
++
++routines-$(OPTION_EGLIBC_SPAWN) +=					      \
+ 	spawn_faction_init spawn_faction_destroy spawn_faction_addclose	      \
+ 	spawn_faction_addopen spawn_faction_adddup2			      \
+ 	spawnattr_init spawnattr_destroy				      \
+@@ -57,41 +70,53 @@
+ 	spawnattr_getflags spawnattr_setflags				      \
+ 	spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni	      \
+ 	spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \
+-	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
+-	posix_madvise							      \
+-	get_child_max sched_cpucount sched_cpualloc sched_cpufree
++	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam
++routines-$(OPTION_EGLIBC_WORDEXP) += wordexp
+ 
+ aux		:= init-posix environ
+-tests		:= tstgetopt testfnm runtests runptests	     \
++tests		:= tstgetopt testfnm runtests	     \
+ 		   tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \
+-		   tst-getlogin tst-mmap tst-getaddrinfo tst-truncate \
+-		   tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \
+-		   tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \
+-		   tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \
+-		   bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \
+-		   bug-regex13 bug-regex14 bug-regex15 bug-regex16 \
+-		   bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
+-		   bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
+-		   bug-regex25 bug-regex26 bug-regex27 bug-regex28 \
+-		   bug-regex29 bug-regex30 bug-regex31 bug-regex32 \
+-		   bug-regex33 tst-nice tst-nanosleep tst-regex2 \
+-		   transbug tst-rxspencer tst-pcre tst-boost \
+-		   bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
+-		   tst-getaddrinfo2 bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
++		   tst-getlogin tst-mmap tst-truncate \
++		   tst-truncate64 tst-fork tst-dir \
++		   tst-chmod bug-regex2 bug-regex3 bug-regex4 \
++		   tst-gnuglob bug-regex6 bug-regex7 \
++		   bug-regex8 bug-regex9 bug-regex10 bug-regex12 \
++		   bug-regex14 bug-regex15 \
++		   bug-regex21 bug-regex24 \
++		   bug-regex27 bug-regex28 bug-regex29 bug-regex30 \
++		   bug-regex31 \
++		   tst-nice tst-nanosleep \
++		   transbug \
++		   tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
++		   bug-glob1 bug-glob2 bug-glob3 tst-sysconf \
+ 		   tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
+ 		   tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
+ 		   tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
+-		   tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
+-		   tst-rfc3484-3 \
+-		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
++		   tst-execvp3 tst-execvp4 \
++		   tst-fnmatch2 tst-cpucount tst-cpuset \
+ 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
+ 		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
+ 		   tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
+ 		   tst-fnmatch3 bug-regex36
+-xtests		:= bug-ga2
++tests-$(OPTION_EGLIBC_LOCALE_CODE)					    \
++		+= tst-fnmatch tst-regexloc bug-regex1 bug-regex5 \
++		   bug-regex23 bug-regex25 bug-regex32 bug-regex33
++tests-$(OPTION_EGLIBC_INET) \
++	        += tst-getaddrinfo bug-ga1 tst-getaddrinfo2 \
++		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 tst-getaddrinfo3
++tests-$(OPTION_POSIX_REGEXP_GLIBC) \
++		+= runptests bug-regex11 bug-regex13 bug-regex16 \
++		   tst-regex2 tst-rxspencer tst-pcre tst-boost
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP_GLIBC))
++tests           += tst-regex bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
++		   bug-regex22 bug-regex26
++endif
++xtests-$(OPTION_EGLIBC_INET) += bug-ga2
+ ifeq (yes,$(build-shared))
+ test-srcs	:= globtest
+-tests           += wordexp-test tst-exec tst-spawn
++tests           += tst-exec
++tests-$(OPTION_EGLIBC_SPAWN) += tst-spawn
++tests-$(OPTION_EGLIBC_WORDEXP) += wordexp-test
+ endif
+ tests-static	= tst-exec-static tst-spawn-static
+ tests		+= $(tests-static)
+@@ -117,7 +142,10 @@
+ 
+ ifeq ($(run-built-tests),yes)
+ ifeq (yes,$(build-shared))
+-tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
++tests-special += $(objpfx)globtest.out
++ifeq (y,$(OPTION_EGLIBC_WORDEXP))
++tests-special += $(objpfx)wordexp-tst.out
++endif
+ endif
+ endif
+ 
+@@ -125,12 +153,16 @@
+ # XXX Please note that for now we ignore the result of this test.
+ tests-special += $(objpfx)annexc.out
+ ifeq ($(run-built-tests),yes)
+-tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
++tests-special += $(objpfx)bug-regex2-mem.out \
+ 		 $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
+-		 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
+-		 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
++		 $(objpfx)tst-getconf.out \
+ 		 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
+ 		 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
++ifeq (y,$(OPTION_POSIX_REGEXP_GLIBC))
++tests-special += $(objpfx)bug-regex14-mem.out $(objpfx)tst-rxspencer-no-utf8-mem.out \
++  		 $(objpfx)tst-pcre-mem.out $(objpfx)tst-boost-mem.out
++endif
++
+ xtests-special += $(objpfx)bug-ga2-mem.out
+ endif
+ 
+@@ -143,6 +175,8 @@
+ 	$(SHELL) $< $(common-objpfx) '$(test-via-rtld-prefix)' \
+ 		'$(test-program-prefix)' '$(test-wrapper-env)'; \
+ 	$(evaluate-test)
++LDLIBS-globtest += $(shell cat $(common-objpfx)nss/fixed-nsswitch-libs)
++
+ $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test
+ 	$(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \
+ 		 '$(run-program-env)' '$(test-program-prefix-after-env)'; \
+@@ -205,7 +239,10 @@
+ tst-chmod-ARGS = $(objdir)
+ tst-vfork3-ARGS = --test-dir=$(objpfx)
+ 
+-tst-rxspencer-ARGS = --utf8 rxspencer/tests
++tst-rxspencer-ARGS = rxspencer/tests
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++tst-rxspencer-ARGS += --utf8
++endif
+ tst-rxspencer-no-utf8-ARGS = rxspencer/tests
+ tst-pcre-ARGS = PCRE.tests
+ tst-boost-ARGS = BOOST.tests
+Index: git/posix/regcomp.c
+===================================================================
+--- git.orig/posix/regcomp.c	2014-08-29 20:00:53.264070587 -0700
++++ git/posix/regcomp.c	2014-08-29 20:01:15.224070587 -0700
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
+ static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
+ 					  size_t length, reg_syntax_t syntax);
+@@ -305,7 +306,7 @@
+ {
+   re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+   int node_cnt;
+-  int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
++  int icase = (dfa_mb_cur_max (dfa) == 1 && (bufp->syntax & RE_ICASE));
+   for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
+     {
+       int node = init_state->nodes.elems[node_cnt];
+@@ -315,9 +316,9 @@
+ 	{
+ 	  re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
+ #ifdef RE_ENABLE_I18N
+-	  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
++	  if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
+ 	    {
+-	      unsigned char *buf = alloca (dfa->mb_cur_max), *p;
++	      unsigned char *buf = alloca (dfa_mb_cur_max (dfa)), *p;
+ 	      wchar_t wc;
+ 	      mbstate_t state;
+ 
+@@ -348,7 +349,11 @@
+ 		  re_set_fastmap (fastmap, icase, ch);
+ 	    }
+ 	}
+-#ifdef RE_ENABLE_I18N
++
++      /* When OPTION_EGLIBC_LOCALE_CODE is disabled, the current
++         locale is always C, which has no rules and no multi-byte
++         characters.  */
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+       else if (type == COMPLEX_BRACKET)
+ 	{
+ 	  re_charset_t *cset = dfa->nodes[node].opr.mbcset;
+@@ -376,7 +381,7 @@
+ 	     i.e. where we would not find an invalid sequence.  This only
+ 	     applies to multibyte character sets; for single byte character
+ 	     sets, the SIMPLE_BRACKET again suffices.  */
+-	  if (dfa->mb_cur_max > 1
++	  if (dfa_mb_cur_max (dfa) > 1
+ 	      && (cset->nchar_classes || cset->non_match || cset->nranges
+ # ifdef _LIBC
+ 		  || cset->nequiv_classes
+@@ -404,7 +409,7 @@
+ 		  memset (&state, '\0', sizeof (state));
+ 		  if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
+ 		    re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+-		  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
++		  if ((bufp->syntax & RE_ICASE) && dfa_mb_cur_max (dfa) > 1)
+ 		    {
+ 		      if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
+ 			  != (size_t) -1)
+@@ -413,7 +418,7 @@
+ 		}
+ 	    }
+ 	}
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+       else if (type == OP_PERIOD
+ #ifdef RE_ENABLE_I18N
+ 	       || type == OP_UTF8_PERIOD
+@@ -856,11 +861,15 @@
+ 
+   dfa->mb_cur_max = MB_CUR_MAX;
+ #ifdef _LIBC
+-  if (dfa->mb_cur_max == 6
++  if (dfa_mb_cur_max (dfa) == 6
+       && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
+     dfa->is_utf8 = 1;
++# if __OPTION_EGLIBC_LOCALE_CODE
+   dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
+ 		       != 0);
++# else
++  dfa->map_notascii = 0;
++# endif
+ #else
+ # ifdef HAVE_LANGINFO_CODESET
+   codeset_name = nl_langinfo (CODESET);
+@@ -886,7 +895,7 @@
+ #endif
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     {
+       if (dfa->is_utf8)
+ 	dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
+@@ -1784,7 +1793,7 @@
+   token->word_char = 0;
+ #ifdef RE_ENABLE_I18N
+   token->mb_partial = 0;
+-  if (input->mb_cur_max > 1 &&
++  if (string_mb_cur_max (input) > 1 &&
+       !re_string_first_byte (input, re_string_cur_idx (input)))
+     {
+       token->type = CHARACTER;
+@@ -1805,7 +1814,7 @@
+       token->opr.c = c2;
+       token->type = CHARACTER;
+ #ifdef RE_ENABLE_I18N
+-      if (input->mb_cur_max > 1)
++      if (string_mb_cur_max (input) > 1)
+ 	{
+ 	  wint_t wc = re_string_wchar_at (input,
+ 					  re_string_cur_idx (input) + 1);
+@@ -1919,7 +1928,7 @@
+ 
+   token->type = CHARACTER;
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1)
++  if (string_mb_cur_max (input) > 1)
+     {
+       wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
+       token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+@@ -2019,7 +2028,7 @@
+   token->opr.c = c;
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1 &&
++  if (string_mb_cur_max (input) > 1 &&
+       !re_string_first_byte (input, re_string_cur_idx (input)))
+     {
+       token->type = CHARACTER;
+@@ -2242,7 +2251,7 @@
+ 	  return NULL;
+ 	}
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  while (!re_string_eoi (regexp)
+ 		 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
+@@ -2380,7 +2389,7 @@
+ 	  *err = REG_ESPACE;
+ 	  return NULL;
+ 	}
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	dfa->has_mb_node = 1;
+       break;
+     case OP_WORD:
+@@ -2686,7 +2695,7 @@
+        However, for !_LIBC we have no collation elements: if the
+        character set is single byte, the single byte character set
+        that we build below suffices.  parse_bracket_exp passes
+-       no MBCSET if dfa->mb_cur_max == 1.  */
++       no MBCSET if dfa_mb_cur_max (dfa) == 1.  */
+     if (mbcset)
+       {
+ 	/* Check the space of the arrays.  */
+@@ -2782,7 +2791,13 @@
+ 		   reg_syntax_t syntax, reg_errcode_t *err)
+ {
+ #ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+   const unsigned char *collseqmb;
++# define COLLSEQMB_LOOKUP(ix) (collseqmb[(ix)])
++#else
++# define COLLSEQMB_LOOKUP(ix) (ix)
++#endif
++
+   const char *collseqwc;
+   uint32_t nrules;
+   int32_t table_size;
+@@ -2830,18 +2845,20 @@
+ 	  if (MB_CUR_MAX == 1)
+ 	  */
+ 	  if (nrules == 0)
+-	    return collseqmb[br_elem->opr.ch];
++	    return COLLSEQMB_LOOKUP (br_elem->opr.ch);
+ 	  else
+ 	    {
+ 	      wint_t wc = __btowc (br_elem->opr.ch);
+ 	      return __collseq_table_lookup (collseqwc, wc);
+ 	    }
+ 	}
++#if __OPTION_EGLIBC_LOCALE_CODE
+       else if (br_elem->type == MB_CHAR)
+ 	{
+ 	  if (nrules != 0)
+ 	    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+ 	}
++#endif
+       else if (br_elem->type == COLL_SYM)
+ 	{
+ 	  size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+@@ -2872,11 +2889,11 @@
+ 		{
+ 		  /* No valid character.  Match it as a single byte
+ 		     character.  */
+-		  return collseqmb[br_elem->opr.name[0]];
++		  return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
+ 		}
+ 	    }
+ 	  else if (sym_name_len == 1)
+-	    return collseqmb[br_elem->opr.name[0]];
++	    return COLLSEQMB_LOOKUP (br_elem->opr.name[0]);
+ 	}
+       return UINT_MAX;
+     }
+@@ -2916,7 +2933,7 @@
+ 	 However, if we have no collation elements, and the character set
+ 	 is single byte, the single byte character set that we
+ 	 build below suffices. */
+-      if (nrules > 0 || dfa->mb_cur_max > 1)
++      if (nrules > 0 || dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  /* Check the space of the arrays.  */
+ 	  if (BE (*range_alloc == mbcset->nranges, 0))
+@@ -2953,7 +2970,7 @@
+ 	  if (MB_CUR_MAX == 1)
+ 	  */
+ 	  if (nrules == 0)
+-	    ch_collseq = collseqmb[ch];
++	    ch_collseq = COLLSEQMB_LOOKUP (ch);
+ 	  else
+ 	    ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+ 	  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+@@ -3031,7 +3048,10 @@
+   re_bitset_ptr_t sbcset;
+ #ifdef RE_ENABLE_I18N
+   re_charset_t *mbcset;
+-  int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
++  int coll_sym_alloc = 0, range_alloc = 0;
++#if __OPTION_EGLIBC_LOCALE_CODE
++  int mbchar_alloc = 0;
++#endif
+   int equiv_class_alloc = 0, char_class_alloc = 0;
+ #endif /* not RE_ENABLE_I18N */
+   int non_match = 0;
+@@ -3039,9 +3059,15 @@
+   int token_len;
+   int first_round = 1;
+ #ifdef _LIBC
++#if __OPTION_EGLIBC_LOCALE_CODE
+   collseqmb = (const unsigned char *)
+     _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+   nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++#else
++  /* This is true when OPTION_EGLIBC_LOCALE_CODE is disabled, but the
++     compiler can't figure that out.  */
++  nrules = 0;
++#endif
+   if (nrules)
+     {
+       /*
+@@ -3169,7 +3195,7 @@
+ #else
+ # ifdef RE_ENABLE_I18N
+ 	  *err = build_range_exp (sbcset,
+-				  dfa->mb_cur_max > 1 ? mbcset : NULL,
++				  dfa_mb_cur_max (dfa) > 1 ? mbcset : NULL,
+ 				  &range_alloc, &start_elem, &end_elem);
+ # else
+ 	  *err = build_range_exp (sbcset, &start_elem, &end_elem);
+@@ -3185,7 +3211,7 @@
+ 	    case SB_CHAR:
+ 	      bitset_set (sbcset, start_elem.opr.ch);
+ 	      break;
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+ 	    case MB_CHAR:
+ 	      /* Check whether the array has enough space.  */
+ 	      if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+@@ -3203,7 +3229,7 @@
+ 		}
+ 	      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
+ 	      break;
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+ 	    case EQUIV_CLASS:
+ 	      *err = build_equiv_class (sbcset,
+ #ifdef RE_ENABLE_I18N
+@@ -3253,11 +3279,11 @@
+ 
+ #ifdef RE_ENABLE_I18N
+   /* Ensure only single byte characters are set.  */
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     bitset_mask (sbcset, dfa->sb_char);
+ 
+   if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
+-      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
++      || mbcset->nranges || (dfa_mb_cur_max (dfa) > 1 && (mbcset->nchar_classes
+ 						     || mbcset->non_match)))
+     {
+       bin_tree_t *mbc_tree;
+@@ -3326,7 +3352,7 @@
+ 		       re_token_t *token, int token_len, re_dfa_t *dfa,
+ 		       reg_syntax_t syntax, int accept_hyphen)
+ {
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+   int cur_char_size;
+   cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
+   if (cur_char_size > 1)
+@@ -3336,7 +3362,7 @@
+       re_string_skip_bytes (regexp, cur_char_size);
+       return REG_NOERROR;
+     }
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+   re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+   if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+       || token->type == OP_OPEN_EQUIV_CLASS)
+@@ -3416,7 +3442,9 @@
+ build_equiv_class (bitset_t sbcset, const unsigned char *name)
+ #endif /* not RE_ENABLE_I18N */
+ {
+-#ifdef _LIBC
++  /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C locale
++     is supported; it has no collation rules.  */
++#if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+   uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+   if (nrules != 0)
+     {
+@@ -3488,7 +3516,7 @@
+       mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
+     }
+   else
+-#endif /* _LIBC */
++#endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+     {
+       if (BE (strlen ((const char *) name) != 1, 0))
+ 	return REG_ECOLLATE;
+@@ -3522,7 +3550,7 @@
+       && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
+     name = "alpha";
+ 
+-#ifdef RE_ENABLE_I18N
++#if defined RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE
+   /* Check the space of the arrays.  */
+   if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+     {
+@@ -3538,7 +3566,7 @@
+       *char_class_alloc = new_char_class_alloc;
+     }
+   mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
+-#endif /* RE_ENABLE_I18N */
++#endif /* RE_ENABLE_I18N && __OPTION_EGLIBC_LOCALE_CODE */
+ 
+ #define BUILD_CHARCLASS_LOOP(ctype_func)	\
+   do {						\
+@@ -3649,7 +3677,7 @@
+ 
+ #ifdef RE_ENABLE_I18N
+   /* Ensure only single byte characters are set.  */
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     bitset_mask (sbcset, dfa->sb_char);
+ #endif
+ 
+@@ -3661,7 +3689,7 @@
+     goto build_word_op_espace;
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (dfa->mb_cur_max > 1)
++  if (dfa_mb_cur_max (dfa) > 1)
+     {
+       bin_tree_t *mbc_tree;
+       /* Build a tree for complex bracket.  */
+Index: git/posix/regexec.c
+===================================================================
+--- git.orig/posix/regexec.c	2014-08-29 20:00:53.268070587 -0700
++++ git/posix/regexec.c	2014-08-29 20:01:15.224070587 -0700
+@@ -18,6 +18,7 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <stdint.h>
++#include <gnu/option-groups.h>
+ 
+ static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+ 				     int n) internal_function;
+@@ -186,11 +187,11 @@
+ static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
+ 				    const re_string_t *input, int idx)
+      internal_function;
+-# ifdef _LIBC
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+ static unsigned int find_collation_sequence_value (const unsigned char *mbs,
+ 						   size_t name_len)
+      internal_function;
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ #endif /* RE_ENABLE_I18N */
+ static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
+ 				       const re_dfastate_t *state,
+@@ -255,25 +256,9 @@
+   return err != REG_NOERROR;
+ }
+ 
+-#ifdef _LIBC
+-# include <shlib-compat.h>
+-versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
+-
+-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+-__typeof__ (__regexec) __compat_regexec;
+-
+-int
+-attribute_compat_text_section
+-__compat_regexec (const regex_t *__restrict preg,
+-		  const char *__restrict string, size_t nmatch,
+-		  regmatch_t pmatch[], int eflags)
+-{
+-  return regexec (preg, string, nmatch, pmatch,
+-		  eflags & (REG_NOTBOL | REG_NOTEOL));
+-}
+-compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+-# endif
+-#endif
++/* EGLIBC: The code that used to be here was move to a separate file
++   so that it can be shared with xregex.c.  */
++#include "regexec-compat.c"
+ 
+ /* Entry points for GNU code.  */
+ 
+@@ -728,7 +713,7 @@
+   incr = (range < 0) ? -1 : 1;
+   left_lim = (range < 0) ? start + range : start;
+   right_lim = (range < 0) ? start : start + range;
+-  sb = dfa->mb_cur_max == 1;
++  sb = dfa_mb_cur_max (dfa) == 1;
+   match_kind =
+     (fastmap
+      ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+@@ -3448,7 +3433,7 @@
+ 	  if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+ 	    goto out_free;
+ 
+-	  if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
++	  if (dest_states[i] != dest_states_word[i] && dfa_mb_cur_max (dfa) > 1)
+ 	    need_word_trtable = 1;
+ 
+ 	  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+@@ -3590,7 +3575,7 @@
+       else if (type == OP_PERIOD)
+ 	{
+ #ifdef RE_ENABLE_I18N
+-	  if (dfa->mb_cur_max > 1)
++	  if (dfa_mb_cur_max (dfa) > 1)
+ 	    bitset_merge (accepts, dfa->sb_char);
+ 	  else
+ #endif
+@@ -3641,7 +3626,7 @@
+ 		  continue;
+ 		}
+ #ifdef RE_ENABLE_I18N
+-	      if (dfa->mb_cur_max > 1)
++	      if (dfa_mb_cur_max (dfa) > 1)
+ 		for (j = 0; j < BITSET_WORDS; ++j)
+ 		  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
+ 	      else
+@@ -3660,7 +3645,7 @@
+ 		  continue;
+ 		}
+ #ifdef RE_ENABLE_I18N
+-	      if (dfa->mb_cur_max > 1)
++	      if (dfa_mb_cur_max (dfa) > 1)
+ 		for (j = 0; j < BITSET_WORDS; ++j)
+ 		  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
+ 	      else
+@@ -3832,12 +3817,6 @@
+   if (node->type == COMPLEX_BRACKET)
+     {
+       const re_charset_t *cset = node->opr.mbcset;
+-# ifdef _LIBC
+-      const unsigned char *pin
+-	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
+-      int j;
+-      uint32_t nrules;
+-# endif /* _LIBC */
+       int match_len = 0;
+       wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
+ 		    ? re_string_wchar_at (input, str_idx) : 0);
+@@ -3849,6 +3828,7 @@
+ 	    match_len = char_len;
+ 	    goto check_node_accept_bytes_match;
+ 	  }
++#if __OPTION_EGLIBC_LOCALE_CODE
+       /* match with character_class?  */
+       for (i = 0; i < cset->nchar_classes; ++i)
+ 	{
+@@ -3859,8 +3839,16 @@
+ 	      goto check_node_accept_bytes_match;
+ 	    }
+ 	}
++#endif
++
++      /* When __OPTION_EGLIBC_LOCALE_CODE is disabled, only the C
++         locale is supported; it has no collation rules.  */
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
++      const unsigned char *pin
++	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
++      int j;
++      uint32_t nrules;
+ 
+-# ifdef _LIBC
+       nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+       if (nrules != 0)
+ 	{
+@@ -3953,8 +3941,12 @@
+ 	    }
+ 	}
+       else
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ 	{
++          /* In the _LIBC version, if OPTION_EGLIBC_LOCALE_CODE is
++             disabled, there can be no multibyte range endpoints, and
++             cset->nranges is always zero.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	  /* match with range expression?  */
+ #if __GNUC__ >= 2
+ 	  wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
+@@ -3973,6 +3965,7 @@
+ 		  goto check_node_accept_bytes_match;
+ 		}
+ 	    }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 	}
+     check_node_accept_bytes_match:
+       if (!cset->non_match)
+@@ -3988,7 +3981,7 @@
+   return 0;
+ }
+ 
+-# ifdef _LIBC
++# if defined _LIBC && __OPTION_EGLIBC_LOCALE_CODE
+ static unsigned int
+ internal_function
+ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
+@@ -4046,7 +4039,7 @@
+       return UINT_MAX;
+     }
+ }
+-# endif /* _LIBC */
++# endif /* _LIBC && __OPTION_EGLIBC_LOCALE_CODE */
+ #endif /* RE_ENABLE_I18N */
+ 
+ /* Check whether the node accepts the byte which is IDX-th
+@@ -4137,7 +4130,7 @@
+   if (pstr->icase)
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	{
+ 	  ret = build_wcs_upper_buffer (pstr);
+ 	  if (BE (ret != REG_NOERROR, 0))
+@@ -4150,7 +4143,7 @@
+   else
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	build_wcs_buffer (pstr);
+       else
+ #endif /* RE_ENABLE_I18N  */
+Index: git/posix/regexec-compat.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/posix/regexec-compat.c	2014-08-29 20:01:15.224070587 -0700
+@@ -0,0 +1,39 @@
++/* Extended regular expression matching and search library.
++   Copyright (C) 2008 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
++
++   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.  */
++
++#ifdef _LIBC
++# include <shlib-compat.h>
++versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
++
++# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
++__typeof__ (__regexec) __compat_regexec;
++
++int
++attribute_compat_text_section
++__compat_regexec (const regex_t *__restrict preg,
++		  const char *__restrict string, size_t nmatch,
++		  regmatch_t pmatch[], int eflags)
++{
++  return regexec (preg, string, nmatch, pmatch,
++		  eflags & (REG_NOTBOL | REG_NOTEOL));
++}
++compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
++# endif
++#endif
+Index: git/posix/regex.h
+===================================================================
+--- git.orig/posix/regex.h	2014-08-29 20:00:53.264070587 -0700
++++ git/posix/regex.h	2014-08-29 20:01:15.224070587 -0700
+@@ -21,6 +21,7 @@
+ #define _REGEX_H 1
+ 
+ #include <sys/types.h>
++#include <gnu/option-groups.h>
+ 
+ /* Allow the use in C++ code.  */
+ #ifdef __cplusplus
+@@ -156,6 +157,8 @@
+    treated as 'a\{1'.  */
+ # define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+ 
++/* EGLIBC: Old regex implementation does not support these.  */
++# if __OPTION_POSIX_REGEXP_GLIBC
+ /* If this bit is set, then ignore case when matching.
+    If not set, then case is significant.  */
+ # define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+@@ -172,6 +175,7 @@
+ /* If this bit is set, then no_sub will be set to 1 during
+    re_compile_pattern.  */
+ # define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
++# endif /* __OPTION_POSIX_REGEXP_GLIBC */
+ #endif
+ 
+ /* This global variable defines the particular regexp syntax to use (for
+@@ -231,8 +235,13 @@
+   (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
+    | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+ 
++#if __OPTION_POSIX_REGEXP_GLIBC
+ #define RE_SYNTAX_POSIX_BASIC						\
+   (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
++#else
++#define RE_SYNTAX_POSIX_BASIC						\
++  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
++#endif
+ 
+ /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+    RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+@@ -298,9 +307,11 @@
+ /* Like REG_NOTBOL, except for the end-of-line.  */
+ #define REG_NOTEOL (1 << 1)
+ 
++#if __OPTION_POSIX_REGEXP_GLIBC
+ /* Use PMATCH[0] to delimit the start and end of the search in the
+    buffer.  */
+ #define REG_STARTEND (1 << 2)
++#endif
+ 
+ 
+ /* If any error codes are removed, changed, or added, update the
+Index: git/posix/regex_internal.c
+===================================================================
+--- git.orig/posix/regex_internal.c	2014-08-29 20:00:53.264070587 -0700
++++ git/posix/regex_internal.c	2014-08-29 20:01:15.224070587 -0700
+@@ -43,8 +43,8 @@
+   int init_buf_len;
+ 
+   /* Ensure at least one character fits into the buffers.  */
+-  if (init_len < dfa->mb_cur_max)
+-    init_len = dfa->mb_cur_max;
++  if (init_len < dfa_mb_cur_max (dfa))
++    init_len = dfa_mb_cur_max (dfa);
+   init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
+   re_string_construct_common (str, len, pstr, trans, icase, dfa);
+ 
+@@ -55,7 +55,7 @@
+   pstr->word_char = dfa->word_char;
+   pstr->word_ops_used = dfa->word_ops_used;
+   pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+-  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
++  pstr->valid_len = (pstr->mbs_allocated || dfa_mb_cur_max (dfa) > 1) ? 0 : len;
+   pstr->valid_raw_len = pstr->valid_len;
+   return REG_NOERROR;
+ }
+@@ -82,7 +82,7 @@
+   if (icase)
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	{
+ 	  while (1)
+ 	    {
+@@ -91,7 +91,7 @@
+ 		return ret;
+ 	      if (pstr->valid_raw_len >= len)
+ 		break;
+-	      if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
++	      if (pstr->bufs_len > pstr->valid_len + dfa_mb_cur_max (dfa))
+ 		break;
+ 	      ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+ 	      if (BE (ret != REG_NOERROR, 0))
+@@ -105,7 +105,7 @@
+   else
+     {
+ #ifdef RE_ENABLE_I18N
+-      if (dfa->mb_cur_max > 1)
++      if (dfa_mb_cur_max (dfa) > 1)
+ 	build_wcs_buffer (pstr);
+       else
+ #endif /* RE_ENABLE_I18N  */
+@@ -130,7 +130,7 @@
+ re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
+ {
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1)
++  if (string_mb_cur_max (pstr) > 1)
+     {
+       wint_t *new_wcs;
+ 
+@@ -177,7 +177,7 @@
+   pstr->trans = trans;
+   pstr->icase = icase ? 1 : 0;
+   pstr->mbs_allocated = (trans != NULL || icase);
+-  pstr->mb_cur_max = dfa->mb_cur_max;
++  pstr->mb_cur_max = dfa_mb_cur_max (dfa);
+   pstr->is_utf8 = dfa->is_utf8;
+   pstr->map_notascii = dfa->map_notascii;
+   pstr->stop = pstr->len;
+@@ -203,7 +203,7 @@
+ {
+ #ifdef _LIBC
+   unsigned char buf[MB_LEN_MAX];
+-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
++  assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
+ #else
+   unsigned char buf[64];
+ #endif
+@@ -226,7 +226,7 @@
+ 	{
+ 	  int i, ch;
+ 
+-	  for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
++	  for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
+ 	    {
+ 	      ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
+ 	      buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
+@@ -275,7 +275,7 @@
+   size_t mbclen;
+ #ifdef _LIBC
+   char buf[MB_LEN_MAX];
+-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
++  assert (MB_LEN_MAX >= string_mb_cur_max (pstr));
+ #else
+   char buf[64];
+ #endif
+@@ -369,7 +369,7 @@
+ 	  {
+ 	    int i, ch;
+ 
+-	    for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
++	    for (i = 0; i < string_mb_cur_max (pstr) && i < remain_len; ++i)
+ 	      {
+ 		ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
+ 		buf[i] = pstr->trans[ch];
+@@ -567,8 +567,9 @@
+ }
+ 
+ /* This function re-construct the buffers.
+-   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+-   convert to upper case in case of REG_ICASE, apply translation.  */
++   Concretely, convert to wide character in case of
++   string_mb_cur_max (pstr) > 1, convert to upper case in case of
++   REG_ICASE, apply translation.  */
+ 
+ static reg_errcode_t
+ internal_function __attribute_warn_unused_result__
+@@ -579,7 +580,7 @@
+     {
+       /* Reset buffer.  */
+ #ifdef RE_ENABLE_I18N
+-      if (pstr->mb_cur_max > 1)
++      if (string_mb_cur_max (pstr) > 1)
+ 	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+ #endif /* RE_ENABLE_I18N */
+       pstr->len = pstr->raw_len;
+@@ -670,7 +671,7 @@
+ 	      pstr->tip_context = re_string_context_at (pstr, offset - 1,
+ 							eflags);
+ #ifdef RE_ENABLE_I18N
+-	      if (pstr->mb_cur_max > 1)
++	      if (string_mb_cur_max (pstr) > 1)
+ 		memmove (pstr->wcs, pstr->wcs + offset,
+ 			 (pstr->valid_len - offset) * sizeof (wint_t));
+ #endif /* RE_ENABLE_I18N */
+@@ -699,7 +700,7 @@
+ #endif
+ 	  pstr->valid_len = 0;
+ #ifdef RE_ENABLE_I18N
+-	  if (pstr->mb_cur_max > 1)
++	  if (string_mb_cur_max (pstr) > 1)
+ 	    {
+ 	      int wcs_idx;
+ 	      wint_t wc = WEOF;
+@@ -711,7 +712,7 @@
+ 		  /* Special case UTF-8.  Multi-byte chars start with any
+ 		     byte other than 0x80 - 0xbf.  */
+ 		  raw = pstr->raw_mbs + pstr->raw_mbs_idx;
+-		  end = raw + (offset - pstr->mb_cur_max);
++		  end = raw + (offset - string_mb_cur_max (pstr));
+ 		  if (end < pstr->raw_mbs)
+ 		    end = pstr->raw_mbs;
+ 		  p = raw + offset - 1;
+@@ -803,7 +804,7 @@
+ 
+   /* Then build the buffers.  */
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1)
++  if (string_mb_cur_max (pstr) > 1)
+     {
+       if (pstr->icase)
+ 	{
+@@ -841,7 +842,7 @@
+     return re_string_peek_byte (pstr, idx);
+ 
+ #ifdef RE_ENABLE_I18N
+-  if (pstr->mb_cur_max > 1
++  if (string_mb_cur_max (pstr) > 1
+       && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
+     return re_string_peek_byte (pstr, idx);
+ #endif
+@@ -930,7 +931,7 @@
+     return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+ 	    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+ #ifdef RE_ENABLE_I18N
+-  if (input->mb_cur_max > 1)
++  if (string_mb_cur_max (input) > 1)
+     {
+       wint_t wc;
+       int wc_idx = idx;
+@@ -1444,7 +1445,7 @@
+   dfa->nodes[dfa->nodes_len].constraint = 0;
+ #ifdef RE_ENABLE_I18N
+   dfa->nodes[dfa->nodes_len].accept_mb =
+-    (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
++    (type == OP_PERIOD && dfa_mb_cur_max (dfa) > 1) || type == COMPLEX_BRACKET;
+ #endif
+   dfa->nexts[dfa->nodes_len] = -1;
+   re_node_set_init_empty (dfa->edests + dfa->nodes_len);
+Index: git/posix/regex_internal.h
+===================================================================
+--- git.orig/posix/regex_internal.h	2014-08-29 20:00:53.264070587 -0700
++++ git/posix/regex_internal.h	2014-08-29 20:01:15.224070587 -0700
+@@ -26,6 +26,10 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#if defined _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
+ # include <langinfo.h>
+ #endif
+@@ -370,6 +374,13 @@
+ };
+ typedef struct re_string_t re_string_t;
+ 
++/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
++   help the compiler make use of that fact.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define string_mb_cur_max(str) ((str)->mb_cur_max + 0)
++#else
++# define string_mb_cur_max(str) (1)
++#endif
+ 
+ struct re_dfa_t;
+ typedef struct re_dfa_t re_dfa_t;
+@@ -655,6 +666,14 @@
+   __libc_lock_define (, lock)
+ };
+ 
++/* When OPTION_EGLIBC_LOCALE_CODE is disabled, this is always 1;
++   help the compiler make use of that fact.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define dfa_mb_cur_max(dfa) ((dfa)->mb_cur_max + 0)
++#else
++# define dfa_mb_cur_max(dfa) (1)
++#endif
++
+ #define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+ #define re_node_set_remove(set,id) \
+   (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+@@ -715,7 +734,7 @@
+ re_string_char_size_at (const re_string_t *pstr, int idx)
+ {
+   int byte_idx;
+-  if (pstr->mb_cur_max == 1)
++  if (string_mb_cur_max (pstr) == 1)
+     return 1;
+   for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
+     if (pstr->wcs[idx + byte_idx] != WEOF)
+@@ -727,7 +746,7 @@
+ internal_function __attribute__ ((pure, unused))
+ re_string_wchar_at (const re_string_t *pstr, int idx)
+ {
+-  if (pstr->mb_cur_max == 1)
++  if (string_mb_cur_max (pstr) == 1)
+     return (wint_t) pstr->mbs[idx];
+   return (wint_t) pstr->wcs[idx];
+ }
+Index: git/posix/xregex.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/posix/xregex.c	2014-08-29 20:01:15.228070587 -0700
+@@ -0,0 +1,8212 @@
++/* Extended regular expression matching and search library,
++   version 0.12.
++   (Implements POSIX draft P1003.2/D11.2, except for some of the
++   internationalization features.)
++
++   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
++   2002, 2005 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   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., 51 Franklin Street, Fifth Floor, Boston, MA
++   02110-1301 USA.  */
++
++/* AIX requires this to be the first thing in the file. */
++#if defined _AIX && !defined __GNUC__ && !defined REGEX_MALLOC
++  #pragma alloca
++#endif
++
++#undef	_GNU_SOURCE
++#define _GNU_SOURCE
++
++#ifndef INSIDE_RECURSION
++# ifdef HAVE_CONFIG_H
++#  include <config.h>
++# endif
++#endif
++
++/*#include <ansidecl.h>*/
++
++#ifndef INSIDE_RECURSION
++
++# if defined STDC_HEADERS && !defined emacs
++#  include <stddef.h>
++# else
++/* We need this for `regex.h', and perhaps for the Emacs include files.  */
++#  include <sys/types.h>
++# endif
++
++# define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
++
++/* For platform which support the ISO C amendement 1 functionality we
++   support user defined character classes.  */
++# if WIDE_CHAR_SUPPORT
++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
++#  include <wchar.h>
++#  include <wctype.h>
++# endif
++
++# ifdef _LIBC
++/* We have to keep the namespace clean.  */
++#  define regfree(preg) __regfree (preg)
++#  define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
++#  define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
++#  define regerror(errcode, preg, errbuf, errbuf_size) \
++	__regerror(errcode, preg, errbuf, errbuf_size)
++#  define re_set_registers(bu, re, nu, st, en) \
++	__re_set_registers (bu, re, nu, st, en)
++#  define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
++	__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
++#  define re_match(bufp, string, size, pos, regs) \
++	__re_match (bufp, string, size, pos, regs)
++#  define re_search(bufp, string, size, startpos, range, regs) \
++	__re_search (bufp, string, size, startpos, range, regs)
++#  define re_compile_pattern(pattern, length, bufp) \
++	__re_compile_pattern (pattern, length, bufp)
++#  define re_set_syntax(syntax) __re_set_syntax (syntax)
++#  define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
++	__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
++#  define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
++
++#  define btowc __btowc
++
++/* We are also using some library internals.  */
++#  include <locale/localeinfo.h>
++#  include <locale/elem-hash.h>
++#  include <langinfo.h>
++#  include <locale/coll-lookup.h>
++# endif
++
++/* This is for other GNU distributions with internationalized messages.  */
++# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
++#  include <libintl.h>
++#  ifdef _LIBC
++#   undef gettext
++#   define gettext(msgid) __dcgettext ("libc", msgid, LC_MESSAGES)
++#  endif
++# else
++#  define gettext(msgid) (msgid)
++# endif
++
++# ifndef gettext_noop
++/* This define is so xgettext can find the internationalizable
++   strings.  */
++#  define gettext_noop(String) String
++# endif
++
++/* The `emacs' switch turns on certain matching commands
++   that make sense only in Emacs. */
++# ifdef emacs
++
++#  include "lisp.h"
++#  include "buffer.h"
++#  include "syntax.h"
++
++# else  /* not emacs */
++
++/* If we are not linking with Emacs proper,
++   we can't use the relocating allocator
++   even if config.h says that we can.  */
++#  undef REL_ALLOC
++
++#  if defined STDC_HEADERS || defined _LIBC
++#   include <stdlib.h>
++#  else
++char *malloc ();
++char *realloc ();
++#  endif
++
++/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
++   If nothing else has been done, use the method below.  */
++#  ifdef INHIBIT_STRING_HEADER
++#   if !(defined HAVE_BZERO && defined HAVE_BCOPY)
++#    if !defined bzero && !defined bcopy
++#     undef INHIBIT_STRING_HEADER
++#    endif
++#   endif
++#  endif
++
++/* This is the normal way of making sure we have a bcopy and a bzero.
++   This is used in most programs--a few other programs avoid this
++   by defining INHIBIT_STRING_HEADER.  */
++#  ifndef INHIBIT_STRING_HEADER
++#   if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
++#    include <string.h>
++#    ifndef bzero
++#     ifndef _LIBC
++#      define bzero(s, n)	(memset (s, '\0', n), (s))
++#     else
++#      define bzero(s, n)	__bzero (s, n)
++#     endif
++#    endif
++#   else
++#    include <strings.h>
++#    ifndef memcmp
++#     define memcmp(s1, s2, n)	bcmp (s1, s2, n)
++#    endif
++#    ifndef memcpy
++#     define memcpy(d, s, n)	(bcopy (s, d, n), (d))
++#    endif
++#   endif
++#  endif
++
++/* Define the syntax stuff for \<, \>, etc.  */
++
++/* This must be nonzero for the wordchar and notwordchar pattern
++   commands in re_match_2.  */
++#  ifndef Sword
++#   define Sword 1
++#  endif
++
++#  ifdef SWITCH_ENUM_BUG
++#   define SWITCH_ENUM_CAST(x) ((int)(x))
++#  else
++#   define SWITCH_ENUM_CAST(x) (x)
++#  endif
++
++# endif /* not emacs */
++
++# if defined _LIBC || HAVE_LIMITS_H
++#  include <limits.h>
++# endif
++
++# ifndef MB_LEN_MAX
++#  define MB_LEN_MAX 1
++# endif
++\f
++/* Get the interface, including the syntax bits.  */
++# include "regex.h"
++
++/* isalpha etc. are used for the character classes.  */
++# include <ctype.h>
++
++/* Jim Meyering writes:
++
++   "... Some ctype macros are valid only for character codes that
++   isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
++   using /bin/cc or gcc but without giving an ansi option).  So, all
++   ctype uses should be through macros like ISPRINT...  If
++   STDC_HEADERS is defined, then autoconf has verified that the ctype
++   macros don't need to be guarded with references to isascii. ...
++   Defining isascii to 1 should let any compiler worth its salt
++   eliminate the && through constant folding."
++   Solaris defines some of these symbols so we must undefine them first.  */
++
++# undef ISASCII
++# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
++#  define ISASCII(c) 1
++# else
++#  define ISASCII(c) isascii(c)
++# endif
++
++# ifdef isblank
++#  define ISBLANK(c) (ISASCII (c) && isblank (c))
++# else
++#  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
++# endif
++# ifdef isgraph
++#  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
++# else
++#  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
++# endif
++
++# undef ISPRINT
++# define ISPRINT(c) (ISASCII (c) && isprint (c))
++# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
++# define ISALNUM(c) (ISASCII (c) && isalnum (c))
++# define ISALPHA(c) (ISASCII (c) && isalpha (c))
++# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
++# define ISLOWER(c) (ISASCII (c) && islower (c))
++# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
++# define ISSPACE(c) (ISASCII (c) && isspace (c))
++# define ISUPPER(c) (ISASCII (c) && isupper (c))
++# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
++
++# ifdef _tolower
++#  define TOLOWER(c) _tolower(c)
++# else
++#  define TOLOWER(c) tolower(c)
++# endif
++
++# ifndef NULL
++#  define NULL (void *)0
++# endif
++
++/* We remove any previous definition of `SIGN_EXTEND_CHAR',
++   since ours (we hope) works properly with all combinations of
++   machines, compilers, `char' and `unsigned char' argument types.
++   (Per Bothner suggested the basic approach.)  */
++# undef SIGN_EXTEND_CHAR
++# if __STDC__
++#  define SIGN_EXTEND_CHAR(c) ((signed char) (c))
++# else  /* not __STDC__ */
++/* As in Harbison and Steele.  */
++#  define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
++# endif
++\f
++# ifndef emacs
++/* How many characters in the character set.  */
++#  define CHAR_SET_SIZE 256
++
++#  ifdef SYNTAX_TABLE
++
++extern char *re_syntax_table;
++
++#  else /* not SYNTAX_TABLE */
++
++static char re_syntax_table[CHAR_SET_SIZE];
++
++static void init_syntax_once (void);
++
++static void
++init_syntax_once (void)
++{
++   register int c;
++   static int done = 0;
++
++   if (done)
++     return;
++   bzero (re_syntax_table, sizeof re_syntax_table);
++
++   for (c = 0; c < CHAR_SET_SIZE; ++c)
++     if (ISALNUM (c))
++	re_syntax_table[c] = Sword;
++
++   re_syntax_table['_'] = Sword;
++
++   done = 1;
++}
++
++#  endif /* not SYNTAX_TABLE */
++
++#  define SYNTAX(c) re_syntax_table[(unsigned char) (c)]
++
++# endif /* emacs */
++\f
++/* Integer type for pointers.  */
++# if !defined _LIBC && !defined HAVE_UINTPTR_T
++typedef unsigned long int uintptr_t;
++# endif
++
++/* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
++   use `alloca' instead of `malloc'.  This is because using malloc in
++   re_search* or re_match* could cause memory leaks when C-g is used in
++   Emacs; also, malloc is slower and causes storage fragmentation.  On
++   the other hand, malloc is more portable, and easier to debug.
++
++   Because we sometimes use alloca, some routines have to be macros,
++   not functions -- `alloca'-allocated space disappears at the end of the
++   function it is called in.  */
++
++# ifdef REGEX_MALLOC
++
++#  define REGEX_ALLOCATE malloc
++#  define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
++#  define REGEX_FREE free
++
++# else /* not REGEX_MALLOC  */
++
++/* Emacs already defines alloca, sometimes.  */
++#  ifndef alloca
++
++/* Make alloca work the best possible way.  */
++#   ifdef __GNUC__
++#    define alloca __builtin_alloca
++#   else /* not __GNUC__ */
++#    if HAVE_ALLOCA_H
++#     include <alloca.h>
++#    endif /* HAVE_ALLOCA_H */
++#   endif /* not __GNUC__ */
++
++#  endif /* not alloca */
++
++#  define REGEX_ALLOCATE alloca
++
++/* Assumes a `char *destination' variable.  */
++#  define REGEX_REALLOCATE(source, osize, nsize)			\
++  (destination = (char *) alloca (nsize),				\
++   memcpy (destination, source, osize))
++
++/* No need to do anything to free, after alloca.  */
++#  define REGEX_FREE(arg) ((void)0) /* Do nothing!  But inhibit gcc warning.  */
++
++# endif /* not REGEX_MALLOC */
++
++/* Define how to allocate the failure stack.  */
++
++# if defined REL_ALLOC && defined REGEX_MALLOC
++
++#  define REGEX_ALLOCATE_STACK(size)				\
++  r_alloc (&failure_stack_ptr, (size))
++#  define REGEX_REALLOCATE_STACK(source, osize, nsize)		\
++  r_re_alloc (&failure_stack_ptr, (nsize))
++#  define REGEX_FREE_STACK(ptr)					\
++  r_alloc_free (&failure_stack_ptr)
++
++# else /* not using relocating allocator */
++
++#  ifdef REGEX_MALLOC
++
++#   define REGEX_ALLOCATE_STACK malloc
++#   define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
++#   define REGEX_FREE_STACK free
++
++#  else /* not REGEX_MALLOC */
++
++#   define REGEX_ALLOCATE_STACK alloca
++
++#   define REGEX_REALLOCATE_STACK(source, osize, nsize)			\
++   REGEX_REALLOCATE (source, osize, nsize)
++/* No need to explicitly free anything.  */
++#   define REGEX_FREE_STACK(arg)
++
++#  endif /* not REGEX_MALLOC */
++# endif /* not using relocating allocator */
++
++
++/* True if `size1' is non-NULL and PTR is pointing anywhere inside
++   `string1' or just past its end.  This works if PTR is NULL, which is
++   a good thing.  */
++# define FIRST_STRING_P(ptr) 					\
++  (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
++
++/* (Re)Allocate N items of type T using malloc, or fail.  */
++# define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
++# define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
++# define RETALLOC_IF(addr, n, t) \
++  if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
++# define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
++
++# define BYTEWIDTH 8 /* In bits.  */
++
++# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
++
++# undef MAX
++# undef MIN
++# define MAX(a, b) ((a) > (b) ? (a) : (b))
++# define MIN(a, b) ((a) < (b) ? (a) : (b))
++
++typedef char boolean;
++# define false 0
++# define true 1
++
++static reg_errcode_t byte_regex_compile (const char *pattern, size_t size,
++                                         reg_syntax_t syntax,
++                                         struct re_pattern_buffer *bufp);
++
++static int byte_re_match_2_internal (struct re_pattern_buffer *bufp,
++                                     const char *string1, int size1,
++                                     const char *string2, int size2,
++                                     int pos,
++                                     struct re_registers *regs,
++                                     int stop);
++static int byte_re_search_2 (struct re_pattern_buffer *bufp,
++                             const char *string1, int size1,
++                             const char *string2, int size2,
++                             int startpos, int range,
++                             struct re_registers *regs, int stop);
++static int byte_re_compile_fastmap (struct re_pattern_buffer *bufp);
++
++#ifdef MBS_SUPPORT
++static reg_errcode_t wcs_regex_compile (const char *pattern, size_t size,
++                                        reg_syntax_t syntax,
++                                        struct re_pattern_buffer *bufp);
++
++
++static int wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
++                                    const char *cstring1, int csize1,
++                                    const char *cstring2, int csize2,
++                                    int pos,
++                                    struct re_registers *regs,
++                                    int stop,
++                                    wchar_t *string1, int size1,
++                                    wchar_t *string2, int size2,
++                                    int *mbs_offset1, int *mbs_offset2);
++static int wcs_re_search_2 (struct re_pattern_buffer *bufp,
++                            const char *string1, int size1,
++                            const char *string2, int size2,
++                            int startpos, int range,
++                            struct re_registers *regs, int stop);
++static int wcs_re_compile_fastmap (struct re_pattern_buffer *bufp);
++#endif
++\f
++/* These are the command codes that appear in compiled regular
++   expressions.  Some opcodes are followed by argument bytes.  A
++   command code can specify any interpretation whatsoever for its
++   arguments.  Zero bytes may appear in the compiled regular expression.  */
++
++typedef enum
++{
++  no_op = 0,
++
++  /* Succeed right away--no more backtracking.  */
++  succeed,
++
++        /* Followed by one byte giving n, then by n literal bytes.  */
++  exactn,
++
++# ifdef MBS_SUPPORT
++	/* Same as exactn, but contains binary data.  */
++  exactn_bin,
++# endif
++
++        /* Matches any (more or less) character.  */
++  anychar,
++
++        /* Matches any one char belonging to specified set.  First
++           following byte is number of bitmap bytes.  Then come bytes
++           for a bitmap saying which chars are in.  Bits in each byte
++           are ordered low-bit-first.  A character is in the set if its
++           bit is 1.  A character too large to have a bit in the map is
++           automatically not in the set.  */
++        /* ifdef MBS_SUPPORT, following element is length of character
++	   classes, length of collating symbols, length of equivalence
++	   classes, length of character ranges, and length of characters.
++	   Next, character class element, collating symbols elements,
++	   equivalence class elements, range elements, and character
++	   elements follow.
++	   See regex_compile function.  */
++  charset,
++
++        /* Same parameters as charset, but match any character that is
++           not one of those specified.  */
++  charset_not,
++
++        /* Start remembering the text that is matched, for storing in a
++           register.  Followed by one byte with the register number, in
++           the range 0 to one less than the pattern buffer's re_nsub
++           field.  Then followed by one byte with the number of groups
++           inner to this one.  (This last has to be part of the
++           start_memory only because we need it in the on_failure_jump
++           of re_match_2.)  */
++  start_memory,
++
++        /* Stop remembering the text that is matched and store it in a
++           memory register.  Followed by one byte with the register
++           number, in the range 0 to one less than `re_nsub' in the
++           pattern buffer, and one byte with the number of inner groups,
++           just like `start_memory'.  (We need the number of inner
++           groups here because we don't have any easy way of finding the
++           corresponding start_memory when we're at a stop_memory.)  */
++  stop_memory,
++
++        /* Match a duplicate of something remembered. Followed by one
++           byte containing the register number.  */
++  duplicate,
++
++        /* Fail unless at beginning of line.  */
++  begline,
++
++        /* Fail unless at end of line.  */
++  endline,
++
++        /* Succeeds if at beginning of buffer (if emacs) or at beginning
++           of string to be matched (if not).  */
++  begbuf,
++
++        /* Analogously, for end of buffer/string.  */
++  endbuf,
++
++        /* Followed by two byte relative address to which to jump.  */
++  jump,
++
++	/* Same as jump, but marks the end of an alternative.  */
++  jump_past_alt,
++
++        /* Followed by two-byte relative address of place to resume at
++           in case of failure.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  on_failure_jump,
++
++        /* Like on_failure_jump, but pushes a placeholder instead of the
++           current string position when executed.  */
++  on_failure_keep_string_jump,
++
++        /* Throw away latest failure point and then jump to following
++           two-byte relative address.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  pop_failure_jump,
++
++        /* Change to pop_failure_jump if know won't have to backtrack to
++           match; otherwise change to jump.  This is used to jump
++           back to the beginning of a repeat.  If what follows this jump
++           clearly won't match what the repeat does, such that we can be
++           sure that there is no use backtracking out of repetitions
++           already matched, then we change it to a pop_failure_jump.
++           Followed by two-byte address.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  maybe_pop_jump,
++
++        /* Jump to following two-byte address, and push a dummy failure
++           point. This failure point will be thrown away if an attempt
++           is made to use it for a failure.  A `+' construct makes this
++           before the first repeat.  Also used as an intermediary kind
++           of jump when compiling an alternative.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  dummy_failure_jump,
++
++	/* Push a dummy failure point and continue.  Used at the end of
++	   alternatives.  */
++  push_dummy_failure,
++
++        /* Followed by two-byte relative address and two-byte number n.
++           After matching N times, jump to the address upon failure.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  succeed_n,
++
++        /* Followed by two-byte relative address, and two-byte number n.
++           Jump to the address N times, then fail.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  jump_n,
++
++        /* Set the following two-byte relative address to the
++           subsequent two-byte number.  The address *includes* the two
++           bytes of number.  */
++        /* ifdef MBS_SUPPORT, the size of address is 1.  */
++  set_number_at,
++
++  wordchar,	/* Matches any word-constituent character.  */
++  notwordchar,	/* Matches any char that is not a word-constituent.  */
++
++  wordbeg,	/* Succeeds if at word beginning.  */
++  wordend,	/* Succeeds if at word end.  */
++
++  wordbound,	/* Succeeds if at a word boundary.  */
++  notwordbound	/* Succeeds if not at a word boundary.  */
++
++# ifdef emacs
++  ,before_dot,	/* Succeeds if before point.  */
++  at_dot,	/* Succeeds if at point.  */
++  after_dot,	/* Succeeds if after point.  */
++
++	/* Matches any character whose syntax is specified.  Followed by
++           a byte which contains a syntax code, e.g., Sword.  */
++  syntaxspec,
++
++	/* Matches any character whose syntax is not that specified.  */
++  notsyntaxspec
++# endif /* emacs */
++} re_opcode_t;
++#endif /* not INSIDE_RECURSION */
++\f
++
++#ifdef BYTE
++# define CHAR_T char
++# define UCHAR_T unsigned char
++# define COMPILED_BUFFER_VAR bufp->buffer
++# define OFFSET_ADDRESS_SIZE 2
++# define PREFIX(name) byte_##name
++# define ARG_PREFIX(name) name
++# define PUT_CHAR(c) putchar (c)
++#else
++# ifdef WCHAR
++#  define CHAR_T wchar_t
++#  define UCHAR_T wchar_t
++#  define COMPILED_BUFFER_VAR wc_buffer
++#  define OFFSET_ADDRESS_SIZE 1 /* the size which STORE_NUMBER macro use */
++#  define CHAR_CLASS_SIZE ((__alignof__(wctype_t)+sizeof(wctype_t))/sizeof(CHAR_T)+1)
++#  define PREFIX(name) wcs_##name
++#  define ARG_PREFIX(name) c##name
++/* Should we use wide stream??  */
++#  define PUT_CHAR(c) printf ("%C", c);
++#  define TRUE 1
++#  define FALSE 0
++# else
++#  ifdef MBS_SUPPORT
++#   define WCHAR
++#   define INSIDE_RECURSION
++#   include "xregex.c"
++#   undef INSIDE_RECURSION
++#  endif
++#  define BYTE
++#  define INSIDE_RECURSION
++#  include "xregex.c"
++#  undef INSIDE_RECURSION
++# endif
++#endif
++
++#ifdef INSIDE_RECURSION
++/* Common operations on the compiled pattern.  */
++
++/* Store NUMBER in two contiguous bytes starting at DESTINATION.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# ifdef WCHAR
++#  define STORE_NUMBER(destination, number)				\
++  do {									\
++    *(destination) = (UCHAR_T)(number);				\
++  } while (0)
++# else /* BYTE */
++#  define STORE_NUMBER(destination, number)				\
++  do {									\
++    (destination)[0] = (number) & 0377;					\
++    (destination)[1] = (number) >> 8;					\
++  } while (0)
++# endif /* WCHAR */
++
++/* Same as STORE_NUMBER, except increment DESTINATION to
++   the byte after where the number is stored.  Therefore, DESTINATION
++   must be an lvalue.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# define STORE_NUMBER_AND_INCR(destination, number)			\
++  do {									\
++    STORE_NUMBER (destination, number);					\
++    (destination) += OFFSET_ADDRESS_SIZE;				\
++  } while (0)
++
++/* Put into DESTINATION a number stored in two contiguous bytes starting
++   at SOURCE.  */
++/* ifdef MBS_SUPPORT, we store NUMBER in 1 element.  */
++
++# ifdef WCHAR
++#  define EXTRACT_NUMBER(destination, source)				\
++  do {									\
++    (destination) = *(source);						\
++  } while (0)
++# else /* BYTE */
++#  define EXTRACT_NUMBER(destination, source)				\
++  do {									\
++    (destination) = *(source) & 0377;					\
++    (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8;		\
++  } while (0)
++# endif
++
++# ifdef DEBUG
++static void PREFIX(extract_number) (int *dest, UCHAR_T *source);
++static void
++PREFIX(extract_number) (int *dest, UCHAR_T *source)
++{
++#  ifdef WCHAR
++  *dest = *source;
++#  else /* BYTE */
++  int temp = SIGN_EXTEND_CHAR (*(source + 1));
++  *dest = *source & 0377;
++  *dest += temp << 8;
++#  endif
++}
++
++#  ifndef EXTRACT_MACROS /* To debug the macros.  */
++#   undef EXTRACT_NUMBER
++#   define EXTRACT_NUMBER(dest, src) PREFIX(extract_number) (&dest, src)
++#  endif /* not EXTRACT_MACROS */
++
++# endif /* DEBUG */
++
++/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
++   SOURCE must be an lvalue.  */
++
++# define EXTRACT_NUMBER_AND_INCR(destination, source)			\
++  do {									\
++    EXTRACT_NUMBER (destination, source);				\
++    (source) += OFFSET_ADDRESS_SIZE; 					\
++  } while (0)
++
++# ifdef DEBUG
++static void PREFIX(extract_number_and_incr) (int *destination,
++                                             UCHAR_T **source);
++static void
++PREFIX(extract_number_and_incr) (int *destination, UCHAR_T **source)
++{
++  PREFIX(extract_number) (destination, *source);
++  *source += OFFSET_ADDRESS_SIZE;
++}
++
++#  ifndef EXTRACT_MACROS
++#   undef EXTRACT_NUMBER_AND_INCR
++#   define EXTRACT_NUMBER_AND_INCR(dest, src) \
++  PREFIX(extract_number_and_incr) (&dest, &src)
++#  endif /* not EXTRACT_MACROS */
++
++# endif /* DEBUG */
++
++\f
++
++/* If DEBUG is defined, Regex prints many voluminous messages about what
++   it is doing (if the variable `debug' is nonzero).  If linked with the
++   main program in `iregex.c', you can enter patterns and strings
++   interactively.  And if linked with the main program in `main.c' and
++   the other test files, you can run the already-written tests.  */
++
++# ifdef DEBUG
++
++#  ifndef DEFINED_ONCE
++
++/* We use standard I/O for debugging.  */
++#   include <stdio.h>
++
++/* It is useful to test things that ``must'' be true when debugging.  */
++#   include <assert.h>
++
++static int debug;
++
++#   define DEBUG_STATEMENT(e) e
++#   define DEBUG_PRINT1(x) if (debug) printf (x)
++#   define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
++#   define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
++#   define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
++#  endif /* not DEFINED_ONCE */
++
++#  define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) 			\
++  if (debug) PREFIX(print_partial_compiled_pattern) (s, e)
++#  define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)		\
++  if (debug) PREFIX(print_double_string) (w, s1, sz1, s2, sz2)
++
++
++/* Print the fastmap in human-readable form.  */
++
++#  ifndef DEFINED_ONCE
++void
++print_fastmap (char *fastmap)
++{
++  unsigned was_a_range = 0;
++  unsigned i = 0;
++
++  while (i < (1 << BYTEWIDTH))
++    {
++      if (fastmap[i++])
++	{
++	  was_a_range = 0;
++          putchar (i - 1);
++          while (i < (1 << BYTEWIDTH)  &&  fastmap[i])
++            {
++              was_a_range = 1;
++              i++;
++            }
++	  if (was_a_range)
++            {
++              printf ("-");
++              putchar (i - 1);
++            }
++        }
++    }
++  putchar ('\n');
++}
++#  endif /* not DEFINED_ONCE */
++
++
++/* Print a compiled pattern string in human-readable form, starting at
++   the START pointer into it and ending just before the pointer END.  */
++
++void
++PREFIX(print_partial_compiled_pattern) (UCHAR_T *start, UCHAR_T *end)
++{
++  int mcnt, mcnt2;
++  UCHAR_T *p1;
++  UCHAR_T *p = start;
++  UCHAR_T *pend = end;
++
++  if (start == NULL)
++    {
++      printf ("(null)\n");
++      return;
++    }
++
++  /* Loop over pattern commands.  */
++  while (p < pend)
++    {
++#  ifdef _LIBC
++      printf ("%td:\t", p - start);
++#  else
++      printf ("%ld:\t", (long int) (p - start));
++#  endif
++
++      switch ((re_opcode_t) *p++)
++	{
++        case no_op:
++          printf ("/no_op");
++          break;
++
++	case exactn:
++	  mcnt = *p++;
++          printf ("/exactn/%d", mcnt);
++          do
++	    {
++              putchar ('/');
++	      PUT_CHAR (*p++);
++            }
++          while (--mcnt);
++          break;
++
++#  ifdef MBS_SUPPORT
++	case exactn_bin:
++	  mcnt = *p++;
++	  printf ("/exactn_bin/%d", mcnt);
++          do
++	    {
++	      printf("/%lx", (long int) *p++);
++            }
++          while (--mcnt);
++          break;
++#  endif /* MBS_SUPPORT */
++
++	case start_memory:
++          mcnt = *p++;
++          printf ("/start_memory/%d/%ld", mcnt, (long int) *p++);
++          break;
++
++	case stop_memory:
++          mcnt = *p++;
++	  printf ("/stop_memory/%d/%ld", mcnt, (long int) *p++);
++          break;
++
++	case duplicate:
++	  printf ("/duplicate/%ld", (long int) *p++);
++	  break;
++
++	case anychar:
++	  printf ("/anychar");
++	  break;
++
++	case charset:
++        case charset_not:
++          {
++#  ifdef WCHAR
++	    int i, length;
++	    wchar_t *workp = p;
++	    printf ("/charset [%s",
++	            (re_opcode_t) *(workp - 1) == charset_not ? "^" : "");
++	    p += 5;
++	    length = *workp++; /* the length of char_classes */
++	    for (i=0 ; i<length ; i++)
++	      printf("[:%lx:]", (long int) *p++);
++	    length = *workp++; /* the length of collating_symbol */
++	    for (i=0 ; i<length ;)
++	      {
++		printf("[.");
++		while(*p != 0)
++		  PUT_CHAR((i++,*p++));
++		i++,p++;
++		printf(".]");
++	      }
++	    length = *workp++; /* the length of equivalence_class */
++	    for (i=0 ; i<length ;)
++	      {
++		printf("[=");
++		while(*p != 0)
++		  PUT_CHAR((i++,*p++));
++		i++,p++;
++		printf("=]");
++	      }
++	    length = *workp++; /* the length of char_range */
++	    for (i=0 ; i<length ; i++)
++	      {
++		wchar_t range_start = *p++;
++		wchar_t range_end = *p++;
++		printf("%C-%C", range_start, range_end);
++	      }
++	    length = *workp++; /* the length of char */
++	    for (i=0 ; i<length ; i++)
++	      printf("%C", *p++);
++	    putchar (']');
++#  else
++            register int c, last = -100;
++	    register int in_range = 0;
++
++	    printf ("/charset [%s",
++	            (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
++
++            assert (p + *p < pend);
++
++            for (c = 0; c < 256; c++)
++	      if (c / 8 < *p
++		  && (p[1 + (c/8)] & (1 << (c % 8))))
++		{
++		  /* Are we starting a range?  */
++		  if (last + 1 == c && ! in_range)
++		    {
++		      putchar ('-');
++		      in_range = 1;
++		    }
++		  /* Have we broken a range?  */
++		  else if (last + 1 != c && in_range)
++              {
++		      putchar (last);
++		      in_range = 0;
++		    }
++
++		  if (! in_range)
++		    putchar (c);
++
++		  last = c;
++              }
++
++	    if (in_range)
++	      putchar (last);
++
++	    putchar (']');
++
++	    p += 1 + *p;
++#  endif /* WCHAR */
++	  }
++	  break;
++
++	case begline:
++	  printf ("/begline");
++          break;
++
++	case endline:
++          printf ("/endline");
++          break;
++
++	case on_failure_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/on_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/on_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case on_failure_keep_string_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/on_failure_keep_string_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/on_failure_keep_string_jump to %ld",
++		  (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case dummy_failure_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/dummy_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/dummy_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++          break;
++
++	case push_dummy_failure:
++          printf ("/push_dummy_failure");
++          break;
++
++        case maybe_pop_jump:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/maybe_pop_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/maybe_pop_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case pop_failure_jump:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/pop_failure_jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/pop_failure_jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case jump_past_alt:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/jump_past_alt to %td", p + mcnt - start);
++#  else
++  	  printf ("/jump_past_alt to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case jump:
++	  PREFIX(extract_number_and_incr) (&mcnt, &p);
++#  ifdef _LIBC
++  	  printf ("/jump to %td", p + mcnt - start);
++#  else
++  	  printf ("/jump to %ld", (long int) (p + mcnt - start));
++#  endif
++	  break;
++
++        case succeed_n:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++#  ifdef _LIBC
++	  printf ("/succeed_n to %td, %d times", p1 - start, mcnt2);
++#  else
++	  printf ("/succeed_n to %ld, %d times",
++		  (long int) (p1 - start), mcnt2);
++#  endif
++          break;
++
++        case jump_n:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++	  printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
++          break;
++
++        case set_number_at:
++          PREFIX(extract_number_and_incr) (&mcnt, &p);
++	  p1 = p + mcnt;
++          PREFIX(extract_number_and_incr) (&mcnt2, &p);
++#  ifdef _LIBC
++	  printf ("/set_number_at location %td to %d", p1 - start, mcnt2);
++#  else
++	  printf ("/set_number_at location %ld to %d",
++		  (long int) (p1 - start), mcnt2);
++#  endif
++          break;
++
++        case wordbound:
++	  printf ("/wordbound");
++	  break;
++
++	case notwordbound:
++	  printf ("/notwordbound");
++          break;
++
++	case wordbeg:
++	  printf ("/wordbeg");
++	  break;
++
++	case wordend:
++	  printf ("/wordend");
++	  break;
++
++#  ifdef emacs
++	case before_dot:
++	  printf ("/before_dot");
++          break;
++
++	case at_dot:
++	  printf ("/at_dot");
++          break;
++
++	case after_dot:
++	  printf ("/after_dot");
++          break;
++
++	case syntaxspec:
++          printf ("/syntaxspec");
++	  mcnt = *p++;
++	  printf ("/%d", mcnt);
++          break;
++
++	case notsyntaxspec:
++          printf ("/notsyntaxspec");
++	  mcnt = *p++;
++	  printf ("/%d", mcnt);
++	  break;
++#  endif /* emacs */
++
++	case wordchar:
++	  printf ("/wordchar");
++          break;
++
++	case notwordchar:
++	  printf ("/notwordchar");
++          break;
++
++	case begbuf:
++	  printf ("/begbuf");
++          break;
++
++	case endbuf:
++	  printf ("/endbuf");
++          break;
++
++        default:
++          printf ("?%ld", (long int) *(p-1));
++	}
++
++      putchar ('\n');
++    }
++
++#  ifdef _LIBC
++  printf ("%td:\tend of pattern.\n", p - start);
++#  else
++  printf ("%ld:\tend of pattern.\n", (long int) (p - start));
++#  endif
++}
++
++
++void
++PREFIX(print_compiled_pattern) (struct re_pattern_buffer *bufp)
++{
++  UCHAR_T *buffer = (UCHAR_T*) bufp->buffer;
++
++  PREFIX(print_partial_compiled_pattern) (buffer, buffer
++				  + bufp->used / sizeof(UCHAR_T));
++  printf ("%ld bytes used/%ld bytes allocated.\n",
++	  bufp->used, bufp->allocated);
++
++  if (bufp->fastmap_accurate && bufp->fastmap)
++    {
++      printf ("fastmap: ");
++      print_fastmap (bufp->fastmap);
++    }
++
++#  ifdef _LIBC
++  printf ("re_nsub: %Zd\t", bufp->re_nsub);
++#  else
++  printf ("re_nsub: %ld\t", (long int) bufp->re_nsub);
++#  endif
++  printf ("regs_alloc: %d\t", bufp->regs_allocated);
++  printf ("can_be_null: %d\t", bufp->can_be_null);
++  printf ("newline_anchor: %d\n", bufp->newline_anchor);
++  printf ("no_sub: %d\t", bufp->no_sub);
++  printf ("not_bol: %d\t", bufp->not_bol);
++  printf ("not_eol: %d\t", bufp->not_eol);
++  printf ("syntax: %lx\n", bufp->syntax);
++  /* Perhaps we should print the translate table?  */
++}
++
++
++void
++PREFIX(print_double_string) (const CHAR_T *where, const CHAR_T *string1,
++                             int size1, const CHAR_T *string2, int size2)
++{
++  int this_char;
++
++  if (where == NULL)
++    printf ("(null)");
++  else
++    {
++      int cnt;
++
++      if (FIRST_STRING_P (where))
++        {
++          for (this_char = where - string1; this_char < size1; this_char++)
++	    PUT_CHAR (string1[this_char]);
++
++          where = string2;
++        }
++
++      cnt = 0;
++      for (this_char = where - string2; this_char < size2; this_char++)
++	{
++	  PUT_CHAR (string2[this_char]);
++	  if (++cnt > 100)
++	    {
++	      fputs ("...", stdout);
++	      break;
++	    }
++	}
++    }
++}
++
++#  ifndef DEFINED_ONCE
++void
++printchar (int c)
++{
++  putc (c, stderr);
++}
++#  endif
++
++# else /* not DEBUG */
++
++#  ifndef DEFINED_ONCE
++#   undef assert
++#   define assert(e)
++
++#   define DEBUG_STATEMENT(e)
++#   define DEBUG_PRINT1(x)
++#   define DEBUG_PRINT2(x1, x2)
++#   define DEBUG_PRINT3(x1, x2, x3)
++#   define DEBUG_PRINT4(x1, x2, x3, x4)
++#  endif /* not DEFINED_ONCE */
++#  define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
++#  define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
++
++# endif /* not DEBUG */
++
++\f
++
++# ifdef WCHAR
++/* This  convert a multibyte string to a wide character string.
++   And write their correspondances to offset_buffer(see below)
++   and write whether each wchar_t is binary data to is_binary.
++   This assume invalid multibyte sequences as binary data.
++   We assume offset_buffer and is_binary is already allocated
++   enough space.  */
++
++static size_t convert_mbs_to_wcs (CHAR_T *dest, const unsigned char* src,
++				  size_t len, int *offset_buffer,
++				  char *is_binary);
++static size_t
++convert_mbs_to_wcs (CHAR_T *dest, const unsigned char*src, size_t len,
++                    int *offset_buffer, char *is_binary)
++     /* It hold correspondances between src(char string) and
++	dest(wchar_t string) for optimization.
++	e.g. src  = "xxxyzz"
++             dest = {'X', 'Y', 'Z'}
++	      (each "xxx", "y" and "zz" represent one multibyte character
++	       corresponding to 'X', 'Y' and 'Z'.)
++	  offset_buffer = {0, 0+3("xxx"), 0+3+1("y"), 0+3+1+2("zz")}
++	  	        = {0, 3, 4, 6}
++     */
++{
++  wchar_t *pdest = dest;
++  const unsigned char *psrc = src;
++  size_t wc_count = 0;
++
++  mbstate_t mbs;
++  int i, consumed;
++  size_t mb_remain = len;
++  size_t mb_count = 0;
++
++  /* Initialize the conversion state.  */
++  memset (&mbs, 0, sizeof (mbstate_t));
++
++  offset_buffer[0] = 0;
++  for( ; mb_remain > 0 ; ++wc_count, ++pdest, mb_remain -= consumed,
++	 psrc += consumed)
++    {
++#ifdef _LIBC
++      consumed = __mbrtowc (pdest, psrc, mb_remain, &mbs);
++#else
++      consumed = mbrtowc (pdest, psrc, mb_remain, &mbs);
++#endif
++
++      if (consumed <= 0)
++	/* failed to convert. maybe src contains binary data.
++	   So we consume 1 byte manualy.  */
++	{
++	  *pdest = *psrc;
++	  consumed = 1;
++	  is_binary[wc_count] = TRUE;
++	}
++      else
++	is_binary[wc_count] = FALSE;
++      /* In sjis encoding, we use yen sign as escape character in
++	 place of reverse solidus. So we convert 0x5c(yen sign in
++	 sjis) to not 0xa5(yen sign in UCS2) but 0x5c(reverse
++	 solidus in UCS2).  */
++      if (consumed == 1 && (int) *psrc == 0x5c && (int) *pdest == 0xa5)
++	*pdest = (wchar_t) *psrc;
++
++      offset_buffer[wc_count + 1] = mb_count += consumed;
++    }
++
++  /* Fill remain of the buffer with sentinel.  */
++  for (i = wc_count + 1 ; i <= len ; i++)
++    offset_buffer[i] = mb_count + 1;
++
++  return wc_count;
++}
++
++# endif /* WCHAR */
++
++#else /* not INSIDE_RECURSION */
++
++/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
++   also be assigned to arbitrarily: each pattern buffer stores its own
++   syntax, so it can be changed between regex compilations.  */
++/* This has no initializer because initialized variables in Emacs
++   become read-only after dumping.  */
++reg_syntax_t re_syntax_options;
++
++
++/* Specify the precise syntax of regexps for compilation.  This provides
++   for compatibility for various utilities which historically have
++   different, incompatible syntaxes.
++
++   The argument SYNTAX is a bit mask comprised of the various bits
++   defined in regex.h.  We return the old syntax.  */
++
++reg_syntax_t
++re_set_syntax (reg_syntax_t syntax)
++{
++  reg_syntax_t ret = re_syntax_options;
++
++  re_syntax_options = syntax;
++# ifdef DEBUG
++  if (syntax & RE_DEBUG)
++    debug = 1;
++  else if (debug) /* was on but now is not */
++    debug = 0;
++# endif /* DEBUG */
++  return ret;
++}
++# ifdef _LIBC
++weak_alias (__re_set_syntax, re_set_syntax)
++# endif
++\f
++/* This table gives an error message for each of the error codes listed
++   in regex.h.  Obviously the order here has to be same as there.
++   POSIX doesn't require that we do anything for REG_NOERROR,
++   but why not be nice?  */
++
++static const char *re_error_msgid[] =
++  {
++    gettext_noop ("Success"),	/* REG_NOERROR */
++    gettext_noop ("No match"),	/* REG_NOMATCH */
++    gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
++    gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
++    gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
++    gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
++    gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
++    gettext_noop ("Unmatched [ or [^"),	/* REG_EBRACK */
++    gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
++    gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
++    gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
++    gettext_noop ("Invalid range end"),	/* REG_ERANGE */
++    gettext_noop ("Memory exhausted"), /* REG_ESPACE */
++    gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
++    gettext_noop ("Premature end of regular expression"), /* REG_EEND */
++    gettext_noop ("Regular expression too big"), /* REG_ESIZE */
++    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
++  };
++\f
++#endif /* INSIDE_RECURSION */
++
++#ifndef DEFINED_ONCE
++/* Avoiding alloca during matching, to placate r_alloc.  */
++
++/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
++   searching and matching functions should not call alloca.  On some
++   systems, alloca is implemented in terms of malloc, and if we're
++   using the relocating allocator routines, then malloc could cause a
++   relocation, which might (if the strings being searched are in the
++   ralloc heap) shift the data out from underneath the regexp
++   routines.
++
++   Here's another reason to avoid allocation: Emacs
++   processes input from X in a signal handler; processing X input may
++   call malloc; if input arrives while a matching routine is calling
++   malloc, then we're scrod.  But Emacs can't just block input while
++   calling matching routines; then we don't notice interrupts when
++   they come in.  So, Emacs blocks input around all regexp calls
++   except the matching calls, which it leaves unprotected, in the
++   faith that they will not malloc.  */
++
++/* Normally, this is fine.  */
++# define MATCH_MAY_ALLOCATE
++
++/* When using GNU C, we are not REALLY using the C alloca, no matter
++   what config.h may say.  So don't take precautions for it.  */
++# ifdef __GNUC__
++#  undef C_ALLOCA
++# endif
++
++/* The match routines may not allocate if (1) they would do it with malloc
++   and (2) it's not safe for them to use malloc.
++   Note that if REL_ALLOC is defined, matching would not use malloc for the
++   failure stack, but we would still use it for the register vectors;
++   so REL_ALLOC should not affect this.  */
++# if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
++#  undef MATCH_MAY_ALLOCATE
++# endif
++#endif /* not DEFINED_ONCE */
++\f
++#ifdef INSIDE_RECURSION
++/* Failure stack declarations and macros; both re_compile_fastmap and
++   re_match_2 use a failure stack.  These have to be macros because of
++   REGEX_ALLOCATE_STACK.  */
++
++
++/* Number of failure points for which to initially allocate space
++   when matching.  If this number is exceeded, we allocate more
++   space, so it is not a hard limit.  */
++# ifndef INIT_FAILURE_ALLOC
++#  define INIT_FAILURE_ALLOC 5
++# endif
++
++/* Roughly the maximum number of failure points on the stack.  Would be
++   exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
++   This is a variable only so users of regex can assign to it; we never
++   change it ourselves.  */
++
++
++# ifndef DEFINED_ONCE
++
++#  ifdef INT_IS_16BIT
++#   define RE_M_F_TYPE long int
++#  else
++#   define RE_M_F_TYPE int
++#  endif /* INT_IS_16BIT */
++
++#  ifdef MATCH_MAY_ALLOCATE
++/* 4400 was enough to cause a crash on Alpha OSF/1,
++   whose default stack limit is 2mb.  */
++#   define RE_M_F_DEFAULT 4000
++#  else
++#   define RE_M_F_DEFAULT 2000
++#  endif /* MATCH_MAY_ALLOCATE */
++
++#  include <shlib-compat.h>
++
++#  if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
++link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
++RE_M_F_TYPE re_max_failures = RE_M_F_DEFAULT;
++#  else
++RE_M_F_TYPE re_max_failures attribute_hidden = RE_M_F_DEFAULT;
++#  endif /* SHLIB_COMPAT */
++
++#  undef RE_M_F_TYPE
++#  undef RE_M_F_DEFAULT
++
++# endif /* DEFINED_ONCE */
++
++# ifdef INT_IS_16BIT
++
++union PREFIX(fail_stack_elt)
++{
++  UCHAR_T *pointer;
++  long int integer;
++};
++
++typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
++
++typedef struct
++{
++  PREFIX(fail_stack_elt_t) *stack;
++  unsigned long int size;
++  unsigned long int avail;		/* Offset of next open position.  */
++} PREFIX(fail_stack_type);
++
++# else /* not INT_IS_16BIT */
++
++union PREFIX(fail_stack_elt)
++{
++  UCHAR_T *pointer;
++  int integer;
++};
++
++typedef union PREFIX(fail_stack_elt) PREFIX(fail_stack_elt_t);
++
++typedef struct
++{
++  PREFIX(fail_stack_elt_t) *stack;
++  unsigned size;
++  unsigned avail;			/* Offset of next open position.  */
++} PREFIX(fail_stack_type);
++
++# endif /* INT_IS_16BIT */
++
++# ifndef DEFINED_ONCE
++#  define FAIL_STACK_EMPTY()     (fail_stack.avail == 0)
++#  define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
++#  define FAIL_STACK_FULL()      (fail_stack.avail == fail_stack.size)
++# endif
++
++
++/* Define macros to initialize and free the failure stack.
++   Do `return -2' if the alloc fails.  */
++
++# ifdef MATCH_MAY_ALLOCATE
++#  define INIT_FAIL_STACK()						\
++  do {									\
++    fail_stack.stack = (PREFIX(fail_stack_elt_t) *)		\
++      REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (PREFIX(fail_stack_elt_t))); \
++									\
++    if (fail_stack.stack == NULL)				\
++      return -2;							\
++									\
++    fail_stack.size = INIT_FAILURE_ALLOC;			\
++    fail_stack.avail = 0;					\
++  } while (0)
++
++#  define RESET_FAIL_STACK()  REGEX_FREE_STACK (fail_stack.stack)
++# else
++#  define INIT_FAIL_STACK()						\
++  do {									\
++    fail_stack.avail = 0;					\
++  } while (0)
++
++#  define RESET_FAIL_STACK()
++# endif
++
++
++/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
++
++   Return 1 if succeeds, and 0 if either ran out of memory
++   allocating space for it or it was already too large.
++
++   REGEX_REALLOCATE_STACK requires `destination' be declared.   */
++
++# define DOUBLE_FAIL_STACK(fail_stack)					\
++  ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS)	\
++   ? 0									\
++   : ((fail_stack).stack = (PREFIX(fail_stack_elt_t) *)			\
++        REGEX_REALLOCATE_STACK ((fail_stack).stack, 			\
++          (fail_stack).size * sizeof (PREFIX(fail_stack_elt_t)),	\
++          ((fail_stack).size << 1) * sizeof (PREFIX(fail_stack_elt_t))),\
++									\
++      (fail_stack).stack == NULL					\
++      ? 0								\
++      : ((fail_stack).size <<= 1, 					\
++         1)))
++
++
++/* Push pointer POINTER on FAIL_STACK.
++   Return 1 if was able to do so and 0 if ran out of memory allocating
++   space to do so.  */
++# define PUSH_PATTERN_OP(POINTER, FAIL_STACK)				\
++  ((FAIL_STACK_FULL ()							\
++    && !DOUBLE_FAIL_STACK (FAIL_STACK))					\
++   ? 0									\
++   : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER,	\
++      1))
++
++/* Push a pointer value onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_POINTER(item)					\
++  fail_stack.stack[fail_stack.avail++].pointer = (UCHAR_T *) (item)
++
++/* This pushes an integer-valued item onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_INT(item)					\
++  fail_stack.stack[fail_stack.avail++].integer = (item)
++
++/* Push a fail_stack_elt_t value onto the failure stack.
++   Assumes the variable `fail_stack'.  Probably should only
++   be called from within `PUSH_FAILURE_POINT'.  */
++# define PUSH_FAILURE_ELT(item)					\
++  fail_stack.stack[fail_stack.avail++] =  (item)
++
++/* These three POP... operations complement the three PUSH... operations.
++   All assume that `fail_stack' is nonempty.  */
++# define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
++# define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
++# define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
++
++/* Used to omit pushing failure point id's when we're not debugging.  */
++# ifdef DEBUG
++#  define DEBUG_PUSH PUSH_FAILURE_INT
++#  define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
++# else
++#  define DEBUG_PUSH(item)
++#  define DEBUG_POP(item_addr)
++# endif
++
++
++/* Push the information about the state we will need
++   if we ever fail back to it.
++
++   Requires variables fail_stack, regstart, regend, reg_info, and
++   num_regs_pushed be declared.  DOUBLE_FAIL_STACK requires `destination'
++   be declared.
++
++   Does `return FAILURE_CODE' if runs out of memory.  */
++
++# define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code)	\
++  do {									\
++    char *destination;							\
++    /* Must be int, so when we don't save any registers, the arithmetic	\
++       of 0 + -1 isn't done as unsigned.  */				\
++    /* Can't be int, since there is not a shred of a guarantee that int	\
++       is wide enough to hold a value of something to which pointer can	\
++       be assigned */							\
++    active_reg_t this_reg;						\
++    									\
++    DEBUG_STATEMENT (failure_id++);					\
++    DEBUG_STATEMENT (nfailure_points_pushed++);				\
++    DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id);		\
++    DEBUG_PRINT2 ("  Before push, next avail: %d\n", (fail_stack).avail);\
++    DEBUG_PRINT2 ("                     size: %d\n", (fail_stack).size);\
++									\
++    DEBUG_PRINT2 ("  slots needed: %ld\n", NUM_FAILURE_ITEMS);		\
++    DEBUG_PRINT2 ("     available: %d\n", REMAINING_AVAIL_SLOTS);	\
++									\
++    /* Ensure we have enough space allocated for what we will push.  */	\
++    while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS)			\
++      {									\
++        if (!DOUBLE_FAIL_STACK (fail_stack))				\
++          return failure_code;						\
++									\
++        DEBUG_PRINT2 ("\n  Doubled stack; size now: %d\n",		\
++		       (fail_stack).size);				\
++        DEBUG_PRINT2 ("  slots available: %d\n", REMAINING_AVAIL_SLOTS);\
++      }									\
++									\
++    /* Push the info, starting with the registers.  */			\
++    DEBUG_PRINT1 ("\n");						\
++									\
++    if (1)								\
++      for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
++	   this_reg++)							\
++	{								\
++	  DEBUG_PRINT2 ("  Pushing reg: %lu\n", this_reg);		\
++	  DEBUG_STATEMENT (num_regs_pushed++);				\
++									\
++	  DEBUG_PRINT2 ("    start: %p\n", regstart[this_reg]);		\
++	  PUSH_FAILURE_POINTER (regstart[this_reg]);			\
++									\
++	  DEBUG_PRINT2 ("    end: %p\n", regend[this_reg]);		\
++	  PUSH_FAILURE_POINTER (regend[this_reg]);			\
++									\
++	  DEBUG_PRINT2 ("    info: %p\n      ",				\
++			reg_info[this_reg].word.pointer);		\
++	  DEBUG_PRINT2 (" match_null=%d",				\
++			REG_MATCH_NULL_STRING_P (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" matched_something=%d",			\
++			MATCHED_SOMETHING (reg_info[this_reg]));	\
++	  DEBUG_PRINT2 (" ever_matched=%d",				\
++			EVER_MATCHED_SOMETHING (reg_info[this_reg]));	\
++	  DEBUG_PRINT1 ("\n");						\
++	  PUSH_FAILURE_ELT (reg_info[this_reg].word);			\
++	}								\
++									\
++    DEBUG_PRINT2 ("  Pushing  low active reg: %ld\n", lowest_active_reg);\
++    PUSH_FAILURE_INT (lowest_active_reg);				\
++									\
++    DEBUG_PRINT2 ("  Pushing high active reg: %ld\n", highest_active_reg);\
++    PUSH_FAILURE_INT (highest_active_reg);				\
++									\
++    DEBUG_PRINT2 ("  Pushing pattern %p:\n", pattern_place);		\
++    DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend);		\
++    PUSH_FAILURE_POINTER (pattern_place);				\
++									\
++    DEBUG_PRINT2 ("  Pushing string %p: `", string_place);		\
++    DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2,   \
++				 size2);				\
++    DEBUG_PRINT1 ("'\n");						\
++    PUSH_FAILURE_POINTER (string_place);				\
++									\
++    DEBUG_PRINT2 ("  Pushing failure id: %u\n", failure_id);		\
++    DEBUG_PUSH (failure_id);						\
++  } while (0)
++
++# ifndef DEFINED_ONCE
++/* This is the number of items that are pushed and popped on the stack
++   for each register.  */
++#  define NUM_REG_ITEMS  3
++
++/* Individual items aside from the registers.  */
++#  ifdef DEBUG
++#   define NUM_NONREG_ITEMS 5 /* Includes failure point id.  */
++#  else
++#   define NUM_NONREG_ITEMS 4
++#  endif
++
++/* We push at most this many items on the stack.  */
++/* We used to use (num_regs - 1), which is the number of registers
++   this regexp will save; but that was changed to 5
++   to avoid stack overflow for a regexp with lots of parens.  */
++#  define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
++
++/* We actually push this many items.  */
++#  define NUM_FAILURE_ITEMS				\
++  (((0							\
++     ? 0 : highest_active_reg - lowest_active_reg + 1)	\
++    * NUM_REG_ITEMS)					\
++   + NUM_NONREG_ITEMS)
++
++/* How many items can still be added to the stack without overflowing it.  */
++#  define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
++# endif /* not DEFINED_ONCE */
++
++
++/* Pops what PUSH_FAIL_STACK pushes.
++
++   We restore into the parameters, all of which should be lvalues:
++     STR -- the saved data position.
++     PAT -- the saved pattern position.
++     LOW_REG, HIGH_REG -- the highest and lowest active registers.
++     REGSTART, REGEND -- arrays of string positions.
++     REG_INFO -- array of information about each subexpression.
++
++   Also assumes the variables `fail_stack' and (if debugging), `bufp',
++   `pend', `string1', `size1', `string2', and `size2'.  */
++# define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
++{									\
++  DEBUG_STATEMENT (unsigned failure_id;)				\
++  active_reg_t this_reg;						\
++  const UCHAR_T *string_temp;						\
++									\
++  assert (!FAIL_STACK_EMPTY ());					\
++									\
++  /* Remove failure points and point to how many regs pushed.  */	\
++  DEBUG_PRINT1 ("POP_FAILURE_POINT:\n");				\
++  DEBUG_PRINT2 ("  Before pop, next avail: %d\n", fail_stack.avail);	\
++  DEBUG_PRINT2 ("                    size: %d\n", fail_stack.size);	\
++									\
++  assert (fail_stack.avail >= NUM_NONREG_ITEMS);			\
++									\
++  DEBUG_POP (&failure_id);						\
++  DEBUG_PRINT2 ("  Popping failure id: %u\n", failure_id);		\
++									\
++  /* If the saved string location is NULL, it came from an		\
++     on_failure_keep_string_jump opcode, and we want to throw away the	\
++     saved NULL, thus retaining our current position in the string.  */	\
++  string_temp = POP_FAILURE_POINTER ();					\
++  if (string_temp != NULL)						\
++    str = (const CHAR_T *) string_temp;					\
++									\
++  DEBUG_PRINT2 ("  Popping string %p: `", str);				\
++  DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2);	\
++  DEBUG_PRINT1 ("'\n");							\
++									\
++  pat = (UCHAR_T *) POP_FAILURE_POINTER ();				\
++  DEBUG_PRINT2 ("  Popping pattern %p:\n", pat);			\
++  DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend);			\
++									\
++  /* Restore register info.  */						\
++  high_reg = (active_reg_t) POP_FAILURE_INT ();				\
++  DEBUG_PRINT2 ("  Popping high active reg: %ld\n", high_reg);		\
++									\
++  low_reg = (active_reg_t) POP_FAILURE_INT ();				\
++  DEBUG_PRINT2 ("  Popping  low active reg: %ld\n", low_reg);		\
++									\
++  if (1)								\
++    for (this_reg = high_reg; this_reg >= low_reg; this_reg--)		\
++      {									\
++	DEBUG_PRINT2 ("    Popping reg: %ld\n", this_reg);		\
++									\
++	reg_info[this_reg].word = POP_FAILURE_ELT ();			\
++	DEBUG_PRINT2 ("      info: %p\n",				\
++		      reg_info[this_reg].word.pointer);			\
++									\
++	regend[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER ();	\
++	DEBUG_PRINT2 ("      end: %p\n", regend[this_reg]);		\
++									\
++	regstart[this_reg] = (const CHAR_T *) POP_FAILURE_POINTER ();	\
++	DEBUG_PRINT2 ("      start: %p\n", regstart[this_reg]);		\
++      }									\
++  else									\
++    {									\
++      for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
++	{								\
++	  reg_info[this_reg].word.integer = 0;				\
++	  regend[this_reg] = 0;						\
++	  regstart[this_reg] = 0;					\
++	}								\
++      highest_active_reg = high_reg;					\
++    }									\
++									\
++  set_regs_matched_done = 0;						\
++  DEBUG_STATEMENT (nfailure_points_popped++);				\
++} /* POP_FAILURE_POINT */
++\f
++/* Structure for per-register (a.k.a. per-group) information.
++   Other register information, such as the
++   starting and ending positions (which are addresses), and the list of
++   inner groups (which is a bits list) are maintained in separate
++   variables.
++
++   We are making a (strictly speaking) nonportable assumption here: that
++   the compiler will pack our bit fields into something that fits into
++   the type of `word', i.e., is something that fits into one item on the
++   failure stack.  */
++
++
++/* Declarations and macros for re_match_2.  */
++
++typedef union
++{
++  PREFIX(fail_stack_elt_t) word;
++  struct
++  {
++      /* This field is one if this group can match the empty string,
++         zero if not.  If not yet determined,  `MATCH_NULL_UNSET_VALUE'.  */
++# define MATCH_NULL_UNSET_VALUE 3
++    unsigned match_null_string_p : 2;
++    unsigned is_active : 1;
++    unsigned matched_something : 1;
++    unsigned ever_matched_something : 1;
++  } bits;
++} PREFIX(register_info_type);
++
++# ifndef DEFINED_ONCE
++#  define REG_MATCH_NULL_STRING_P(R)  ((R).bits.match_null_string_p)
++#  define IS_ACTIVE(R)  ((R).bits.is_active)
++#  define MATCHED_SOMETHING(R)  ((R).bits.matched_something)
++#  define EVER_MATCHED_SOMETHING(R)  ((R).bits.ever_matched_something)
++
++
++/* Call this when have matched a real character; it sets `matched' flags
++   for the subexpressions which we are currently inside.  Also records
++   that those subexprs have matched.  */
++#  define SET_REGS_MATCHED()						\
++  do									\
++    {									\
++      if (!set_regs_matched_done)					\
++	{								\
++	  active_reg_t r;						\
++	  set_regs_matched_done = 1;					\
++	  for (r = lowest_active_reg; r <= highest_active_reg; r++)	\
++	    {								\
++	      MATCHED_SOMETHING (reg_info[r])				\
++		= EVER_MATCHED_SOMETHING (reg_info[r])			\
++		= 1;							\
++	    }								\
++	}								\
++    }									\
++  while (0)
++# endif /* not DEFINED_ONCE */
++
++/* Registers are set to a sentinel when they haven't yet matched.  */
++static CHAR_T PREFIX(reg_unset_dummy);
++# define REG_UNSET_VALUE (&PREFIX(reg_unset_dummy))
++# define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
++
++/* Subroutine declarations and macros for regex_compile.  */
++static void PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg);
++static void PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc,
++                               int arg1, int arg2);
++static void PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc,
++                                int arg, UCHAR_T *end);
++static void PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc,
++                                int arg1, int arg2, UCHAR_T *end);
++static boolean PREFIX(at_begline_loc_p) (const CHAR_T *pattern,
++                                         const CHAR_T *p,
++                                         reg_syntax_t syntax);
++static boolean PREFIX(at_endline_loc_p) (const CHAR_T *p,
++                                         const CHAR_T *pend,
++                                         reg_syntax_t syntax);
++# ifdef WCHAR
++static reg_errcode_t wcs_compile_range (CHAR_T range_start,
++                                        const CHAR_T **p_ptr,
++                                        const CHAR_T *pend,
++                                        char *translate,
++                                        reg_syntax_t syntax,
++                                        UCHAR_T *b,
++                                        CHAR_T *char_set);
++static void insert_space (int num, CHAR_T *loc, CHAR_T *end);
++# else /* BYTE */
++static reg_errcode_t byte_compile_range (unsigned int range_start,
++                                         const char **p_ptr,
++                                         const char *pend,
++                                         RE_TRANSLATE_TYPE translate,
++                                         reg_syntax_t syntax,
++                                         unsigned char *b);
++# endif /* WCHAR */
++
++/* Fetch the next character in the uncompiled pattern---translating it
++   if necessary.  Also cast from a signed character in the constant
++   string passed to us by the user to an unsigned char that we can use
++   as an array index (in, e.g., `translate').  */
++/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
++   because it is impossible to allocate 4GB array for some encodings
++   which have 4 byte character_set like UCS4.  */
++# ifndef PATFETCH
++#  ifdef WCHAR
++#   define PATFETCH(c)							\
++  do {if (p == pend) return REG_EEND;					\
++    c = (UCHAR_T) *p++;							\
++    if (translate && (c <= 0xff)) c = (UCHAR_T) translate[c];		\
++  } while (0)
++#  else /* BYTE */
++#   define PATFETCH(c)							\
++  do {if (p == pend) return REG_EEND;					\
++    c = (unsigned char) *p++;						\
++    if (translate) c = (unsigned char) translate[c];			\
++  } while (0)
++#  endif /* WCHAR */
++# endif
++
++/* Fetch the next character in the uncompiled pattern, with no
++   translation.  */
++# define PATFETCH_RAW(c)						\
++  do {if (p == pend) return REG_EEND;					\
++    c = (UCHAR_T) *p++; 	       					\
++  } while (0)
++
++/* Go backwards one character in the pattern.  */
++# define PATUNFETCH p--
++
++
++/* If `translate' is non-null, return translate[D], else just D.  We
++   cast the subscript to translate because some data is declared as
++   `char *', to avoid warnings when a string constant is passed.  But
++   when we use a character as a subscript we must make it unsigned.  */
++/* ifdef MBS_SUPPORT, we translate only if character <= 0xff,
++   because it is impossible to allocate 4GB array for some encodings
++   which have 4 byte character_set like UCS4.  */
++
++# ifndef TRANSLATE
++#  ifdef WCHAR
++#   define TRANSLATE(d) \
++  ((translate && ((UCHAR_T) (d)) <= 0xff) \
++   ? (char) translate[(unsigned char) (d)] : (d))
++# else /* BYTE */
++#   define TRANSLATE(d) \
++  (translate ? (char) translate[(unsigned char) (d)] : (char) (d))
++#  endif /* WCHAR */
++# endif
++
++
++/* Macros for outputting the compiled pattern into `buffer'.  */
++
++/* If the buffer isn't allocated when it comes in, use this.  */
++# define INIT_BUF_SIZE  (32 * sizeof(UCHAR_T))
++
++/* Make sure we have at least N more bytes of space in buffer.  */
++# ifdef WCHAR
++#  define GET_BUFFER_SPACE(n)						\
++    while (((unsigned long)b - (unsigned long)COMPILED_BUFFER_VAR	\
++            + (n)*sizeof(CHAR_T)) > bufp->allocated)			\
++      EXTEND_BUFFER ()
++# else /* BYTE */
++#  define GET_BUFFER_SPACE(n)						\
++    while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated)	\
++      EXTEND_BUFFER ()
++# endif /* WCHAR */
++
++/* Make sure we have one more byte of buffer space and then add C to it.  */
++# define BUF_PUSH(c)							\
++  do {									\
++    GET_BUFFER_SPACE (1);						\
++    *b++ = (UCHAR_T) (c);						\
++  } while (0)
++
++
++/* Ensure we have two more bytes of buffer space and then append C1 and C2.  */
++# define BUF_PUSH_2(c1, c2)						\
++  do {									\
++    GET_BUFFER_SPACE (2);						\
++    *b++ = (UCHAR_T) (c1);						\
++    *b++ = (UCHAR_T) (c2);						\
++  } while (0)
++
++
++/* As with BUF_PUSH_2, except for three bytes.  */
++# define BUF_PUSH_3(c1, c2, c3)						\
++  do {									\
++    GET_BUFFER_SPACE (3);						\
++    *b++ = (UCHAR_T) (c1);						\
++    *b++ = (UCHAR_T) (c2);						\
++    *b++ = (UCHAR_T) (c3);						\
++  } while (0)
++
++/* Store a jump with opcode OP at LOC to location TO.  We store a
++   relative address offset by the three bytes the jump itself occupies.  */
++# define STORE_JUMP(op, loc, to) \
++ PREFIX(store_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)))
++
++/* Likewise, for a two-argument jump.  */
++# define STORE_JUMP2(op, loc, to, arg) \
++  PREFIX(store_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), arg)
++
++/* Like `STORE_JUMP', but for inserting.  Assume `b' is the buffer end.  */
++# define INSERT_JUMP(op, loc, to) \
++  PREFIX(insert_op1) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)), b)
++
++/* Like `STORE_JUMP2', but for inserting.  Assume `b' is the buffer end.  */
++# define INSERT_JUMP2(op, loc, to, arg) \
++  PREFIX(insert_op2) (op, loc, (int) ((to) - (loc) - (1 + OFFSET_ADDRESS_SIZE)),\
++	      arg, b)
++
++/* This is not an arbitrary limit: the arguments which represent offsets
++   into the pattern are two bytes long.  So if 2^16 bytes turns out to
++   be too small, many things would have to change.  */
++/* Any other compiler which, like MSC, has allocation limit below 2^16
++   bytes will have to use approach similar to what was done below for
++   MSC and drop MAX_BUF_SIZE a bit.  Otherwise you may end up
++   reallocating to 0 bytes.  Such thing is not going to work too well.
++   You have been warned!!  */
++# ifndef DEFINED_ONCE
++#  if defined _MSC_VER  && !defined WIN32
++/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
++   The REALLOC define eliminates a flurry of conversion warnings,
++   but is not required. */
++#   define MAX_BUF_SIZE  65500L
++#   define REALLOC(p,s) realloc ((p), (size_t) (s))
++#  else
++#   define MAX_BUF_SIZE (1L << 16)
++#   define REALLOC(p,s) realloc ((p), (s))
++#  endif
++
++/* Extend the buffer by twice its current size via realloc and
++   reset the pointers that pointed into the old block to point to the
++   correct places in the new one.  If extending the buffer results in it
++   being larger than MAX_BUF_SIZE, then flag memory exhausted.  */
++#  if __BOUNDED_POINTERS__
++#   define SET_HIGH_BOUND(P) (__ptrhigh (P) = __ptrlow (P) + bufp->allocated)
++#   define MOVE_BUFFER_POINTER(P) \
++  (__ptrlow (P) += incr, SET_HIGH_BOUND (P), __ptrvalue (P) += incr)
++#   define ELSE_EXTEND_BUFFER_HIGH_BOUND	\
++  else						\
++    {						\
++      SET_HIGH_BOUND (b);			\
++      SET_HIGH_BOUND (begalt);			\
++      if (fixup_alt_jump)			\
++	SET_HIGH_BOUND (fixup_alt_jump);	\
++      if (laststart)				\
++	SET_HIGH_BOUND (laststart);		\
++      if (pending_exact)			\
++	SET_HIGH_BOUND (pending_exact);		\
++    }
++#  else
++#   define MOVE_BUFFER_POINTER(P) (P) += incr
++#   define ELSE_EXTEND_BUFFER_HIGH_BOUND
++#  endif
++# endif /* not DEFINED_ONCE */
++
++# ifdef WCHAR
++#  define EXTEND_BUFFER()						\
++  do {									\
++    UCHAR_T *old_buffer = COMPILED_BUFFER_VAR;				\
++    int wchar_count;							\
++    if (bufp->allocated + sizeof(UCHAR_T) > MAX_BUF_SIZE)		\
++      return REG_ESIZE;							\
++    bufp->allocated <<= 1;						\
++    if (bufp->allocated > MAX_BUF_SIZE)					\
++      bufp->allocated = MAX_BUF_SIZE;					\
++    /* How many characters the new buffer can have?  */			\
++    wchar_count = bufp->allocated / sizeof(UCHAR_T);			\
++    if (wchar_count == 0) wchar_count = 1;				\
++    /* Truncate the buffer to CHAR_T align.  */			\
++    bufp->allocated = wchar_count * sizeof(UCHAR_T);			\
++    RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T);		\
++    bufp->buffer = (char*)COMPILED_BUFFER_VAR;				\
++    if (COMPILED_BUFFER_VAR == NULL)					\
++      return REG_ESPACE;						\
++    /* If the buffer moved, move all the pointers into it.  */		\
++    if (old_buffer != COMPILED_BUFFER_VAR)				\
++      {									\
++	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
++	MOVE_BUFFER_POINTER (b);					\
++	MOVE_BUFFER_POINTER (begalt);					\
++	if (fixup_alt_jump)						\
++	  MOVE_BUFFER_POINTER (fixup_alt_jump);				\
++	if (laststart)							\
++	  MOVE_BUFFER_POINTER (laststart);				\
++	if (pending_exact)						\
++	  MOVE_BUFFER_POINTER (pending_exact);				\
++      }									\
++    ELSE_EXTEND_BUFFER_HIGH_BOUND					\
++  } while (0)
++# else /* BYTE */
++#  define EXTEND_BUFFER()						\
++  do {									\
++    UCHAR_T *old_buffer = COMPILED_BUFFER_VAR;				\
++    if (bufp->allocated == MAX_BUF_SIZE)				\
++      return REG_ESIZE;							\
++    bufp->allocated <<= 1;						\
++    if (bufp->allocated > MAX_BUF_SIZE)					\
++      bufp->allocated = MAX_BUF_SIZE;					\
++    bufp->buffer = (UCHAR_T *) REALLOC (COMPILED_BUFFER_VAR,		\
++						bufp->allocated);	\
++    if (COMPILED_BUFFER_VAR == NULL)					\
++      return REG_ESPACE;						\
++    /* If the buffer moved, move all the pointers into it.  */		\
++    if (old_buffer != COMPILED_BUFFER_VAR)				\
++      {									\
++	int incr = COMPILED_BUFFER_VAR - old_buffer;			\
++	MOVE_BUFFER_POINTER (b);					\
++	MOVE_BUFFER_POINTER (begalt);					\
++	if (fixup_alt_jump)						\
++	  MOVE_BUFFER_POINTER (fixup_alt_jump);				\
++	if (laststart)							\
++	  MOVE_BUFFER_POINTER (laststart);				\
++	if (pending_exact)						\
++	  MOVE_BUFFER_POINTER (pending_exact);				\
++      }									\
++    ELSE_EXTEND_BUFFER_HIGH_BOUND					\
++  } while (0)
++# endif /* WCHAR */
++
++# ifndef DEFINED_ONCE
++/* Since we have one byte reserved for the register number argument to
++   {start,stop}_memory, the maximum number of groups we can report
++   things about is what fits in that byte.  */
++#  define MAX_REGNUM 255
++
++/* But patterns can have more than `MAX_REGNUM' registers.  We just
++   ignore the excess.  */
++typedef unsigned regnum_t;
++
++
++/* Macros for the compile stack.  */
++
++/* Since offsets can go either forwards or backwards, this type needs to
++   be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1.  */
++/* int may be not enough when sizeof(int) == 2.  */
++typedef long pattern_offset_t;
++
++typedef struct
++{
++  pattern_offset_t begalt_offset;
++  pattern_offset_t fixup_alt_jump;
++  pattern_offset_t inner_group_offset;
++  pattern_offset_t laststart_offset;
++  regnum_t regnum;
++} compile_stack_elt_t;
++
++
++typedef struct
++{
++  compile_stack_elt_t *stack;
++  unsigned size;
++  unsigned avail;			/* Offset of next open position.  */
++} compile_stack_type;
++
++
++#  define INIT_COMPILE_STACK_SIZE 32
++
++#  define COMPILE_STACK_EMPTY  (compile_stack.avail == 0)
++#  define COMPILE_STACK_FULL  (compile_stack.avail == compile_stack.size)
++
++/* The next available element.  */
++#  define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
++
++# endif /* not DEFINED_ONCE */
++
++/* Set the bit for character C in a list.  */
++# ifndef DEFINED_ONCE
++#  define SET_LIST_BIT(c)                               \
++  (b[((unsigned char) (c)) / BYTEWIDTH]               \
++   |= 1 << (((unsigned char) c) % BYTEWIDTH))
++# endif /* DEFINED_ONCE */
++
++/* Get the next unsigned number in the uncompiled pattern.  */
++# define GET_UNSIGNED_NUMBER(num) \
++  {									\
++    while (p != pend)							\
++      {									\
++	PATFETCH (c);							\
++	if (c < '0' || c > '9')						\
++	  break;							\
++	if (num <= RE_DUP_MAX)						\
++	  {								\
++	    if (num < 0)						\
++	      num = 0;							\
++	    num = num * 10 + c - '0';					\
++	  }								\
++      }									\
++  }
++
++# ifndef DEFINED_ONCE
++#  if WIDE_CHAR_SUPPORT
++/* The GNU C library provides support for user-defined character classes
++   and the functions from ISO C amendement 1.  */
++#   ifdef CHARCLASS_NAME_MAX
++#    define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
++#   else
++/* This shouldn't happen but some implementation might still have this
++   problem.  Use a reasonable default value.  */
++#    define CHAR_CLASS_MAX_LENGTH 256
++#   endif
++
++#   ifdef _LIBC
++#    define IS_CHAR_CLASS(string) __wctype (string)
++#   else
++#    define IS_CHAR_CLASS(string) wctype (string)
++#   endif
++#  else
++#   define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
++
++#   define IS_CHAR_CLASS(string)					\
++   (STREQ (string, "alpha") || STREQ (string, "upper")			\
++    || STREQ (string, "lower") || STREQ (string, "digit")		\
++    || STREQ (string, "alnum") || STREQ (string, "xdigit")		\
++    || STREQ (string, "space") || STREQ (string, "print")		\
++    || STREQ (string, "punct") || STREQ (string, "graph")		\
++    || STREQ (string, "cntrl") || STREQ (string, "blank"))
++#  endif
++# endif /* DEFINED_ONCE */
++\f
++# ifndef MATCH_MAY_ALLOCATE
++
++/* If we cannot allocate large objects within re_match_2_internal,
++   we make the fail stack and register vectors global.
++   The fail stack, we grow to the maximum size when a regexp
++   is compiled.
++   The register vectors, we adjust in size each time we
++   compile a regexp, according to the number of registers it needs.  */
++
++static PREFIX(fail_stack_type) fail_stack;
++
++/* Size with which the following vectors are currently allocated.
++   That is so we can make them bigger as needed,
++   but never make them smaller.  */
++#  ifdef DEFINED_ONCE
++static int regs_allocated_size;
++
++static const char **     regstart, **     regend;
++static const char ** old_regstart, ** old_regend;
++static const char **best_regstart, **best_regend;
++static const char **reg_dummy;
++#  endif /* DEFINED_ONCE */
++
++static PREFIX(register_info_type) *PREFIX(reg_info);
++static PREFIX(register_info_type) *PREFIX(reg_info_dummy);
++
++/* Make the register vectors big enough for NUM_REGS registers,
++   but don't make them smaller.  */
++
++static void
++PREFIX(regex_grow_registers) (int num_regs)
++{
++  if (num_regs > regs_allocated_size)
++    {
++      RETALLOC_IF (regstart,	 num_regs, const char *);
++      RETALLOC_IF (regend,	 num_regs, const char *);
++      RETALLOC_IF (old_regstart, num_regs, const char *);
++      RETALLOC_IF (old_regend,	 num_regs, const char *);
++      RETALLOC_IF (best_regstart, num_regs, const char *);
++      RETALLOC_IF (best_regend,	 num_regs, const char *);
++      RETALLOC_IF (PREFIX(reg_info), num_regs, PREFIX(register_info_type));
++      RETALLOC_IF (reg_dummy,	 num_regs, const char *);
++      RETALLOC_IF (PREFIX(reg_info_dummy), num_regs, PREFIX(register_info_type));
++
++      regs_allocated_size = num_regs;
++    }
++}
++
++# endif /* not MATCH_MAY_ALLOCATE */
++\f
++# ifndef DEFINED_ONCE
++static boolean group_in_compile_stack (compile_stack_type compile_stack,
++                                       regnum_t regnum);
++# endif /* not DEFINED_ONCE */
++
++/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
++   Returns one of error codes defined in `regex.h', or zero for success.
++
++   Assumes the `allocated' (and perhaps `buffer') and `translate'
++   fields are set in BUFP on entry.
++
++   If it succeeds, results are put in BUFP (if it returns an error, the
++   contents of BUFP are undefined):
++     `buffer' is the compiled pattern;
++     `syntax' is set to SYNTAX;
++     `used' is set to the length of the compiled pattern;
++     `fastmap_accurate' is zero;
++     `re_nsub' is the number of subexpressions in PATTERN;
++     `not_bol' and `not_eol' are zero;
++
++   The `fastmap' and `newline_anchor' fields are neither
++   examined nor set.  */
++
++/* Return, freeing storage we allocated.  */
++# ifdef WCHAR
++#  define FREE_STACK_RETURN(value)		\
++  return (free(pattern), free(mbs_offset), free(is_binary), free (compile_stack.stack), value)
++# else
++#  define FREE_STACK_RETURN(value)		\
++  return (free (compile_stack.stack), value)
++# endif /* WCHAR */
++
++static reg_errcode_t
++PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
++                       size_t ARG_PREFIX(size), reg_syntax_t syntax,
++                       struct re_pattern_buffer *bufp)
++{
++  /* We fetch characters from PATTERN here.  Even though PATTERN is
++     `char *' (i.e., signed), we declare these variables as unsigned, so
++     they can be reliably used as array indices.  */
++  register UCHAR_T c, c1;
++
++#ifdef WCHAR
++  /* A temporary space to keep wchar_t pattern and compiled pattern.  */
++  CHAR_T *pattern, *COMPILED_BUFFER_VAR;
++  size_t size;
++  /* offset buffer for optimization. See convert_mbs_to_wc.  */
++  int *mbs_offset = NULL;
++  /* It hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++  /* A flag whether exactn is handling binary data or not.  */
++  char is_exactn_bin = FALSE;
++#endif /* WCHAR */
++
++  /* A random temporary spot in PATTERN.  */
++  const CHAR_T *p1;
++
++  /* Points to the end of the buffer, where we should append.  */
++  register UCHAR_T *b;
++
++  /* Keeps track of unclosed groups.  */
++  compile_stack_type compile_stack;
++
++  /* Points to the current (ending) position in the pattern.  */
++#ifdef WCHAR
++  const CHAR_T *p;
++  const CHAR_T *pend;
++#else /* BYTE */
++  const CHAR_T *p = pattern;
++  const CHAR_T *pend = pattern + size;
++#endif /* WCHAR */
++
++  /* How to translate the characters in the pattern.  */
++  RE_TRANSLATE_TYPE translate = bufp->translate;
++
++  /* Address of the count-byte of the most recently inserted `exactn'
++     command.  This makes it possible to tell if a new exact-match
++     character can be added to that command or if the character requires
++     a new `exactn' command.  */
++  UCHAR_T *pending_exact = 0;
++
++  /* Address of start of the most recently finished expression.
++     This tells, e.g., postfix * where to find the start of its
++     operand.  Reset at the beginning of groups and alternatives.  */
++  UCHAR_T *laststart = 0;
++
++  /* Address of beginning of regexp, or inside of last group.  */
++  UCHAR_T *begalt;
++
++  /* Address of the place where a forward jump should go to the end of
++     the containing expression.  Each alternative of an `or' -- except the
++     last -- ends with a forward jump of this sort.  */
++  UCHAR_T *fixup_alt_jump = 0;
++
++  /* Counts open-groups as they are encountered.  Remembered for the
++     matching close-group on the compile stack, so the same register
++     number is put in the stop_memory as the start_memory.  */
++  regnum_t regnum = 0;
++
++#ifdef WCHAR
++  /* Initialize the wchar_t PATTERN and offset_buffer.  */
++  p = pend = pattern = TALLOC(csize + 1, CHAR_T);
++  mbs_offset = TALLOC(csize + 1, int);
++  is_binary = TALLOC(csize + 1, char);
++  if (pattern == NULL || mbs_offset == NULL || is_binary == NULL)
++    {
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++      return REG_ESPACE;
++    }
++  pattern[csize] = L'\0';	/* sentinel */
++  size = convert_mbs_to_wcs(pattern, cpattern, csize, mbs_offset, is_binary);
++  pend = p + size;
++  if (size < 0)
++    {
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++      return REG_BADPAT;
++    }
++#endif
++
++#ifdef DEBUG
++  DEBUG_PRINT1 ("\nCompiling pattern: ");
++  if (debug)
++    {
++      unsigned debug_count;
++
++      for (debug_count = 0; debug_count < size; debug_count++)
++        PUT_CHAR (pattern[debug_count]);
++      putchar ('\n');
++    }
++#endif /* DEBUG */
++
++  /* Initialize the compile stack.  */
++  compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
++  if (compile_stack.stack == NULL)
++    {
++#ifdef WCHAR
++      free(pattern);
++      free(mbs_offset);
++      free(is_binary);
++#endif
++      return REG_ESPACE;
++    }
++
++  compile_stack.size = INIT_COMPILE_STACK_SIZE;
++  compile_stack.avail = 0;
++
++  /* Initialize the pattern buffer.  */
++  bufp->syntax = syntax;
++  bufp->fastmap_accurate = 0;
++  bufp->not_bol = bufp->not_eol = 0;
++
++  /* Set `used' to zero, so that if we return an error, the pattern
++     printer (for debugging) will think there's no pattern.  We reset it
++     at the end.  */
++  bufp->used = 0;
++
++  /* Always count groups, whether or not bufp->no_sub is set.  */
++  bufp->re_nsub = 0;
++
++#if !defined emacs && !defined SYNTAX_TABLE
++  /* Initialize the syntax table.  */
++   init_syntax_once ();
++#endif
++
++  if (bufp->allocated == 0)
++    {
++      if (bufp->buffer)
++	{ /* If zero allocated, but buffer is non-null, try to realloc
++             enough space.  This loses if buffer's address is bogus, but
++             that is the user's responsibility.  */
++#ifdef WCHAR
++	  /* Free bufp->buffer and allocate an array for wchar_t pattern
++	     buffer.  */
++          free(bufp->buffer);
++          COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE/sizeof(UCHAR_T),
++					UCHAR_T);
++#else
++          RETALLOC (COMPILED_BUFFER_VAR, INIT_BUF_SIZE, UCHAR_T);
++#endif /* WCHAR */
++        }
++      else
++        { /* Caller did not allocate a buffer.  Do it for them.  */
++          COMPILED_BUFFER_VAR = TALLOC (INIT_BUF_SIZE / sizeof(UCHAR_T),
++					UCHAR_T);
++        }
++
++      if (!COMPILED_BUFFER_VAR) FREE_STACK_RETURN (REG_ESPACE);
++#ifdef WCHAR
++      bufp->buffer = (char*)COMPILED_BUFFER_VAR;
++#endif /* WCHAR */
++      bufp->allocated = INIT_BUF_SIZE;
++    }
++#ifdef WCHAR
++  else
++    COMPILED_BUFFER_VAR = (UCHAR_T*) bufp->buffer;
++#endif
++
++  begalt = b = COMPILED_BUFFER_VAR;
++
++  /* Loop through the uncompiled pattern until we're at the end.  */
++  while (p != pend)
++    {
++      PATFETCH (c);
++
++      switch (c)
++        {
++        case '^':
++          {
++            if (   /* If at start of pattern, it's an operator.  */
++                   p == pattern + 1
++                   /* If context independent, it's an operator.  */
++                || syntax & RE_CONTEXT_INDEP_ANCHORS
++                   /* Otherwise, depends on what's come before.  */
++                || PREFIX(at_begline_loc_p) (pattern, p, syntax))
++              BUF_PUSH (begline);
++            else
++              goto normal_char;
++          }
++          break;
++
++
++        case '$':
++          {
++            if (   /* If at end of pattern, it's an operator.  */
++                   p == pend
++                   /* If context independent, it's an operator.  */
++                || syntax & RE_CONTEXT_INDEP_ANCHORS
++                   /* Otherwise, depends on what's next.  */
++                || PREFIX(at_endline_loc_p) (p, pend, syntax))
++               BUF_PUSH (endline);
++             else
++               goto normal_char;
++           }
++           break;
++
++
++	case '+':
++        case '?':
++          if ((syntax & RE_BK_PLUS_QM)
++              || (syntax & RE_LIMITED_OPS))
++            goto normal_char;
++        handle_plus:
++        case '*':
++          /* If there is no previous pattern... */
++          if (!laststart)
++            {
++              if (syntax & RE_CONTEXT_INVALID_OPS)
++                FREE_STACK_RETURN (REG_BADRPT);
++              else if (!(syntax & RE_CONTEXT_INDEP_OPS))
++                goto normal_char;
++            }
++
++          {
++            /* Are we optimizing this jump?  */
++            boolean keep_string_p = false;
++
++            /* 1 means zero (many) matches is allowed.  */
++            char zero_times_ok = 0, many_times_ok = 0;
++
++            /* If there is a sequence of repetition chars, collapse it
++               down to just one (the right one).  We can't combine
++               interval operators with these because of, e.g., `a{2}*',
++               which should only match an even number of `a's.  */
++
++            for (;;)
++              {
++                zero_times_ok |= c != '+';
++                many_times_ok |= c != '?';
++
++                if (p == pend)
++                  break;
++
++                PATFETCH (c);
++
++                if (c == '*'
++                    || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
++                  ;
++
++                else if (syntax & RE_BK_PLUS_QM  &&  c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++                    if (!(c1 == '+' || c1 == '?'))
++                      {
++                        PATUNFETCH;
++                        PATUNFETCH;
++                        break;
++                      }
++
++                    c = c1;
++                  }
++                else
++                  {
++                    PATUNFETCH;
++                    break;
++                  }
++
++                /* If we get here, we found another repeat character.  */
++               }
++
++            /* Star, etc. applied to an empty pattern is equivalent
++               to an empty pattern.  */
++            if (!laststart)
++              break;
++
++            /* Now we know whether or not zero matches is allowed
++               and also whether or not two or more matches is allowed.  */
++            if (many_times_ok)
++              { /* More than one repetition is allowed, so put in at the
++                   end a backward relative jump from `b' to before the next
++                   jump we're going to put in below (which jumps from
++                   laststart to after this jump).
++
++                   But if we are at the `*' in the exact sequence `.*\n',
++                   insert an unconditional jump backwards to the .,
++                   instead of the beginning of the loop.  This way we only
++                   push a failure point once, instead of every time
++                   through the loop.  */
++                assert (p - 1 > pattern);
++
++                /* Allocate the space for the jump.  */
++                GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++
++                /* We know we are not at the first character of the pattern,
++                   because laststart was nonzero.  And we've already
++                   incremented `p', by the way, to be the character after
++                   the `*'.  Do we have to do something analogous here
++                   for null bytes, because of RE_DOT_NOT_NULL?  */
++                if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
++		    && zero_times_ok
++                    && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
++                    && !(syntax & RE_DOT_NEWLINE))
++                  { /* We have .*\n.  */
++                    STORE_JUMP (jump, b, laststart);
++                    keep_string_p = true;
++                  }
++                else
++                  /* Anything else.  */
++                  STORE_JUMP (maybe_pop_jump, b, laststart -
++			      (1 + OFFSET_ADDRESS_SIZE));
++
++                /* We've added more stuff to the buffer.  */
++                b += 1 + OFFSET_ADDRESS_SIZE;
++              }
++
++            /* On failure, jump from laststart to b + 3, which will be the
++               end of the buffer after this jump is inserted.  */
++	    /* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE' instead of
++	       'b + 3'.  */
++            GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++            INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
++                                       : on_failure_jump,
++                         laststart, b + 1 + OFFSET_ADDRESS_SIZE);
++            pending_exact = 0;
++            b += 1 + OFFSET_ADDRESS_SIZE;
++
++            if (!zero_times_ok)
++              {
++                /* At least one repetition is required, so insert a
++                   `dummy_failure_jump' before the initial
++                   `on_failure_jump' instruction of the loop. This
++                   effects a skip over that instruction the first time
++                   we hit that loop.  */
++                GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++                INSERT_JUMP (dummy_failure_jump, laststart, laststart +
++			     2 + 2 * OFFSET_ADDRESS_SIZE);
++                b += 1 + OFFSET_ADDRESS_SIZE;
++              }
++            }
++	  break;
++
++
++	case '.':
++          laststart = b;
++          BUF_PUSH (anychar);
++          break;
++
++
++        case '[':
++          {
++            boolean had_char_class = false;
++#ifdef WCHAR
++	    CHAR_T range_start = 0xffffffff;
++#else
++	    unsigned int range_start = 0xffffffff;
++#endif
++            if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++#ifdef WCHAR
++	    /* We assume a charset(_not) structure as a wchar_t array.
++	       charset[0] = (re_opcode_t) charset(_not)
++               charset[1] = l (= length of char_classes)
++               charset[2] = m (= length of collating_symbols)
++               charset[3] = n (= length of equivalence_classes)
++	       charset[4] = o (= length of char_ranges)
++	       charset[5] = p (= length of chars)
++
++               charset[6] = char_class (wctype_t)
++               charset[6+CHAR_CLASS_SIZE] = char_class (wctype_t)
++                         ...
++               charset[l+5]  = char_class (wctype_t)
++
++               charset[l+6]  = collating_symbol (wchar_t)
++                            ...
++               charset[l+m+5]  = collating_symbol (wchar_t)
++					ifdef _LIBC we use the index if
++					_NL_COLLATE_SYMB_EXTRAMB instead of
++					wchar_t string.
++
++               charset[l+m+6]  = equivalence_classes (wchar_t)
++                              ...
++               charset[l+m+n+5]  = equivalence_classes (wchar_t)
++					ifdef _LIBC we use the index in
++					_NL_COLLATE_WEIGHT instead of
++					wchar_t string.
++
++	       charset[l+m+n+6] = range_start
++	       charset[l+m+n+7] = range_end
++	                       ...
++	       charset[l+m+n+2o+4] = range_start
++	       charset[l+m+n+2o+5] = range_end
++					ifdef _LIBC we use the value looked up
++					in _NL_COLLATE_COLLSEQ instead of
++					wchar_t character.
++
++	       charset[l+m+n+2o+6] = char
++	                          ...
++	       charset[l+m+n+2o+p+5] = char
++
++	     */
++
++	    /* We need at least 6 spaces: the opcode, the length of
++               char_classes, the length of collating_symbols, the length of
++               equivalence_classes, the length of char_ranges, the length of
++               chars.  */
++	    GET_BUFFER_SPACE (6);
++
++	    /* Save b as laststart. And We use laststart as the pointer
++	       to the first element of the charset here.
++	       In other words, laststart[i] indicates charset[i].  */
++            laststart = b;
++
++            /* We test `*p == '^' twice, instead of using an if
++               statement, so we only need one BUF_PUSH.  */
++            BUF_PUSH (*p == '^' ? charset_not : charset);
++            if (*p == '^')
++              p++;
++
++            /* Push the length of char_classes, the length of
++               collating_symbols, the length of equivalence_classes, the
++               length of char_ranges and the length of chars.  */
++            BUF_PUSH_3 (0, 0, 0);
++            BUF_PUSH_2 (0, 0);
++
++            /* Remember the first position in the bracket expression.  */
++            p1 = p;
++
++            /* charset_not matches newline according to a syntax bit.  */
++            if ((re_opcode_t) b[-6] == charset_not
++                && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
++	      {
++		BUF_PUSH('\n');
++		laststart[5]++; /* Update the length of characters  */
++	      }
++
++            /* Read in characters and ranges, setting map bits.  */
++            for (;;)
++              {
++                if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                PATFETCH (c);
++
++                /* \ might escape characters inside [...] and [^...].  */
++                if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++		    BUF_PUSH(c1);
++		    laststart[5]++; /* Update the length of chars  */
++		    range_start = c1;
++                    continue;
++                  }
++
++                /* Could be the end of the bracket expression.  If it's
++                   not (i.e., when the bracket expression is `[]' so
++                   far), the ']' character bit gets set way below.  */
++                if (c == ']' && p != p1 + 1)
++                  break;
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character class.  */
++                if (had_char_class && c == '-' && *p != ']')
++                  FREE_STACK_RETURN (REG_ERANGE);
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character: if this is a hyphen not at the
++                   beginning or the end of a list, then it's the range
++                   operator.  */
++                if (c == '-'
++                    && !(p - 2 >= pattern && p[-2] == '[')
++                    && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
++                    && *p != ']')
++                  {
++                    reg_errcode_t ret;
++		    /* Allocate the space for range_start and range_end.  */
++		    GET_BUFFER_SPACE (2);
++		    /* Update the pointer to indicate end of buffer.  */
++                    b += 2;
++                    ret = wcs_compile_range (range_start, &p, pend, translate,
++                                         syntax, b, laststart);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++                    range_start = 0xffffffff;
++                  }
++                else if (p[0] == '-' && p[1] != ']')
++                  { /* This handles ranges made up of characters only.  */
++                    reg_errcode_t ret;
++
++		    /* Move past the `-'.  */
++                    PATFETCH (c1);
++		    /* Allocate the space for range_start and range_end.  */
++		    GET_BUFFER_SPACE (2);
++		    /* Update the pointer to indicate end of buffer.  */
++                    b += 2;
++                    ret = wcs_compile_range (c, &p, pend, translate, syntax, b,
++                                         laststart);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                /* See if we're at the beginning of a possible character
++                   class.  */
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
++                  { /* Leave room for the null.  */
++                    char str[CHAR_CLASS_MAX_LENGTH + 1];
++
++                    PATFETCH (c);
++                    c1 = 0;
++
++                    /* If pattern is `[[:'.  */
++                    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                    for (;;)
++                      {
++                        PATFETCH (c);
++                        if ((c == ':' && *p == ']') || p == pend)
++                          break;
++			if (c1 < CHAR_CLASS_MAX_LENGTH)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++                    str[c1] = '\0';
++
++                    /* If isn't a word bracketed by `[:' and `:]':
++                       undo the ending character, the letters, and leave
++                       the leading `:' and `[' (but store them as character).  */
++                    if (c == ':' && *p == ']')
++                      {
++			wctype_t wt;
++			uintptr_t alignedp;
++
++			/* Query the character class as wctype_t.  */
++			wt = IS_CHAR_CLASS (str);
++			if (wt == 0)
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++			/* Allocate the space for character class.  */
++                        GET_BUFFER_SPACE(CHAR_CLASS_SIZE);
++			/* Update the pointer to indicate end of buffer.  */
++                        b += CHAR_CLASS_SIZE;
++			/* Move data which follow character classes
++			    not to violate the data.  */
++                        insert_space(CHAR_CLASS_SIZE,
++				     laststart + 6 + laststart[1],
++				     b - 1);
++			alignedp = ((uintptr_t)(laststart + 6 + laststart[1])
++				    + __alignof__(wctype_t) - 1)
++			  	    & ~(uintptr_t)(__alignof__(wctype_t) - 1);
++			/* Store the character class.  */
++                        *((wctype_t*)alignedp) = wt;
++                        /* Update length of char_classes */
++                        laststart[1] += CHAR_CLASS_SIZE;
++
++                        had_char_class = true;
++                      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        BUF_PUSH ('[');
++                        BUF_PUSH (':');
++                        laststart[5] += 2; /* Update the length of characters  */
++			range_start = ':';
++                        had_char_class = false;
++                      }
++                  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && (*p == '='
++							  || *p == '.'))
++		  {
++		    CHAR_T str[128];	/* Should be large enough.  */
++		    CHAR_T delim = *p; /* '=' or '.'  */
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[=' or '[[.'.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == delim && *p == ']') || p == pend)
++			  break;
++			if (c1 < sizeof (str) - 1)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == delim && *p == ']' && str[0] != '\0')
++		      {
++                        unsigned int i, offset;
++			/* If we have no collation data we use the default
++			   collation in which each character is in a class
++			   by itself.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++
++                        /* If not defined _LIBC, we push the name and
++			   `\0' for the sake of matching performance.  */
++			int datasize = c1 + 1;
++
++# ifdef _LIBC
++			int32_t idx = 0;
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    const int32_t *table;
++			    const int32_t *weights;
++			    const int32_t *extra;
++			    const int32_t *indirect;
++			    wint_t *cp;
++
++			    /* This #include defines a local function!  */
++#  include <locale/weightwc.h>
++
++			    if(delim == '=')
++			      {
++				/* We push the index for equivalence class.  */
++				cp = (wint_t*)str;
++
++				table = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_TABLEWC);
++				weights = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_WEIGHTWC);
++				extra = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_EXTRAWC);
++				indirect = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_INDIRECTWC);
++
++				idx = findidx ((const wint_t**)&cp, c1);
++				if (idx == 0 || cp < (wint_t*) str + c1)
++				  /* This is no valid character.  */
++				  FREE_STACK_RETURN (REG_ECOLLATE);
++
++				str[0] = (wchar_t)idx;
++			      }
++			    else /* delim == '.' */
++			      {
++				/* We push collation sequence value
++				   for collating symbol.  */
++				int32_t table_size;
++				const int32_t *symb_table;
++				const unsigned char *extra;
++				int32_t idx;
++				int32_t elem;
++				int32_t second;
++				int32_t hash;
++				char char_str[c1];
++
++				/* We have to convert the name to a single-byte
++				   string.  This is possible since the names
++				   consist of ASCII characters and the internal
++				   representation is UCS4.  */
++				for (i = 0; i < c1; ++i)
++				  char_str[i] = str[i];
++
++				table_size =
++				  _NL_CURRENT_WORD (LC_COLLATE,
++						    _NL_COLLATE_SYMB_HASH_SIZEMB);
++				symb_table = (const int32_t *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_SYMB_TABLEMB);
++				extra = (const unsigned char *)
++				  _NL_CURRENT (LC_COLLATE,
++					       _NL_COLLATE_SYMB_EXTRAMB);
++
++				/* Locate the character in the hashing table.  */
++				hash = elem_hash (char_str, c1);
++
++				idx = 0;
++				elem = hash % table_size;
++				second = hash % (table_size - 2);
++				while (symb_table[2 * elem] != 0)
++				  {
++				    /* First compare the hashing value.  */
++				    if (symb_table[2 * elem] == hash
++					&& c1 == extra[symb_table[2 * elem + 1]]
++					&& memcmp (char_str,
++						   &extra[symb_table[2 * elem + 1]
++							 + 1], c1) == 0)
++				      {
++					/* Yep, this is the entry.  */
++					idx = symb_table[2 * elem + 1];
++					idx += 1 + extra[idx];
++					break;
++				      }
++
++				    /* Next entry.  */
++				    elem += second;
++				  }
++
++				if (symb_table[2 * elem] != 0)
++				  {
++				    /* Compute the index of the byte sequence
++				       in the table.  */
++				    idx += 1 + extra[idx];
++				    /* Adjust for the alignment.  */
++				    idx = (idx + 3) & ~3;
++
++				    str[0] = (wchar_t) idx + 4;
++				  }
++				else if (symb_table[2 * elem] == 0 && c1 == 1)
++				  {
++				    /* No valid character.  Match it as a
++				       single byte character.  */
++				    had_char_class = false;
++				    BUF_PUSH(str[0]);
++				    /* Update the length of characters  */
++				    laststart[5]++;
++				    range_start = str[0];
++
++				    /* Throw away the ] at the end of the
++				       collating symbol.  */
++				    PATFETCH (c);
++				    /* exit from the switch block.  */
++				    continue;
++				  }
++				else
++				  FREE_STACK_RETURN (REG_ECOLLATE);
++			      }
++			    datasize = 1;
++			  }
++# endif
++                        /* Throw away the ] at the end of the equivalence
++                           class (or collating symbol).  */
++                        PATFETCH (c);
++
++			/* Allocate the space for the equivalence class
++			   (or collating symbol) (and '\0' if needed).  */
++                        GET_BUFFER_SPACE(datasize);
++			/* Update the pointer to indicate end of buffer.  */
++                        b += datasize;
++
++			if (delim == '=')
++			  { /* equivalence class  */
++			    /* Calculate the offset of char_ranges,
++			       which is next to equivalence_classes.  */
++			    offset = laststart[1] + laststart[2]
++			      + laststart[3] +6;
++			    /* Insert space.  */
++			    insert_space(datasize, laststart + offset, b - 1);
++
++			    /* Write the equivalence_class and \0.  */
++			    for (i = 0 ; i < datasize ; i++)
++			      laststart[offset + i] = str[i];
++
++			    /* Update the length of equivalence_classes.  */
++			    laststart[3] += datasize;
++			    had_char_class = true;
++			  }
++			else /* delim == '.' */
++			  { /* collating symbol  */
++			    /* Calculate the offset of the equivalence_classes,
++			       which is next to collating_symbols.  */
++			    offset = laststart[1] + laststart[2] + 6;
++			    /* Insert space and write the collationg_symbol
++			       and \0.  */
++			    insert_space(datasize, laststart + offset, b-1);
++			    for (i = 0 ; i < datasize ; i++)
++			      laststart[offset + i] = str[i];
++
++			    /* In re_match_2_internal if range_start < -1, we
++			       assume -range_start is the offset of the
++			       collating symbol which is specified as
++			       the character of the range start.  So we assign
++			       -(laststart[1] + laststart[2] + 6) to
++			       range_start.  */
++			    range_start = -(laststart[1] + laststart[2] + 6);
++			    /* Update the length of collating_symbol.  */
++			    laststart[2] += datasize;
++			    had_char_class = false;
++			  }
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        BUF_PUSH ('[');
++                        BUF_PUSH (delim);
++                        laststart[5] += 2; /* Update the length of characters  */
++			range_start = delim;
++                        had_char_class = false;
++                      }
++		  }
++                else
++                  {
++                    had_char_class = false;
++		    BUF_PUSH(c);
++		    laststart[5]++;  /* Update the length of characters  */
++		    range_start = c;
++                  }
++	      }
++
++#else /* BYTE */
++            /* Ensure that we have enough space to push a charset: the
++               opcode, the length count, and the bitset; 34 bytes in all.  */
++	    GET_BUFFER_SPACE (34);
++
++            laststart = b;
++
++            /* We test `*p == '^' twice, instead of using an if
++               statement, so we only need one BUF_PUSH.  */
++            BUF_PUSH (*p == '^' ? charset_not : charset);
++            if (*p == '^')
++              p++;
++
++            /* Remember the first position in the bracket expression.  */
++            p1 = p;
++
++            /* Push the number of bytes in the bitmap.  */
++            BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
++
++            /* Clear the whole map.  */
++            bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
++
++            /* charset_not matches newline according to a syntax bit.  */
++            if ((re_opcode_t) b[-2] == charset_not
++                && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
++              SET_LIST_BIT ('\n');
++
++            /* Read in characters and ranges, setting map bits.  */
++            for (;;)
++              {
++                if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                PATFETCH (c);
++
++                /* \ might escape characters inside [...] and [^...].  */
++                if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
++                  {
++                    if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++                    PATFETCH (c1);
++                    SET_LIST_BIT (c1);
++		    range_start = c1;
++                    continue;
++                  }
++
++                /* Could be the end of the bracket expression.  If it's
++                   not (i.e., when the bracket expression is `[]' so
++                   far), the ']' character bit gets set way below.  */
++                if (c == ']' && p != p1 + 1)
++                  break;
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character class.  */
++                if (had_char_class && c == '-' && *p != ']')
++                  FREE_STACK_RETURN (REG_ERANGE);
++
++                /* Look ahead to see if it's a range when the last thing
++                   was a character: if this is a hyphen not at the
++                   beginning or the end of a list, then it's the range
++                   operator.  */
++                if (c == '-'
++                    && !(p - 2 >= pattern && p[-2] == '[')
++                    && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
++                    && *p != ']')
++                  {
++                    reg_errcode_t ret
++                      = byte_compile_range (range_start, &p, pend, translate,
++					    syntax, b);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                else if (p[0] == '-' && p[1] != ']')
++                  { /* This handles ranges made up of characters only.  */
++                    reg_errcode_t ret;
++
++		    /* Move past the `-'.  */
++                    PATFETCH (c1);
++
++                    ret = byte_compile_range (c, &p, pend, translate, syntax, b);
++                    if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
++		    range_start = 0xffffffff;
++                  }
++
++                /* See if we're at the beginning of a possible character
++                   class.  */
++
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
++                  { /* Leave room for the null.  */
++                    char str[CHAR_CLASS_MAX_LENGTH + 1];
++
++                    PATFETCH (c);
++                    c1 = 0;
++
++                    /* If pattern is `[[:'.  */
++                    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                    for (;;)
++                      {
++                        PATFETCH (c);
++                        if ((c == ':' && *p == ']') || p == pend)
++                          break;
++			if (((int) c1) < CHAR_CLASS_MAX_LENGTH)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++                    str[c1] = '\0';
++
++                    /* If isn't a word bracketed by `[:' and `:]':
++                       undo the ending character, the letters, and leave
++                       the leading `:' and `[' (but set bits for them).  */
++                    if (c == ':' && *p == ']')
++                      {
++# if WIDE_CHAR_SUPPORT
++                        boolean is_lower = STREQ (str, "lower");
++                        boolean is_upper = STREQ (str, "upper");
++			wctype_t wt;
++                        int ch;
++
++			wt = IS_CHAR_CLASS (str);
++			if (wt == 0)
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                        for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
++			  {
++#  ifdef _LIBC
++			    if (__iswctype (__btowc (ch), wt))
++			      SET_LIST_BIT (ch);
++#  else
++			    if (iswctype (btowc (ch), wt))
++			      SET_LIST_BIT (ch);
++#  endif
++
++			    if (translate && (is_upper || is_lower)
++				&& (ISUPPER (ch) || ISLOWER (ch)))
++			      SET_LIST_BIT (ch);
++			  }
++
++                        had_char_class = true;
++# else
++                        int ch;
++                        boolean is_alnum = STREQ (str, "alnum");
++                        boolean is_alpha = STREQ (str, "alpha");
++                        boolean is_blank = STREQ (str, "blank");
++                        boolean is_cntrl = STREQ (str, "cntrl");
++                        boolean is_digit = STREQ (str, "digit");
++                        boolean is_graph = STREQ (str, "graph");
++                        boolean is_lower = STREQ (str, "lower");
++                        boolean is_print = STREQ (str, "print");
++                        boolean is_punct = STREQ (str, "punct");
++                        boolean is_space = STREQ (str, "space");
++                        boolean is_upper = STREQ (str, "upper");
++                        boolean is_xdigit = STREQ (str, "xdigit");
++
++                        if (!IS_CHAR_CLASS (str))
++			  FREE_STACK_RETURN (REG_ECTYPE);
++
++                        /* Throw away the ] at the end of the character
++                           class.  */
++                        PATFETCH (c);
++
++                        if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++                        for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
++                          {
++			    /* This was split into 3 if's to
++			       avoid an arbitrary limit in some compiler.  */
++                            if (   (is_alnum  && ISALNUM (ch))
++                                || (is_alpha  && ISALPHA (ch))
++                                || (is_blank  && ISBLANK (ch))
++                                || (is_cntrl  && ISCNTRL (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   (is_digit  && ISDIGIT (ch))
++                                || (is_graph  && ISGRAPH (ch))
++                                || (is_lower  && ISLOWER (ch))
++                                || (is_print  && ISPRINT (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   (is_punct  && ISPUNCT (ch))
++                                || (is_space  && ISSPACE (ch))
++                                || (is_upper  && ISUPPER (ch))
++                                || (is_xdigit && ISXDIGIT (ch)))
++			      SET_LIST_BIT (ch);
++			    if (   translate && (is_upper || is_lower)
++				&& (ISUPPER (ch) || ISLOWER (ch)))
++			      SET_LIST_BIT (ch);
++                          }
++                        had_char_class = true;
++# endif	/* libc || wctype.h */
++                      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT (':');
++			range_start = ':';
++                        had_char_class = false;
++                      }
++                  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '=')
++		  {
++		    unsigned char str[MB_LEN_MAX + 1];
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[='.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == '=' && *p == ']') || p == pend)
++			  break;
++			if (c1 < MB_LEN_MAX)
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == '=' && *p == ']' && str[0] != '\0')
++		      {
++			/* If we have no collation data we use the default
++			   collation in which each character is in a class
++			   by itself.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++# ifdef _LIBC
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Set the bit for the character.  */
++			    SET_LIST_BIT (str[0]);
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    /* Try to match the byte sequence in `str' against
++			       those known to the collate implementation.
++			       First find out whether the bytes in `str' are
++			       actually from exactly one character.  */
++			    const int32_t *table;
++			    const unsigned char *weights;
++			    const unsigned char *extra;
++			    const int32_t *indirect;
++			    int32_t idx;
++			    const unsigned char *cp = str;
++			    int ch;
++
++			    /* This #include defines a local function!  */
++#  include <locale/weight.h>
++
++			    table = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
++			    weights = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
++			    extra = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
++			    indirect = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
++
++			    idx = findidx (&cp, c1);
++			    if (idx == 0 || cp < str + c1)
++			      /* This is no valid character.  */
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Now we have to go throught the whole table
++			       and find all characters which have the same
++			       first level weight.
++
++			       XXX Note that this is not entirely correct.
++			       we would have to match multibyte sequences
++			       but this is not possible with the current
++			       implementation.  */
++			    for (ch = 1; ch < 256; ++ch)
++			      /* XXX This test would have to be changed if we
++				 would allow matching multibyte sequences.  */
++			      if (table[ch] > 0)
++				{
++				  int32_t idx2 = table[ch];
++				  size_t len = weights[idx2];
++
++				  /* Test whether the lenghts match.  */
++				  if (weights[idx] == len)
++				    {
++				      /* They do.  New compare the bytes of
++					 the weight.  */
++				      size_t cnt = 0;
++
++				      while (cnt < len
++					     && (weights[idx + 1 + cnt]
++						 == weights[idx2 + 1 + cnt]))
++					++cnt;
++
++				      if (cnt == len)
++					/* They match.  Mark the character as
++					   acceptable.  */
++					SET_LIST_BIT (ch);
++				    }
++				}
++			  }
++# endif
++			had_char_class = true;
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT ('=');
++			range_start = '=';
++                        had_char_class = false;
++                      }
++		  }
++                else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == '.')
++		  {
++		    unsigned char str[128];	/* Should be large enough.  */
++# ifdef _LIBC
++		    uint32_t nrules =
++		      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif
++
++		    PATFETCH (c);
++		    c1 = 0;
++
++		    /* If pattern is `[[.'.  */
++		    if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
++
++		    for (;;)
++		      {
++			PATFETCH (c);
++			if ((c == '.' && *p == ']') || p == pend)
++			  break;
++			if (c1 < sizeof (str))
++			  str[c1++] = c;
++			else
++			  /* This is in any case an invalid class name.  */
++			  str[0] = '\0';
++                      }
++		    str[c1] = '\0';
++
++		    if (c == '.' && *p == ']' && str[0] != '\0')
++		      {
++			/* If we have no collation data we use the default
++			   collation in which each character is the name
++			   for its own class which contains only the one
++			   character.  It also means that ASCII is the
++			   character set and therefore we cannot have character
++			   with more than one byte in the multibyte
++			   representation.  */
++# ifdef _LIBC
++			if (nrules == 0)
++# endif
++			  {
++			    if (c1 != 1)
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Set the bit for the character.  */
++			    SET_LIST_BIT (str[0]);
++			    range_start = ((const unsigned char *) str)[0];
++			  }
++# ifdef _LIBC
++			else
++			  {
++			    /* Try to match the byte sequence in `str' against
++			       those known to the collate implementation.
++			       First find out whether the bytes in `str' are
++			       actually from exactly one character.  */
++			    int32_t table_size;
++			    const int32_t *symb_table;
++			    const unsigned char *extra;
++			    int32_t idx;
++			    int32_t elem;
++			    int32_t second;
++			    int32_t hash;
++
++			    table_size =
++			      _NL_CURRENT_WORD (LC_COLLATE,
++						_NL_COLLATE_SYMB_HASH_SIZEMB);
++			    symb_table = (const int32_t *)
++			      _NL_CURRENT (LC_COLLATE,
++					   _NL_COLLATE_SYMB_TABLEMB);
++			    extra = (const unsigned char *)
++			      _NL_CURRENT (LC_COLLATE,
++					   _NL_COLLATE_SYMB_EXTRAMB);
++
++			    /* Locate the character in the hashing table.  */
++			    hash = elem_hash ((const char *) str, c1);
++
++			    idx = 0;
++			    elem = hash % table_size;
++			    second = hash % (table_size - 2);
++			    while (symb_table[2 * elem] != 0)
++			      {
++				/* First compare the hashing value.  */
++				if (symb_table[2 * elem] == hash
++				    && c1 == extra[symb_table[2 * elem + 1]]
++				    && memcmp (str,
++					       &extra[symb_table[2 * elem + 1]
++						     + 1],
++					       c1) == 0)
++				  {
++				    /* Yep, this is the entry.  */
++				    idx = symb_table[2 * elem + 1];
++				    idx += 1 + extra[idx];
++				    break;
++				  }
++
++				/* Next entry.  */
++				elem += second;
++			      }
++
++			    if (symb_table[2 * elem] == 0)
++			      /* This is no valid character.  */
++			      FREE_STACK_RETURN (REG_ECOLLATE);
++
++			    /* Throw away the ] at the end of the equivalence
++			       class.  */
++			    PATFETCH (c);
++
++			    /* Now add the multibyte character(s) we found
++			       to the accept list.
++
++			       XXX Note that this is not entirely correct.
++			       we would have to match multibyte sequences
++			       but this is not possible with the current
++			       implementation.  Also, we have to match
++			       collating symbols, which expand to more than
++			       one file, as a whole and not allow the
++			       individual bytes.  */
++			    c1 = extra[idx++];
++			    if (c1 == 1)
++			      range_start = extra[idx];
++			    while (c1-- > 0)
++			      {
++				SET_LIST_BIT (extra[idx]);
++				++idx;
++			      }
++			  }
++# endif
++			had_char_class = false;
++		      }
++                    else
++                      {
++                        c1++;
++                        while (c1--)
++                          PATUNFETCH;
++                        SET_LIST_BIT ('[');
++                        SET_LIST_BIT ('.');
++			range_start = '.';
++                        had_char_class = false;
++                      }
++		  }
++                else
++                  {
++                    had_char_class = false;
++                    SET_LIST_BIT (c);
++		    range_start = c;
++                  }
++              }
++
++            /* Discard any (non)matching list bytes that are all 0 at the
++               end of the map.  Decrease the map-length byte too.  */
++            while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
++              b[-1]--;
++            b += b[-1];
++#endif /* WCHAR */
++          }
++          break;
++
++
++	case '(':
++          if (syntax & RE_NO_BK_PARENS)
++            goto handle_open;
++          else
++            goto normal_char;
++
++
++        case ')':
++          if (syntax & RE_NO_BK_PARENS)
++            goto handle_close;
++          else
++            goto normal_char;
++
++
++        case '\n':
++          if (syntax & RE_NEWLINE_ALT)
++            goto handle_alt;
++          else
++            goto normal_char;
++
++
++	case '|':
++          if (syntax & RE_NO_BK_VBAR)
++            goto handle_alt;
++          else
++            goto normal_char;
++
++
++        case '{':
++           if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
++             goto handle_interval;
++           else
++             goto normal_char;
++
++
++        case '\\':
++          if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
++
++          /* Do not translate the character after the \, so that we can
++             distinguish, e.g., \B from \b, even if we normally would
++             translate, e.g., B to b.  */
++          PATFETCH_RAW (c);
++
++          switch (c)
++            {
++            case '(':
++              if (syntax & RE_NO_BK_PARENS)
++                goto normal_backslash;
++
++            handle_open:
++              bufp->re_nsub++;
++              regnum++;
++
++              if (COMPILE_STACK_FULL)
++                {
++                  RETALLOC (compile_stack.stack, compile_stack.size << 1,
++                            compile_stack_elt_t);
++                  if (compile_stack.stack == NULL) return REG_ESPACE;
++
++                  compile_stack.size <<= 1;
++                }
++
++              /* These are the values to restore when we hit end of this
++                 group.  They are all relative offsets, so that if the
++                 whole pattern moves because of realloc, they will still
++                 be valid.  */
++              COMPILE_STACK_TOP.begalt_offset = begalt - COMPILED_BUFFER_VAR;
++              COMPILE_STACK_TOP.fixup_alt_jump
++                = fixup_alt_jump ? fixup_alt_jump - COMPILED_BUFFER_VAR + 1 : 0;
++              COMPILE_STACK_TOP.laststart_offset = b - COMPILED_BUFFER_VAR;
++              COMPILE_STACK_TOP.regnum = regnum;
++
++              /* We will eventually replace the 0 with the number of
++                 groups inner to this one.  But do not push a
++                 start_memory for groups beyond the last one we can
++                 represent in the compiled pattern.  */
++              if (regnum <= MAX_REGNUM)
++                {
++                  COMPILE_STACK_TOP.inner_group_offset = b
++		    - COMPILED_BUFFER_VAR + 2;
++                  BUF_PUSH_3 (start_memory, regnum, 0);
++                }
++
++              compile_stack.avail++;
++
++              fixup_alt_jump = 0;
++              laststart = 0;
++              begalt = b;
++	      /* If we've reached MAX_REGNUM groups, then this open
++		 won't actually generate any code, so we'll have to
++		 clear pending_exact explicitly.  */
++	      pending_exact = 0;
++              break;
++
++
++            case ')':
++              if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
++
++              if (COMPILE_STACK_EMPTY)
++		{
++		  if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
++		    goto normal_backslash;
++		  else
++		    FREE_STACK_RETURN (REG_ERPAREN);
++		}
++
++            handle_close:
++              if (fixup_alt_jump)
++                { /* Push a dummy failure point at the end of the
++                     alternative for a possible future
++                     `pop_failure_jump' to pop.  See comments at
++                     `push_dummy_failure' in `re_match_2'.  */
++                  BUF_PUSH (push_dummy_failure);
++
++                  /* We allocated space for this jump when we assigned
++                     to `fixup_alt_jump', in the `handle_alt' case below.  */
++                  STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
++                }
++
++              /* See similar code for backslashed left paren above.  */
++              if (COMPILE_STACK_EMPTY)
++		{
++		  if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
++		    goto normal_char;
++		  else
++		    FREE_STACK_RETURN (REG_ERPAREN);
++		}
++
++              /* Since we just checked for an empty stack above, this
++                 ``can't happen''.  */
++              assert (compile_stack.avail != 0);
++              {
++                /* We don't just want to restore into `regnum', because
++                   later groups should continue to be numbered higher,
++                   as in `(ab)c(de)' -- the second group is #2.  */
++                regnum_t this_group_regnum;
++
++                compile_stack.avail--;
++                begalt = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.begalt_offset;
++                fixup_alt_jump
++                  = COMPILE_STACK_TOP.fixup_alt_jump
++                    ? COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.fixup_alt_jump - 1
++                    : 0;
++                laststart = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.laststart_offset;
++                this_group_regnum = COMPILE_STACK_TOP.regnum;
++		/* If we've reached MAX_REGNUM groups, then this open
++		   won't actually generate any code, so we'll have to
++		   clear pending_exact explicitly.  */
++		pending_exact = 0;
++
++                /* We're at the end of the group, so now we know how many
++                   groups were inside this one.  */
++                if (this_group_regnum <= MAX_REGNUM)
++                  {
++		    UCHAR_T *inner_group_loc
++                      = COMPILED_BUFFER_VAR + COMPILE_STACK_TOP.inner_group_offset;
++
++                    *inner_group_loc = regnum - this_group_regnum;
++                    BUF_PUSH_3 (stop_memory, this_group_regnum,
++                                regnum - this_group_regnum);
++                  }
++              }
++              break;
++
++
++            case '|':					/* `\|'.  */
++              if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
++                goto normal_backslash;
++            handle_alt:
++              if (syntax & RE_LIMITED_OPS)
++                goto normal_char;
++
++              /* Insert before the previous alternative a jump which
++                 jumps to this alternative if the former fails.  */
++              GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++              INSERT_JUMP (on_failure_jump, begalt,
++			   b + 2 + 2 * OFFSET_ADDRESS_SIZE);
++              pending_exact = 0;
++              b += 1 + OFFSET_ADDRESS_SIZE;
++
++              /* The alternative before this one has a jump after it
++                 which gets executed if it gets matched.  Adjust that
++                 jump so it will jump to this alternative's analogous
++                 jump (put in below, which in turn will jump to the next
++                 (if any) alternative's such jump, etc.).  The last such
++                 jump jumps to the correct final destination.  A picture:
++                          _____ _____
++                          |   | |   |
++                          |   v |   v
++                         a | b   | c
++
++                 If we are at `b', then fixup_alt_jump right now points to a
++                 three-byte space after `a'.  We'll put in the jump, set
++                 fixup_alt_jump to right after `b', and leave behind three
++                 bytes which we'll fill in when we get to after `c'.  */
++
++              if (fixup_alt_jump)
++                STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
++
++              /* Mark and leave space for a jump after this alternative,
++                 to be filled in later either by next alternative or
++                 when know we're at the end of a series of alternatives.  */
++              fixup_alt_jump = b;
++              GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++              b += 1 + OFFSET_ADDRESS_SIZE;
++
++              laststart = 0;
++              begalt = b;
++              break;
++
++
++            case '{':
++              /* If \{ is a literal.  */
++              if (!(syntax & RE_INTERVALS)
++                     /* If we're at `\{' and it's not the open-interval
++                        operator.  */
++		  || (syntax & RE_NO_BK_BRACES))
++                goto normal_backslash;
++
++            handle_interval:
++              {
++                /* If got here, then the syntax allows intervals.  */
++
++                /* At least (most) this many matches must be made.  */
++                int lower_bound = -1, upper_bound = -1;
++
++		/* Place in the uncompiled pattern (i.e., just after
++		   the '{') to go back to if the interval is invalid.  */
++		const CHAR_T *beg_interval = p;
++
++                if (p == pend)
++		  goto invalid_interval;
++
++                GET_UNSIGNED_NUMBER (lower_bound);
++
++                if (c == ',')
++                  {
++                    GET_UNSIGNED_NUMBER (upper_bound);
++		    if (upper_bound < 0)
++		      upper_bound = RE_DUP_MAX;
++                  }
++                else
++                  /* Interval such as `{1}' => match exactly once. */
++                  upper_bound = lower_bound;
++
++                if (! (0 <= lower_bound && lower_bound <= upper_bound))
++		  goto invalid_interval;
++
++                if (!(syntax & RE_NO_BK_BRACES))
++                  {
++		    if (c != '\\' || p == pend)
++		      goto invalid_interval;
++                    PATFETCH (c);
++                  }
++
++                if (c != '}')
++		  goto invalid_interval;
++
++                /* If it's invalid to have no preceding re.  */
++                if (!laststart)
++                  {
++		    if (syntax & RE_CONTEXT_INVALID_OPS
++			&& !(syntax & RE_INVALID_INTERVAL_ORD))
++                      FREE_STACK_RETURN (REG_BADRPT);
++                    else if (syntax & RE_CONTEXT_INDEP_OPS)
++                      laststart = b;
++                    else
++                      goto unfetch_interval;
++                  }
++
++                /* We just parsed a valid interval.  */
++
++                if (RE_DUP_MAX < upper_bound)
++		  FREE_STACK_RETURN (REG_BADBR);
++
++                /* If the upper bound is zero, don't want to succeed at
++                   all; jump from `laststart' to `b + 3', which will be
++		   the end of the buffer after we insert the jump.  */
++		/* ifdef WCHAR, 'b + 1 + OFFSET_ADDRESS_SIZE'
++		   instead of 'b + 3'.  */
++                 if (upper_bound == 0)
++                   {
++                     GET_BUFFER_SPACE (1 + OFFSET_ADDRESS_SIZE);
++                     INSERT_JUMP (jump, laststart, b + 1
++				  + OFFSET_ADDRESS_SIZE);
++                     b += 1 + OFFSET_ADDRESS_SIZE;
++                   }
++
++                 /* Otherwise, we have a nontrivial interval.  When
++                    we're all done, the pattern will look like:
++                      set_number_at <jump count> <upper bound>
++                      set_number_at <succeed_n count> <lower bound>
++                      succeed_n <after jump addr> <succeed_n count>
++                      <body of loop>
++                      jump_n <succeed_n addr> <jump count>
++                    (The upper bound and `jump_n' are omitted if
++                    `upper_bound' is 1, though.)  */
++                 else
++                   { /* If the upper bound is > 1, we need to insert
++                        more at the end of the loop.  */
++                     unsigned nbytes = 2 + 4 * OFFSET_ADDRESS_SIZE +
++		       (upper_bound > 1) * (2 + 4 * OFFSET_ADDRESS_SIZE);
++
++                     GET_BUFFER_SPACE (nbytes);
++
++                     /* Initialize lower bound of the `succeed_n', even
++                        though it will be set during matching by its
++                        attendant `set_number_at' (inserted next),
++                        because `re_compile_fastmap' needs to know.
++                        Jump to the `jump_n' we might insert below.  */
++                     INSERT_JUMP2 (succeed_n, laststart,
++                                   b + 1 + 2 * OFFSET_ADDRESS_SIZE
++				   + (upper_bound > 1) * (1 + 2 * OFFSET_ADDRESS_SIZE)
++				   , lower_bound);
++                     b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                     /* Code to initialize the lower bound.  Insert
++                        before the `succeed_n'.  The `5' is the last two
++                        bytes of this `set_number_at', plus 3 bytes of
++                        the following `succeed_n'.  */
++		     /* ifdef WCHAR, The '1+2*OFFSET_ADDRESS_SIZE'
++			is the 'set_number_at', plus '1+OFFSET_ADDRESS_SIZE'
++			of the following `succeed_n'.  */
++                     PREFIX(insert_op2) (set_number_at, laststart, 1
++				 + 2 * OFFSET_ADDRESS_SIZE, lower_bound, b);
++                     b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                     if (upper_bound > 1)
++                       { /* More than one repetition is allowed, so
++                            append a backward jump to the `succeed_n'
++                            that starts this interval.
++
++                            When we've reached this during matching,
++                            we'll have matched the interval once, so
++                            jump back only `upper_bound - 1' times.  */
++                         STORE_JUMP2 (jump_n, b, laststart
++				      + 2 * OFFSET_ADDRESS_SIZE + 1,
++                                      upper_bound - 1);
++                         b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++                         /* The location we want to set is the second
++                            parameter of the `jump_n'; that is `b-2' as
++                            an absolute address.  `laststart' will be
++                            the `set_number_at' we're about to insert;
++                            `laststart+3' the number to set, the source
++                            for the relative address.  But we are
++                            inserting into the middle of the pattern --
++                            so everything is getting moved up by 5.
++                            Conclusion: (b - 2) - (laststart + 3) + 5,
++                            i.e., b - laststart.
++
++                            We insert this at the beginning of the loop
++                            so that if we fail during matching, we'll
++                            reinitialize the bounds.  */
++                         PREFIX(insert_op2) (set_number_at, laststart,
++					     b - laststart,
++					     upper_bound - 1, b);
++                         b += 1 + 2 * OFFSET_ADDRESS_SIZE;
++                       }
++                   }
++                pending_exact = 0;
++		break;
++
++	      invalid_interval:
++		if (!(syntax & RE_INVALID_INTERVAL_ORD))
++		  FREE_STACK_RETURN (p == pend ? REG_EBRACE : REG_BADBR);
++	      unfetch_interval:
++		/* Match the characters as literals.  */
++		p = beg_interval;
++		c = '{';
++		if (syntax & RE_NO_BK_BRACES)
++		  goto normal_char;
++		else
++		  goto normal_backslash;
++	      }
++
++#ifdef emacs
++            /* There is no way to specify the before_dot and after_dot
++               operators.  rms says this is ok.  --karl  */
++            case '=':
++              BUF_PUSH (at_dot);
++              break;
++
++            case 's':
++              laststart = b;
++              PATFETCH (c);
++              BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
++              break;
++
++            case 'S':
++              laststart = b;
++              PATFETCH (c);
++              BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
++              break;
++#endif /* emacs */
++
++
++            case 'w':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              laststart = b;
++              BUF_PUSH (wordchar);
++              break;
++
++
++            case 'W':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              laststart = b;
++              BUF_PUSH (notwordchar);
++              break;
++
++
++            case '<':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordbeg);
++              break;
++
++            case '>':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordend);
++              break;
++
++            case 'b':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (wordbound);
++              break;
++
++            case 'B':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (notwordbound);
++              break;
++
++            case '`':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (begbuf);
++              break;
++
++            case '\'':
++	      if (syntax & RE_NO_GNU_OPS)
++		goto normal_char;
++              BUF_PUSH (endbuf);
++              break;
++
++            case '1': case '2': case '3': case '4': case '5':
++            case '6': case '7': case '8': case '9':
++              if (syntax & RE_NO_BK_REFS)
++                goto normal_char;
++
++              c1 = c - '0';
++
++              if (c1 > regnum)
++                FREE_STACK_RETURN (REG_ESUBREG);
++
++              /* Can't back reference to a subexpression if inside of it.  */
++              if (group_in_compile_stack (compile_stack, (regnum_t) c1))
++                goto normal_char;
++
++              laststart = b;
++              BUF_PUSH_2 (duplicate, c1);
++              break;
++
++
++            case '+':
++            case '?':
++              if (syntax & RE_BK_PLUS_QM)
++                goto handle_plus;
++              else
++                goto normal_backslash;
++
++            default:
++            normal_backslash:
++              /* You might think it would be useful for \ to mean
++                 not to translate; but if we don't translate it
++                 it will never match anything.  */
++              c = TRANSLATE (c);
++              goto normal_char;
++            }
++          break;
++
++
++	default:
++        /* Expects the character in `c'.  */
++	normal_char:
++	      /* If no exactn currently being built.  */
++          if (!pending_exact
++#ifdef WCHAR
++	      /* If last exactn handle binary(or character) and
++		 new exactn handle character(or binary).  */
++	      || is_exactn_bin != is_binary[p - 1 - pattern]
++#endif /* WCHAR */
++
++              /* If last exactn not at current position.  */
++              || pending_exact + *pending_exact + 1 != b
++
++              /* We have only one byte following the exactn for the count.  */
++	      || *pending_exact == (1 << BYTEWIDTH) - 1
++
++              /* If followed by a repetition operator.  */
++              || *p == '*' || *p == '^'
++	      || ((syntax & RE_BK_PLUS_QM)
++		  ? *p == '\\' && (p[1] == '+' || p[1] == '?')
++		  : (*p == '+' || *p == '?'))
++	      || ((syntax & RE_INTERVALS)
++                  && ((syntax & RE_NO_BK_BRACES)
++		      ? *p == '{'
++                      : (p[0] == '\\' && p[1] == '{'))))
++	    {
++	      /* Start building a new exactn.  */
++
++              laststart = b;
++
++#ifdef WCHAR
++	      /* Is this exactn binary data or character? */
++	      is_exactn_bin = is_binary[p - 1 - pattern];
++	      if (is_exactn_bin)
++		  BUF_PUSH_2 (exactn_bin, 0);
++	      else
++		  BUF_PUSH_2 (exactn, 0);
++#else
++	      BUF_PUSH_2 (exactn, 0);
++#endif /* WCHAR */
++	      pending_exact = b - 1;
++            }
++
++	  BUF_PUSH (c);
++          (*pending_exact)++;
++	  break;
++        } /* switch (c) */
++    } /* while p != pend */
++
++
++  /* Through the pattern now.  */
++
++  if (fixup_alt_jump)
++    STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
++
++  if (!COMPILE_STACK_EMPTY)
++    FREE_STACK_RETURN (REG_EPAREN);
++
++  /* If we don't want backtracking, force success
++     the first time we reach the end of the compiled pattern.  */
++  if (syntax & RE_NO_POSIX_BACKTRACKING)
++    BUF_PUSH (succeed);
++
++#ifdef WCHAR
++  free (pattern);
++  free (mbs_offset);
++  free (is_binary);
++#endif
++  free (compile_stack.stack);
++
++  /* We have succeeded; set the length of the buffer.  */
++#ifdef WCHAR
++  bufp->used = (uintptr_t) b - (uintptr_t) COMPILED_BUFFER_VAR;
++#else
++  bufp->used = b - bufp->buffer;
++#endif
++
++#ifdef DEBUG
++  if (debug)
++    {
++      DEBUG_PRINT1 ("\nCompiled pattern: \n");
++      PREFIX(print_compiled_pattern) (bufp);
++    }
++#endif /* DEBUG */
++
++#ifndef MATCH_MAY_ALLOCATE
++  /* Initialize the failure stack to the largest possible stack.  This
++     isn't necessary unless we're trying to avoid calling alloca in
++     the search and match routines.  */
++  {
++    int num_regs = bufp->re_nsub + 1;
++
++    /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
++       is strictly greater than re_max_failures, the largest possible stack
++       is 2 * re_max_failures failure points.  */
++    if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
++      {
++	fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
++
++# ifdef emacs
++	if (! fail_stack.stack)
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) xmalloc (fail_stack.size
++				    * sizeof (PREFIX(fail_stack_elt_t)));
++	else
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) xrealloc (fail_stack.stack,
++				     (fail_stack.size
++				      * sizeof (PREFIX(fail_stack_elt_t))));
++# else /* not emacs */
++	if (! fail_stack.stack)
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) malloc (fail_stack.size
++				   * sizeof (PREFIX(fail_stack_elt_t)));
++	else
++	  fail_stack.stack
++	    = (PREFIX(fail_stack_elt_t) *) realloc (fail_stack.stack,
++					    (fail_stack.size
++				     * sizeof (PREFIX(fail_stack_elt_t))));
++# endif /* not emacs */
++      }
++
++   PREFIX(regex_grow_registers) (num_regs);
++  }
++#endif /* not MATCH_MAY_ALLOCATE */
++
++  return REG_NOERROR;
++} /* regex_compile */
++
++/* Subroutines for `regex_compile'.  */
++
++/* Store OP at LOC followed by two-byte integer parameter ARG.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(store_op1) (re_opcode_t op, UCHAR_T *loc, int arg)
++{
++  *loc = (UCHAR_T) op;
++  STORE_NUMBER (loc + 1, arg);
++}
++
++
++/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(store_op2) (re_opcode_t op, UCHAR_T *loc, int arg1, int arg2)
++{
++  *loc = (UCHAR_T) op;
++  STORE_NUMBER (loc + 1, arg1);
++  STORE_NUMBER (loc + 1 + OFFSET_ADDRESS_SIZE, arg2);
++}
++
++
++/* Copy the bytes from LOC to END to open up three bytes of space at LOC
++   for OP followed by two-byte integer parameter ARG.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(insert_op1) (re_opcode_t op, UCHAR_T *loc, int arg, UCHAR_T *end)
++{
++  register UCHAR_T *pfrom = end;
++  register UCHAR_T *pto = end + 1 + OFFSET_ADDRESS_SIZE;
++
++  while (pfrom != loc)
++    *--pto = *--pfrom;
++
++  PREFIX(store_op1) (op, loc, arg);
++}
++
++
++/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2.  */
++/* ifdef WCHAR, integer parameter is 1 wchar_t.  */
++
++static void
++PREFIX(insert_op2) (re_opcode_t op, UCHAR_T *loc, int arg1,
++                    int arg2, UCHAR_T *end)
++{
++  register UCHAR_T *pfrom = end;
++  register UCHAR_T *pto = end + 1 + 2 * OFFSET_ADDRESS_SIZE;
++
++  while (pfrom != loc)
++    *--pto = *--pfrom;
++
++  PREFIX(store_op2) (op, loc, arg1, arg2);
++}
++
++
++/* P points to just after a ^ in PATTERN.  Return true if that ^ comes
++   after an alternative or a begin-subexpression.  We assume there is at
++   least one character before the ^.  */
++
++static boolean
++PREFIX(at_begline_loc_p) (const CHAR_T *pattern, const CHAR_T *p,
++                          reg_syntax_t syntax)
++{
++  const CHAR_T *prev = p - 2;
++  boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
++
++  return
++       /* After a subexpression?  */
++       (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
++       /* After an alternative?  */
++    || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
++}
++
++
++/* The dual of at_begline_loc_p.  This one is for $.  We assume there is
++   at least one character after the $, i.e., `P < PEND'.  */
++
++static boolean
++PREFIX(at_endline_loc_p) (const CHAR_T *p, const CHAR_T *pend,
++                          reg_syntax_t syntax)
++{
++  const CHAR_T *next = p;
++  boolean next_backslash = *next == '\\';
++  const CHAR_T *next_next = p + 1 < pend ? p + 1 : 0;
++
++  return
++       /* Before a subexpression?  */
++       (syntax & RE_NO_BK_PARENS ? *next == ')'
++        : next_backslash && next_next && *next_next == ')')
++       /* Before an alternative?  */
++    || (syntax & RE_NO_BK_VBAR ? *next == '|'
++        : next_backslash && next_next && *next_next == '|');
++}
++
++#else /* not INSIDE_RECURSION */
++
++/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
++   false if it's not.  */
++
++static boolean
++group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
++{
++  int this_element;
++
++  for (this_element = compile_stack.avail - 1;
++       this_element >= 0;
++       this_element--)
++    if (compile_stack.stack[this_element].regnum == regnum)
++      return true;
++
++  return false;
++}
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef WCHAR
++/* This insert space, which size is "num", into the pattern at "loc".
++   "end" must point the end of the allocated buffer.  */
++static void
++insert_space (int num, CHAR_T *loc, CHAR_T *end)
++{
++  register CHAR_T *pto = end;
++  register CHAR_T *pfrom = end - num;
++
++  while (pfrom >= loc)
++    *pto-- = *pfrom--;
++}
++#endif /* WCHAR */
++
++#ifdef WCHAR
++static reg_errcode_t
++wcs_compile_range (CHAR_T range_start_char, const CHAR_T **p_ptr,
++                   const CHAR_T *pend, RE_TRANSLATE_TYPE translate,
++                   reg_syntax_t syntax, CHAR_T *b, CHAR_T *char_set)
++{
++  const CHAR_T *p = *p_ptr;
++  CHAR_T range_start, range_end;
++  reg_errcode_t ret;
++# ifdef _LIBC
++  uint32_t nrules;
++  uint32_t start_val, end_val;
++# endif
++  if (p == pend)
++    return REG_ERANGE;
++
++# ifdef _LIBC
++  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++  if (nrules != 0)
++    {
++      const char *collseq = (const char *) _NL_CURRENT(LC_COLLATE,
++						       _NL_COLLATE_COLLSEQWC);
++      const unsigned char *extra = (const unsigned char *)
++	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
++
++      if (range_start_char < -1)
++	{
++	  /* range_start is a collating symbol.  */
++	  int32_t *wextra;
++	  /* Retreive the index and get collation sequence value.  */
++	  wextra = (int32_t*)(extra + char_set[-range_start_char]);
++	  start_val = wextra[1 + *wextra];
++	}
++      else
++	start_val = collseq_table_lookup(collseq, TRANSLATE(range_start_char));
++
++      end_val = collseq_table_lookup (collseq, TRANSLATE (p[0]));
++
++      /* Report an error if the range is empty and the syntax prohibits
++	 this.  */
++      ret = ((syntax & RE_NO_EMPTY_RANGES)
++	     && (start_val > end_val))? REG_ERANGE : REG_NOERROR;
++
++      /* Insert space to the end of the char_ranges.  */
++      insert_space(2, b - char_set[5] - 2, b - 1);
++      *(b - char_set[5] - 2) = (wchar_t)start_val;
++      *(b - char_set[5] - 1) = (wchar_t)end_val;
++      char_set[4]++; /* ranges_index */
++    }
++  else
++# endif
++    {
++      range_start = (range_start_char >= 0)? TRANSLATE (range_start_char):
++	range_start_char;
++      range_end = TRANSLATE (p[0]);
++      /* Report an error if the range is empty and the syntax prohibits
++	 this.  */
++      ret = ((syntax & RE_NO_EMPTY_RANGES)
++	     && (range_start > range_end))? REG_ERANGE : REG_NOERROR;
++
++      /* Insert space to the end of the char_ranges.  */
++      insert_space(2, b - char_set[5] - 2, b - 1);
++      *(b - char_set[5] - 2) = range_start;
++      *(b - char_set[5] - 1) = range_end;
++      char_set[4]++; /* ranges_index */
++    }
++  /* Have to increment the pointer into the pattern string, so the
++     caller isn't still at the ending character.  */
++  (*p_ptr)++;
++
++  return ret;
++}
++#else /* BYTE */
++/* Read the ending character of a range (in a bracket expression) from the
++   uncompiled pattern *P_PTR (which ends at PEND).  We assume the
++   starting character is in `P[-2]'.  (`P[-1]' is the character `-'.)
++   Then we set the translation of all bits between the starting and
++   ending characters (inclusive) in the compiled pattern B.
++
++   Return an error code.
++
++   We use these short variable names so we can use the same macros as
++   `regex_compile' itself.  */
++
++static reg_errcode_t
++byte_compile_range (unsigned int range_start_char, const char **p_ptr,
++                    const char *pend, RE_TRANSLATE_TYPE translate,
++                    reg_syntax_t syntax, unsigned char *b)
++{
++  unsigned this_char;
++  const char *p = *p_ptr;
++  reg_errcode_t ret;
++# if _LIBC
++  const unsigned char *collseq;
++  unsigned int start_colseq;
++  unsigned int end_colseq;
++# else
++  unsigned end_char;
++# endif
++
++  if (p == pend)
++    return REG_ERANGE;
++
++  /* Have to increment the pointer into the pattern string, so the
++     caller isn't still at the ending character.  */
++  (*p_ptr)++;
++
++  /* Report an error if the range is empty and the syntax prohibits this.  */
++  ret = syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
++
++# if _LIBC
++  collseq = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
++						 _NL_COLLATE_COLLSEQMB);
++
++  start_colseq = collseq[(unsigned char) TRANSLATE (range_start_char)];
++  end_colseq = collseq[(unsigned char) TRANSLATE (p[0])];
++  for (this_char = 0; this_char <= (unsigned char) -1; ++this_char)
++    {
++      unsigned int this_colseq = collseq[(unsigned char) TRANSLATE (this_char)];
++
++      if (start_colseq <= this_colseq && this_colseq <= end_colseq)
++	{
++	  SET_LIST_BIT (TRANSLATE (this_char));
++	  ret = REG_NOERROR;
++	}
++    }
++# else
++  /* Here we see why `this_char' has to be larger than an `unsigned
++     char' -- we would otherwise go into an infinite loop, since all
++     characters <= 0xff.  */
++  range_start_char = TRANSLATE (range_start_char);
++  /* TRANSLATE(p[0]) is casted to char (not unsigned char) in TRANSLATE,
++     and some compilers cast it to int implicitly, so following for_loop
++     may fall to (almost) infinite loop.
++     e.g. If translate[p[0]] = 0xff, end_char may equals to 0xffffffff.
++     To avoid this, we cast p[0] to unsigned int and truncate it.  */
++  end_char = ((unsigned)TRANSLATE(p[0]) & ((1 << BYTEWIDTH) - 1));
++
++  for (this_char = range_start_char; this_char <= end_char; ++this_char)
++    {
++      SET_LIST_BIT (TRANSLATE (this_char));
++      ret = REG_NOERROR;
++    }
++# endif
++
++  return ret;
++}
++#endif /* WCHAR */
++\f
++/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
++   BUFP.  A fastmap records which of the (1 << BYTEWIDTH) possible
++   characters can start a string that matches the pattern.  This fastmap
++   is used by re_search to skip quickly over impossible starting points.
++
++   The caller must supply the address of a (1 << BYTEWIDTH)-byte data
++   area as BUFP->fastmap.
++
++   We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
++   the pattern buffer.
++
++   Returns 0 if we succeed, -2 if an internal error.   */
++
++#ifdef WCHAR
++/* local function for re_compile_fastmap.
++   truncate wchar_t character to char.  */
++static unsigned char truncate_wchar (CHAR_T c);
++
++static unsigned char
++truncate_wchar (CHAR_T c)
++{
++  unsigned char buf[MB_CUR_MAX];
++  mbstate_t state;
++  int retval;
++  memset (&state, '\0', sizeof (state));
++# ifdef _LIBC
++  retval = __wcrtomb (buf, c, &state);
++# else
++  retval = wcrtomb (buf, c, &state);
++# endif
++  return retval > 0 ? buf[0] : (unsigned char) c;
++}
++#endif /* WCHAR */
++
++static int
++PREFIX(re_compile_fastmap) (struct re_pattern_buffer *bufp)
++{
++  int j, k;
++#ifdef MATCH_MAY_ALLOCATE
++  PREFIX(fail_stack_type) fail_stack;
++#endif
++#ifndef REGEX_MALLOC
++  char *destination;
++#endif
++
++  register char *fastmap = bufp->fastmap;
++
++#ifdef WCHAR
++  /* We need to cast pattern to (wchar_t*), because we casted this compiled
++     pattern to (char*) in regex_compile.  */
++  UCHAR_T *pattern = (UCHAR_T*)bufp->buffer;
++  register UCHAR_T *pend = (UCHAR_T*) (bufp->buffer + bufp->used);
++#else /* BYTE */
++  UCHAR_T *pattern = bufp->buffer;
++  register UCHAR_T *pend = pattern + bufp->used;
++#endif /* WCHAR */
++  UCHAR_T *p = pattern;
++
++#ifdef REL_ALLOC
++  /* This holds the pointer to the failure stack, when
++     it is allocated relocatably.  */
++  fail_stack_elt_t *failure_stack_ptr;
++#endif
++
++  /* Assume that each path through the pattern can be null until
++     proven otherwise.  We set this false at the bottom of switch
++     statement, to which we get only if a particular path doesn't
++     match the empty string.  */
++  boolean path_can_be_null = true;
++
++  /* We aren't doing a `succeed_n' to begin with.  */
++  boolean succeed_n_p = false;
++
++  assert (fastmap != NULL && p != NULL);
++
++  INIT_FAIL_STACK ();
++  bzero (fastmap, 1 << BYTEWIDTH);  /* Assume nothing's valid.  */
++  bufp->fastmap_accurate = 1;	    /* It will be when we're done.  */
++  bufp->can_be_null = 0;
++
++  while (1)
++    {
++      if (p == pend || *p == (UCHAR_T) succeed)
++	{
++	  /* We have reached the (effective) end of pattern.  */
++	  if (!FAIL_STACK_EMPTY ())
++	    {
++	      bufp->can_be_null |= path_can_be_null;
++
++	      /* Reset for next path.  */
++	      path_can_be_null = true;
++
++	      p = fail_stack.stack[--fail_stack.avail].pointer;
++
++	      continue;
++	    }
++	  else
++	    break;
++	}
++
++      /* We should never be about to go beyond the end of the pattern.  */
++      assert (p < pend);
++
++      switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
++	{
++
++        /* I guess the idea here is to simply not bother with a fastmap
++           if a backreference is used, since it's too hard to figure out
++           the fastmap for the corresponding group.  Setting
++           `can_be_null' stops `re_search_2' from using the fastmap, so
++           that is all we do.  */
++	case duplicate:
++	  bufp->can_be_null = 1;
++          goto done;
++
++
++      /* Following are the cases which match a character.  These end
++         with `break'.  */
++
++#ifdef WCHAR
++	case exactn:
++          fastmap[truncate_wchar(p[1])] = 1;
++	  break;
++#else /* BYTE */
++	case exactn:
++          fastmap[p[1]] = 1;
++	  break;
++#endif /* WCHAR */
++#ifdef MBS_SUPPORT
++	case exactn_bin:
++	  fastmap[p[1]] = 1;
++	  break;
++#endif
++
++#ifdef WCHAR
++        /* It is hard to distinguish fastmap from (multi byte) characters
++           which depends on current locale.  */
++        case charset:
++	case charset_not:
++	case wordchar:
++	case notwordchar:
++          bufp->can_be_null = 1;
++          goto done;
++#else /* BYTE */
++        case charset:
++          for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
++	    if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
++              fastmap[j] = 1;
++	  break;
++
++
++	case charset_not:
++	  /* Chars beyond end of map must be allowed.  */
++	  for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
++            fastmap[j] = 1;
++
++	  for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
++	    if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
++              fastmap[j] = 1;
++          break;
++
++
++	case wordchar:
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) == Sword)
++	      fastmap[j] = 1;
++	  break;
++
++
++	case notwordchar:
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) != Sword)
++	      fastmap[j] = 1;
++	  break;
++#endif /* WCHAR */
++
++        case anychar:
++	  {
++	    int fastmap_newline = fastmap['\n'];
++
++	    /* `.' matches anything ...  */
++	    for (j = 0; j < (1 << BYTEWIDTH); j++)
++	      fastmap[j] = 1;
++
++	    /* ... except perhaps newline.  */
++	    if (!(bufp->syntax & RE_DOT_NEWLINE))
++	      fastmap['\n'] = fastmap_newline;
++
++	    /* Return if we have already set `can_be_null'; if we have,
++	       then the fastmap is irrelevant.  Something's wrong here.  */
++	    else if (bufp->can_be_null)
++	      goto done;
++
++	    /* Otherwise, have to check alternative paths.  */
++	    break;
++	  }
++
++#ifdef emacs
++        case syntaxspec:
++	  k = *p++;
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) == (enum syntaxcode) k)
++	      fastmap[j] = 1;
++	  break;
++
++
++	case notsyntaxspec:
++	  k = *p++;
++	  for (j = 0; j < (1 << BYTEWIDTH); j++)
++	    if (SYNTAX (j) != (enum syntaxcode) k)
++	      fastmap[j] = 1;
++	  break;
++
++
++      /* All cases after this match the empty string.  These end with
++         `continue'.  */
++
++
++	case before_dot:
++	case at_dot:
++	case after_dot:
++          continue;
++#endif /* emacs */
++
++
++        case no_op:
++        case begline:
++        case endline:
++	case begbuf:
++	case endbuf:
++	case wordbound:
++	case notwordbound:
++	case wordbeg:
++	case wordend:
++        case push_dummy_failure:
++          continue;
++
++
++	case jump_n:
++        case pop_failure_jump:
++	case maybe_pop_jump:
++	case jump:
++        case jump_past_alt:
++	case dummy_failure_jump:
++          EXTRACT_NUMBER_AND_INCR (j, p);
++	  p += j;
++	  if (j > 0)
++	    continue;
++
++          /* Jump backward implies we just went through the body of a
++             loop and matched nothing.  Opcode jumped to should be
++             `on_failure_jump' or `succeed_n'.  Just treat it like an
++             ordinary jump.  For a * loop, it has pushed its failure
++             point already; if so, discard that as redundant.  */
++          if ((re_opcode_t) *p != on_failure_jump
++	      && (re_opcode_t) *p != succeed_n)
++	    continue;
++
++          p++;
++          EXTRACT_NUMBER_AND_INCR (j, p);
++          p += j;
++
++          /* If what's on the stack is where we are now, pop it.  */
++          if (!FAIL_STACK_EMPTY ()
++	      && fail_stack.stack[fail_stack.avail - 1].pointer == p)
++            fail_stack.avail--;
++
++          continue;
++
++
++        case on_failure_jump:
++        case on_failure_keep_string_jump:
++	handle_on_failure_jump:
++          EXTRACT_NUMBER_AND_INCR (j, p);
++
++          /* For some patterns, e.g., `(a?)?', `p+j' here points to the
++             end of the pattern.  We don't want to push such a point,
++             since when we restore it above, entering the switch will
++             increment `p' past the end of the pattern.  We don't need
++             to push such a point since we obviously won't find any more
++             fastmap entries beyond `pend'.  Such a pattern can match
++             the null string, though.  */
++          if (p + j < pend)
++            {
++              if (!PUSH_PATTERN_OP (p + j, fail_stack))
++		{
++		  RESET_FAIL_STACK ();
++		  return -2;
++		}
++            }
++          else
++            bufp->can_be_null = 1;
++
++          if (succeed_n_p)
++            {
++              EXTRACT_NUMBER_AND_INCR (k, p);	/* Skip the n.  */
++              succeed_n_p = false;
++	    }
++
++          continue;
++
++
++	case succeed_n:
++          /* Get to the number of times to succeed.  */
++          p += OFFSET_ADDRESS_SIZE;
++
++          /* Increment p past the n for when k != 0.  */
++          EXTRACT_NUMBER_AND_INCR (k, p);
++          if (k == 0)
++	    {
++              p -= 2 * OFFSET_ADDRESS_SIZE;
++  	      succeed_n_p = true;  /* Spaghetti code alert.  */
++              goto handle_on_failure_jump;
++            }
++          continue;
++
++
++	case set_number_at:
++          p += 2 * OFFSET_ADDRESS_SIZE;
++          continue;
++
++
++	case start_memory:
++        case stop_memory:
++	  p += 2;
++	  continue;
++
++
++	default:
++          abort (); /* We have listed all the cases.  */
++        } /* switch *p++ */
++
++      /* Getting here means we have found the possible starting
++         characters for one path of the pattern -- and that the empty
++         string does not match.  We need not follow this path further.
++         Instead, look at the next alternative (remembered on the
++         stack), or quit if no more.  The test at the top of the loop
++         does these things.  */
++      path_can_be_null = false;
++      p = pend;
++    } /* while p */
++
++  /* Set `can_be_null' for the last path (also the first path, if the
++     pattern is empty).  */
++  bufp->can_be_null |= path_can_be_null;
++
++ done:
++  RESET_FAIL_STACK ();
++  return 0;
++}
++
++#else /* not INSIDE_RECURSION */
++
++int
++re_compile_fastmap (struct re_pattern_buffer *bufp)
++{
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    return wcs_re_compile_fastmap(bufp);
++  else
++# endif
++    return byte_re_compile_fastmap(bufp);
++} /* re_compile_fastmap */
++#ifdef _LIBC
++weak_alias (__re_compile_fastmap, re_compile_fastmap)
++#endif
++\f
++
++/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
++   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
++   this memory for recording register information.  STARTS and ENDS
++   must be allocated using the malloc library routine, and must each
++   be at least NUM_REGS * sizeof (regoff_t) bytes long.
++
++   If NUM_REGS == 0, then subsequent matches should allocate their own
++   register data.
++
++   Unless this function is called, the first search or match using
++   PATTERN_BUFFER will allocate its own register data, without
++   freeing the old data.  */
++
++void
++re_set_registers (struct re_pattern_buffer *bufp,
++                  struct re_registers *regs, unsigned num_regs,
++                  regoff_t *starts, regoff_t *ends)
++{
++  if (num_regs)
++    {
++      bufp->regs_allocated = REGS_REALLOCATE;
++      regs->num_regs = num_regs;
++      regs->start = starts;
++      regs->end = ends;
++    }
++  else
++    {
++      bufp->regs_allocated = REGS_UNALLOCATED;
++      regs->num_regs = 0;
++      regs->start = regs->end = (regoff_t *) 0;
++    }
++}
++#ifdef _LIBC
++weak_alias (__re_set_registers, re_set_registers)
++#endif
++\f
++/* Searching routines.  */
++
++/* Like re_search_2, below, but only one string is specified, and
++   doesn't let you say where to stop matching.  */
++
++int
++re_search (struct re_pattern_buffer *bufp, const char *string, int size,
++           int startpos, int range, struct re_registers *regs)
++{
++  return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
++		      regs, size);
++}
++#ifdef _LIBC
++weak_alias (__re_search, re_search)
++#endif
++
++
++/* Using the compiled pattern in BUFP->buffer, first tries to match the
++   virtual concatenation of STRING1 and STRING2, starting first at index
++   STARTPOS, then at STARTPOS + 1, and so on.
++
++   STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
++
++   RANGE is how far to scan while trying to match.  RANGE = 0 means try
++   only at STARTPOS; in general, the last start tried is STARTPOS +
++   RANGE.
++
++   In REGS, return the indices of the virtual concatenation of STRING1
++   and STRING2 that matched the entire BUFP->buffer and its contained
++   subexpressions.
++
++   Do not consider matching one past the index STOP in the virtual
++   concatenation of STRING1 and STRING2.
++
++   We return either the position in the strings at which the match was
++   found, -1 if no match, or -2 if error (such as failure
++   stack overflow).  */
++
++int
++re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
++             const char *string2, int size2, int startpos, int range,
++             struct re_registers *regs, int stop)
++{
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    return wcs_re_search_2 (bufp, string1, size1, string2, size2, startpos,
++			    range, regs, stop);
++  else
++# endif
++    return byte_re_search_2 (bufp, string1, size1, string2, size2, startpos,
++			     range, regs, stop);
++} /* re_search_2 */
++#ifdef _LIBC
++weak_alias (__re_search_2, re_search_2)
++#endif
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef MATCH_MAY_ALLOCATE
++# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
++#else
++# define FREE_VAR(var) if (var) free (var); var = NULL
++#endif
++
++#ifdef WCHAR
++# define MAX_ALLOCA_SIZE	2000
++
++# define FREE_WCS_BUFFERS() \
++  do {									      \
++    if (size1 > MAX_ALLOCA_SIZE)					      \
++      {									      \
++	free (wcs_string1);						      \
++	free (mbs_offset1);						      \
++      }									      \
++    else								      \
++      {									      \
++	FREE_VAR (wcs_string1);						      \
++	FREE_VAR (mbs_offset1);						      \
++      }									      \
++    if (size2 > MAX_ALLOCA_SIZE) 					      \
++      {									      \
++	free (wcs_string2);						      \
++	free (mbs_offset2);						      \
++      }									      \
++    else								      \
++      {									      \
++	FREE_VAR (wcs_string2);						      \
++	FREE_VAR (mbs_offset2);						      \
++      }									      \
++  } while (0)
++
++#endif
++
++
++static int
++PREFIX(re_search_2) (struct re_pattern_buffer *bufp, const char *string1,
++                     int size1, const char *string2, int size2,
++                     int startpos, int range,
++                     struct re_registers *regs, int stop)
++{
++  int val;
++  register char *fastmap = bufp->fastmap;
++  register RE_TRANSLATE_TYPE translate = bufp->translate;
++  int total_size = size1 + size2;
++  int endpos = startpos + range;
++#ifdef WCHAR
++  /* We need wchar_t* buffers correspond to cstring1, cstring2.  */
++  wchar_t *wcs_string1 = NULL, *wcs_string2 = NULL;
++  /* We need the size of wchar_t buffers correspond to csize1, csize2.  */
++  int wcs_size1 = 0, wcs_size2 = 0;
++  /* offset buffer for optimizatoin. See convert_mbs_to_wc.  */
++  int *mbs_offset1 = NULL, *mbs_offset2 = NULL;
++  /* They hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++#endif /* WCHAR */
++
++  /* Check for out-of-range STARTPOS.  */
++  if (startpos < 0 || startpos > total_size)
++    return -1;
++
++  /* Fix up RANGE if it might eventually take us outside
++     the virtual concatenation of STRING1 and STRING2.
++     Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE.  */
++  if (endpos < 0)
++    range = 0 - startpos;
++  else if (endpos > total_size)
++    range = total_size - startpos;
++
++  /* If the search isn't to be a backwards one, don't waste time in a
++     search for a pattern that must be anchored.  */
++  if (bufp->used > 0 && range > 0
++      && ((re_opcode_t) bufp->buffer[0] == begbuf
++	  /* `begline' is like `begbuf' if it cannot match at newlines.  */
++	  || ((re_opcode_t) bufp->buffer[0] == begline
++	      && !bufp->newline_anchor)))
++    {
++      if (startpos > 0)
++	return -1;
++      else
++	range = 1;
++    }
++
++#ifdef emacs
++  /* In a forward search for something that starts with \=.
++     don't keep searching past point.  */
++  if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
++    {
++      range = PT - startpos;
++      if (range <= 0)
++	return -1;
++    }
++#endif /* emacs */
++
++  /* Update the fastmap now if not correct already.  */
++  if (fastmap && !bufp->fastmap_accurate)
++    if (re_compile_fastmap (bufp) == -2)
++      return -2;
++
++#ifdef WCHAR
++  /* Allocate wchar_t array for wcs_string1 and wcs_string2 and
++     fill them with converted string.  */
++  if (size1 != 0)
++    {
++      if (size1 > MAX_ALLOCA_SIZE)
++	{
++	  wcs_string1 = TALLOC (size1 + 1, CHAR_T);
++	  mbs_offset1 = TALLOC (size1 + 1, int);
++	  is_binary = TALLOC (size1 + 1, char);
++	}
++      else
++	{
++	  wcs_string1 = REGEX_TALLOC (size1 + 1, CHAR_T);
++	  mbs_offset1 = REGEX_TALLOC (size1 + 1, int);
++	  is_binary = REGEX_TALLOC (size1 + 1, char);
++	}
++      if (!wcs_string1 || !mbs_offset1 || !is_binary)
++	{
++	  if (size1 > MAX_ALLOCA_SIZE)
++	    {
++	      free (wcs_string1);
++	      free (mbs_offset1);
++	      free (is_binary);
++	    }
++	  else
++	    {
++	      FREE_VAR (wcs_string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (is_binary);
++	    }
++	  return -2;
++	}
++      wcs_size1 = convert_mbs_to_wcs(wcs_string1, string1, size1,
++				     mbs_offset1, is_binary);
++      wcs_string1[wcs_size1] = L'\0'; /* for a sentinel  */
++      if (size1 > MAX_ALLOCA_SIZE)
++	free (is_binary);
++      else
++	FREE_VAR (is_binary);
++    }
++  if (size2 != 0)
++    {
++      if (size2 > MAX_ALLOCA_SIZE)
++	{
++	  wcs_string2 = TALLOC (size2 + 1, CHAR_T);
++	  mbs_offset2 = TALLOC (size2 + 1, int);
++	  is_binary = TALLOC (size2 + 1, char);
++	}
++      else
++	{
++	  wcs_string2 = REGEX_TALLOC (size2 + 1, CHAR_T);
++	  mbs_offset2 = REGEX_TALLOC (size2 + 1, int);
++	  is_binary = REGEX_TALLOC (size2 + 1, char);
++	}
++      if (!wcs_string2 || !mbs_offset2 || !is_binary)
++	{
++	  FREE_WCS_BUFFERS ();
++	  if (size2 > MAX_ALLOCA_SIZE)
++	    free (is_binary);
++	  else
++	    FREE_VAR (is_binary);
++	  return -2;
++	}
++      wcs_size2 = convert_mbs_to_wcs(wcs_string2, string2, size2,
++				     mbs_offset2, is_binary);
++      wcs_string2[wcs_size2] = L'\0'; /* for a sentinel  */
++      if (size2 > MAX_ALLOCA_SIZE)
++	free (is_binary);
++      else
++	FREE_VAR (is_binary);
++    }
++#endif /* WCHAR */
++
++
++  /* Loop through the string, looking for a place to start matching.  */
++  for (;;)
++    {
++      /* If a fastmap is supplied, skip quickly over characters that
++         cannot be the start of a match.  If the pattern can match the
++         null string, however, we don't need to skip characters; we want
++         the first null string.  */
++      if (fastmap && startpos < total_size && !bufp->can_be_null)
++	{
++	  if (range > 0)	/* Searching forwards.  */
++	    {
++	      register const char *d;
++	      register int lim = 0;
++	      int irange = range;
++
++              if (startpos < size1 && startpos + range >= size1)
++                lim = range - (size1 - startpos);
++
++	      d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
++
++              /* Written out as an if-else to avoid testing `translate'
++                 inside the loop.  */
++	      if (translate)
++                while (range > lim
++                       && !fastmap[(unsigned char)
++				   translate[(unsigned char) *d++]])
++                  range--;
++	      else
++                while (range > lim && !fastmap[(unsigned char) *d++])
++                  range--;
++
++	      startpos += irange - range;
++	    }
++	  else				/* Searching backwards.  */
++	    {
++	      register CHAR_T c = (size1 == 0 || startpos >= size1
++				      ? string2[startpos - size1]
++				      : string1[startpos]);
++
++	      if (!fastmap[(unsigned char) TRANSLATE (c)])
++		goto advance;
++	    }
++	}
++
++      /* If can't match the null string, and that's all we have left, fail.  */
++      if (range >= 0 && startpos == total_size && fastmap
++          && !bufp->can_be_null)
++       {
++#ifdef WCHAR
++         FREE_WCS_BUFFERS ();
++#endif
++         return -1;
++       }
++
++#ifdef WCHAR
++      val = wcs_re_match_2_internal (bufp, string1, size1, string2,
++				     size2, startpos, regs, stop,
++				     wcs_string1, wcs_size1,
++				     wcs_string2, wcs_size2,
++				     mbs_offset1, mbs_offset2);
++#else /* BYTE */
++      val = byte_re_match_2_internal (bufp, string1, size1, string2,
++				      size2, startpos, regs, stop);
++#endif /* BYTE */
++
++#ifndef REGEX_MALLOC
++# ifdef C_ALLOCA
++      alloca (0);
++# endif
++#endif
++
++      if (val >= 0)
++	{
++#ifdef WCHAR
++	  FREE_WCS_BUFFERS ();
++#endif
++	  return startpos;
++	}
++
++      if (val == -2)
++	{
++#ifdef WCHAR
++	  FREE_WCS_BUFFERS ();
++#endif
++	  return -2;
++	}
++
++    advance:
++      if (!range)
++        break;
++      else if (range > 0)
++        {
++          range--;
++          startpos++;
++        }
++      else
++        {
++          range++;
++          startpos--;
++        }
++    }
++#ifdef WCHAR
++  FREE_WCS_BUFFERS ();
++#endif
++  return -1;
++}
++
++#ifdef WCHAR
++/* This converts PTR, a pointer into one of the search wchar_t strings
++   `string1' and `string2' into an multibyte string offset from the
++   beginning of that string. We use mbs_offset to optimize.
++   See convert_mbs_to_wcs.  */
++# define POINTER_TO_OFFSET(ptr)						\
++  (FIRST_STRING_P (ptr)							\
++   ? ((regoff_t)(mbs_offset1 != NULL? mbs_offset1[(ptr)-string1] : 0))	\
++   : ((regoff_t)((mbs_offset2 != NULL? mbs_offset2[(ptr)-string2] : 0)	\
++		 + csize1)))
++#else /* BYTE */
++/* This converts PTR, a pointer into one of the search strings `string1'
++   and `string2' into an offset from the beginning of that string.  */
++# define POINTER_TO_OFFSET(ptr)			\
++  (FIRST_STRING_P (ptr)				\
++   ? ((regoff_t) ((ptr) - string1))		\
++   : ((regoff_t) ((ptr) - string2 + size1)))
++#endif /* WCHAR */
++
++/* Macros for dealing with the split strings in re_match_2.  */
++
++#define MATCHING_IN_FIRST_STRING  (dend == end_match_1)
++
++/* Call before fetching a character with *d.  This switches over to
++   string2 if necessary.  */
++#define PREFETCH()							\
++  while (d == dend)						    	\
++    {									\
++      /* End of string2 => fail.  */					\
++      if (dend == end_match_2) 						\
++        goto fail;							\
++      /* End of string1 => advance to string2.  */ 			\
++      d = string2;						        \
++      dend = end_match_2;						\
++    }
++
++/* Test if at very beginning or at very end of the virtual concatenation
++   of `string1' and `string2'.  If only one string, it's `string2'.  */
++#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
++#define AT_STRINGS_END(d) ((d) == end2)
++
++
++/* Test if D points to a character which is word-constituent.  We have
++   two special cases to check for: if past the end of string1, look at
++   the first character in string2; and if before the beginning of
++   string2, look at the last character in string1.  */
++#ifdef WCHAR
++/* Use internationalized API instead of SYNTAX.  */
++# define WORDCHAR_P(d)							\
++  (iswalnum ((wint_t)((d) == end1 ? *string2				\
++           : (d) == string2 - 1 ? *(end1 - 1) : *(d))) != 0		\
++   || ((d) == end1 ? *string2						\
++       : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == L'_')
++#else /* BYTE */
++# define WORDCHAR_P(d)							\
++  (SYNTAX ((d) == end1 ? *string2					\
++           : (d) == string2 - 1 ? *(end1 - 1) : *(d))			\
++   == Sword)
++#endif /* WCHAR */
++
++/* Disabled due to a compiler bug -- see comment at case wordbound */
++#if 0
++/* Test if the character before D and the one at D differ with respect
++   to being word-constituent.  */
++#define AT_WORD_BOUNDARY(d)						\
++  (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)				\
++   || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
++#endif
++
++/* Free everything we malloc.  */
++#ifdef MATCH_MAY_ALLOCATE
++# ifdef WCHAR
++#  define FREE_VARIABLES()						\
++  do {									\
++    REGEX_FREE_STACK (fail_stack.stack);				\
++    FREE_VAR (regstart);						\
++    FREE_VAR (regend);							\
++    FREE_VAR (old_regstart);						\
++    FREE_VAR (old_regend);						\
++    FREE_VAR (best_regstart);						\
++    FREE_VAR (best_regend);						\
++    FREE_VAR (reg_info);						\
++    FREE_VAR (reg_dummy);						\
++    FREE_VAR (reg_info_dummy);						\
++    if (!cant_free_wcs_buf)						\
++      {									\
++        FREE_VAR (string1);						\
++        FREE_VAR (string2);						\
++        FREE_VAR (mbs_offset1);						\
++        FREE_VAR (mbs_offset2);						\
++      }									\
++  } while (0)
++# else /* BYTE */
++#  define FREE_VARIABLES()						\
++  do {									\
++    REGEX_FREE_STACK (fail_stack.stack);				\
++    FREE_VAR (regstart);						\
++    FREE_VAR (regend);							\
++    FREE_VAR (old_regstart);						\
++    FREE_VAR (old_regend);						\
++    FREE_VAR (best_regstart);						\
++    FREE_VAR (best_regend);						\
++    FREE_VAR (reg_info);						\
++    FREE_VAR (reg_dummy);						\
++    FREE_VAR (reg_info_dummy);						\
++  } while (0)
++# endif /* WCHAR */
++#else
++# ifdef WCHAR
++#  define FREE_VARIABLES()						\
++  do {									\
++    if (!cant_free_wcs_buf)						\
++      {									\
++        FREE_VAR (string1);						\
++        FREE_VAR (string2);						\
++        FREE_VAR (mbs_offset1);						\
++        FREE_VAR (mbs_offset2);						\
++      }									\
++  } while (0)
++# else /* BYTE */
++#  define FREE_VARIABLES() ((void)0) /* Do nothing!  But inhibit gcc warning. */
++# endif /* WCHAR */
++#endif /* not MATCH_MAY_ALLOCATE */
++
++/* These values must meet several constraints.  They must not be valid
++   register values; since we have a limit of 255 registers (because
++   we use only one byte in the pattern for the register number), we can
++   use numbers larger than 255.  They must differ by 1, because of
++   NUM_FAILURE_ITEMS above.  And the value for the lowest register must
++   be larger than the value for the highest register, so we do not try
++   to actually save any registers when none are active.  */
++#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
++#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
++\f
++#else /* not INSIDE_RECURSION */
++/* Matching routines.  */
++
++#ifndef emacs   /* Emacs never uses this.  */
++/* re_match is like re_match_2 except it takes only a single string.  */
++
++int
++re_match (struct re_pattern_buffer *bufp, const char *string,
++          int size, int pos, struct re_registers *regs)
++{
++  int result;
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    result = wcs_re_match_2_internal (bufp, NULL, 0, string, size,
++				      pos, regs, size,
++				      NULL, 0, NULL, 0, NULL, NULL);
++  else
++# endif
++    result = byte_re_match_2_internal (bufp, NULL, 0, string, size,
++				  pos, regs, size);
++# ifndef REGEX_MALLOC
++#  ifdef C_ALLOCA
++  alloca (0);
++#  endif
++# endif
++  return result;
++}
++# ifdef _LIBC
++weak_alias (__re_match, re_match)
++# endif
++#endif /* not emacs */
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++static boolean PREFIX(group_match_null_string_p) (UCHAR_T **p,
++                                                  UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static boolean PREFIX(alt_match_null_string_p) (UCHAR_T *p,
++                                                UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static boolean PREFIX(common_op_match_null_string_p) (UCHAR_T **p,
++                                                      UCHAR_T *end,
++					PREFIX(register_info_type) *reg_info);
++static int PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2,
++                                   register int len,
++				   RE_TRANSLATE_TYPE translate);
++#else /* not INSIDE_RECURSION */
++
++/* re_match_2 matches the compiled pattern in BUFP against the
++   the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
++   and SIZE2, respectively).  We start matching at POS, and stop
++   matching at STOP.
++
++   If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
++   store offsets for the substring each group matched in REGS.  See the
++   documentation for exactly how many groups we fill.
++
++   We return -1 if no match, -2 if an internal error (such as the
++   failure stack overflowing).  Otherwise, we return the length of the
++   matched substring.  */
++
++int
++re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int size1,
++            const char *string2, int size2, int pos,
++            struct re_registers *regs, int stop)
++{
++  int result;
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    result = wcs_re_match_2_internal (bufp, string1, size1, string2, size2,
++				      pos, regs, stop,
++				      NULL, 0, NULL, 0, NULL, NULL);
++  else
++# endif
++    result = byte_re_match_2_internal (bufp, string1, size1, string2, size2,
++				  pos, regs, stop);
++
++#ifndef REGEX_MALLOC
++# ifdef C_ALLOCA
++  alloca (0);
++# endif
++#endif
++  return result;
++}
++#ifdef _LIBC
++weak_alias (__re_match_2, re_match_2)
++#endif
++
++#endif /* not INSIDE_RECURSION */
++
++#ifdef INSIDE_RECURSION
++
++#ifdef WCHAR
++static int count_mbs_length (int *, int);
++
++/* This check the substring (from 0, to length) of the multibyte string,
++   to which offset_buffer correspond. And count how many wchar_t_characters
++   the substring occupy. We use offset_buffer to optimization.
++   See convert_mbs_to_wcs.  */
++
++static int
++count_mbs_length(int *offset_buffer, int length)
++{
++  int upper, lower;
++
++  /* Check whether the size is valid.  */
++  if (length < 0)
++    return -1;
++
++  if (offset_buffer == NULL)
++    return 0;
++
++  /* If there are no multibyte character, offset_buffer[i] == i.
++   Optmize for this case.  */
++  if (offset_buffer[length] == length)
++    return length;
++
++  /* Set up upper with length. (because for all i, offset_buffer[i] >= i)  */
++  upper = length;
++  lower = 0;
++
++  while (true)
++    {
++      int middle = (lower + upper) / 2;
++      if (middle == lower || middle == upper)
++	break;
++      if (offset_buffer[middle] > length)
++	upper = middle;
++      else if (offset_buffer[middle] < length)
++	lower = middle;
++      else
++	return middle;
++    }
++
++  return -1;
++}
++#endif /* WCHAR */
++
++/* This is a separate function so that we can force an alloca cleanup
++   afterwards.  */
++#ifdef WCHAR
++static int
++wcs_re_match_2_internal (struct re_pattern_buffer *bufp,
++                         const char *cstring1, int csize1,
++                         const char *cstring2, int csize2,
++                         int pos,
++			 struct re_registers *regs,
++                         int stop,
++     /* string1 == string2 == NULL means string1/2, size1/2 and
++	mbs_offset1/2 need seting up in this function.  */
++     /* We need wchar_t* buffers correspond to cstring1, cstring2.  */
++                         wchar_t *string1, int size1,
++                         wchar_t *string2, int size2,
++     /* offset buffer for optimizatoin. See convert_mbs_to_wc.  */
++			 int *mbs_offset1, int *mbs_offset2)
++#else /* BYTE */
++static int
++byte_re_match_2_internal (struct re_pattern_buffer *bufp,
++                          const char *string1, int size1,
++                          const char *string2, int size2,
++                          int pos,
++			  struct re_registers *regs, int stop)
++#endif /* BYTE */
++{
++  /* General temporaries.  */
++  int mcnt;
++  UCHAR_T *p1;
++#ifdef WCHAR
++  /* They hold whether each wchar_t is binary data or not.  */
++  char *is_binary = NULL;
++  /* If true, we can't free string1/2, mbs_offset1/2.  */
++  int cant_free_wcs_buf = 1;
++#endif /* WCHAR */
++
++  /* Just past the end of the corresponding string.  */
++  const CHAR_T *end1, *end2;
++
++  /* Pointers into string1 and string2, just past the last characters in
++     each to consider matching.  */
++  const CHAR_T *end_match_1, *end_match_2;
++
++  /* Where we are in the data, and the end of the current string.  */
++  const CHAR_T *d, *dend;
++
++  /* Where we are in the pattern, and the end of the pattern.  */
++#ifdef WCHAR
++  UCHAR_T *pattern, *p;
++  register UCHAR_T *pend;
++#else /* BYTE */
++  UCHAR_T *p = bufp->buffer;
++  register UCHAR_T *pend = p + bufp->used;
++#endif /* WCHAR */
++
++  /* Mark the opcode just after a start_memory, so we can test for an
++     empty subpattern when we get to the stop_memory.  */
++  UCHAR_T *just_past_start_mem = 0;
++
++  /* We use this to map every character in the string.  */
++  RE_TRANSLATE_TYPE translate = bufp->translate;
++
++  /* Failure point stack.  Each place that can handle a failure further
++     down the line pushes a failure point on this stack.  It consists of
++     restart, regend, and reg_info for all registers corresponding to
++     the subexpressions we're currently inside, plus the number of such
++     registers, and, finally, two char *'s.  The first char * is where
++     to resume scanning the pattern; the second one is where to resume
++     scanning the strings.  If the latter is zero, the failure point is
++     a ``dummy''; if a failure happens and the failure point is a dummy,
++     it gets discarded and the next next one is tried.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
++  PREFIX(fail_stack_type) fail_stack;
++#endif
++#ifdef DEBUG
++  static unsigned failure_id;
++  unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
++#endif
++
++#ifdef REL_ALLOC
++  /* This holds the pointer to the failure stack, when
++     it is allocated relocatably.  */
++  fail_stack_elt_t *failure_stack_ptr;
++#endif
++
++  /* We fill all the registers internally, independent of what we
++     return, for use in backreferences.  The number here includes
++     an element for register zero.  */
++  size_t num_regs = bufp->re_nsub + 1;
++
++  /* The currently active registers.  */
++  active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++  active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++
++  /* Information on the contents of registers. These are pointers into
++     the input strings; they record just what was matched (on this
++     attempt) by a subexpression part of the pattern, that is, the
++     regnum-th regstart pointer points to where in the pattern we began
++     matching and the regnum-th regend points to right after where we
++     stopped matching the regnum-th subexpression.  (The zeroth register
++     keeps track of what the whole pattern matches.)  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **regstart, **regend;
++#endif
++
++  /* If a group that's operated upon by a repetition operator fails to
++     match anything, then the register for its start will need to be
++     restored because it will have been set to wherever in the string we
++     are when we last see its open-group operator.  Similarly for a
++     register's end.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **old_regstart, **old_regend;
++#endif
++
++  /* The is_active field of reg_info helps us keep track of which (possibly
++     nested) subexpressions we are currently in. The matched_something
++     field of reg_info[reg_num] helps us tell whether or not we have
++     matched any of the pattern so far this time through the reg_num-th
++     subexpression.  These two fields get reset each time through any
++     loop their register is in.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global.  */
++  PREFIX(register_info_type) *reg_info;
++#endif
++
++  /* The following record the register info as found in the above
++     variables when we find a match better than any we've seen before.
++     This happens as we backtrack through the failure points, which in
++     turn happens only if we have not yet matched the entire string. */
++  unsigned best_regs_set = false;
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **best_regstart, **best_regend;
++#endif
++
++  /* Logically, this is `best_regend[0]'.  But we don't want to have to
++     allocate space for that if we're not allocating space for anything
++     else (see below).  Also, we never need info about register 0 for
++     any of the other register vectors, and it seems rather a kludge to
++     treat `best_regend' differently than the rest.  So we keep track of
++     the end of the best match so far in a separate variable.  We
++     initialize this to NULL so that when we backtrack the first time
++     and need to test it, it's not garbage.  */
++  const CHAR_T *match_end = NULL;
++
++  /* This helps SET_REGS_MATCHED avoid doing redundant work.  */
++  int set_regs_matched_done = 0;
++
++  /* Used when we pop values we don't care about.  */
++#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global.  */
++  const CHAR_T **reg_dummy;
++  PREFIX(register_info_type) *reg_info_dummy;
++#endif
++
++#ifdef DEBUG
++  /* Counts the total number of registers pushed.  */
++  unsigned num_regs_pushed = 0;
++#endif
++
++  DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
++
++  INIT_FAIL_STACK ();
++
++#ifdef MATCH_MAY_ALLOCATE
++  /* Do not bother to initialize all the register variables if there are
++     no groups in the pattern, as it takes a fair amount of time.  If
++     there are groups, we include space for register 0 (the whole
++     pattern), even though we never use it, since it simplifies the
++     array indexing.  We should fix this.  */
++  if (bufp->re_nsub)
++    {
++      regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      old_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      old_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      best_regstart = REGEX_TALLOC (num_regs, const CHAR_T *);
++      best_regend = REGEX_TALLOC (num_regs, const CHAR_T *);
++      reg_info = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
++      reg_dummy = REGEX_TALLOC (num_regs, const CHAR_T *);
++      reg_info_dummy = REGEX_TALLOC (num_regs, PREFIX(register_info_type));
++
++      if (!(regstart && regend && old_regstart && old_regend && reg_info
++            && best_regstart && best_regend && reg_dummy && reg_info_dummy))
++        {
++          FREE_VARIABLES ();
++          return -2;
++        }
++    }
++  else
++    {
++      /* We must initialize all our variables to NULL, so that
++         `FREE_VARIABLES' doesn't try to free them.  */
++      regstart = regend = old_regstart = old_regend = best_regstart
++        = best_regend = reg_dummy = NULL;
++      reg_info = reg_info_dummy = (PREFIX(register_info_type) *) NULL;
++    }
++#endif /* MATCH_MAY_ALLOCATE */
++
++  /* The starting position is bogus.  */
++#ifdef WCHAR
++  if (pos < 0 || pos > csize1 + csize2)
++#else /* BYTE */
++  if (pos < 0 || pos > size1 + size2)
++#endif
++    {
++      FREE_VARIABLES ();
++      return -1;
++    }
++
++#ifdef WCHAR
++  /* Allocate wchar_t array for string1 and string2 and
++     fill them with converted string.  */
++  if (string1 == NULL && string2 == NULL)
++    {
++      /* We need seting up buffers here.  */
++
++      /* We must free wcs buffers in this function.  */
++      cant_free_wcs_buf = 0;
++
++      if (csize1 != 0)
++	{
++	  string1 = REGEX_TALLOC (csize1 + 1, CHAR_T);
++	  mbs_offset1 = REGEX_TALLOC (csize1 + 1, int);
++	  is_binary = REGEX_TALLOC (csize1 + 1, char);
++	  if (!string1 || !mbs_offset1 || !is_binary)
++	    {
++	      FREE_VAR (string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (is_binary);
++	      return -2;
++	    }
++	}
++      if (csize2 != 0)
++	{
++	  string2 = REGEX_TALLOC (csize2 + 1, CHAR_T);
++	  mbs_offset2 = REGEX_TALLOC (csize2 + 1, int);
++	  is_binary = REGEX_TALLOC (csize2 + 1, char);
++	  if (!string2 || !mbs_offset2 || !is_binary)
++	    {
++	      FREE_VAR (string1);
++	      FREE_VAR (mbs_offset1);
++	      FREE_VAR (string2);
++	      FREE_VAR (mbs_offset2);
++	      FREE_VAR (is_binary);
++	      return -2;
++	    }
++	  size2 = convert_mbs_to_wcs(string2, cstring2, csize2,
++				     mbs_offset2, is_binary);
++	  string2[size2] = L'\0'; /* for a sentinel  */
++	  FREE_VAR (is_binary);
++	}
++    }
++
++  /* We need to cast pattern to (wchar_t*), because we casted this compiled
++     pattern to (char*) in regex_compile.  */
++  p = pattern = (CHAR_T*)bufp->buffer;
++  pend = (CHAR_T*)(bufp->buffer + bufp->used);
++
++#endif /* WCHAR */
++
++  /* Initialize subexpression text positions to -1 to mark ones that no
++     start_memory/stop_memory has been seen for. Also initialize the
++     register information struct.  */
++  for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++    {
++      regstart[mcnt] = regend[mcnt]
++        = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
++
++      REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
++      IS_ACTIVE (reg_info[mcnt]) = 0;
++      MATCHED_SOMETHING (reg_info[mcnt]) = 0;
++      EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
++    }
++
++  /* We move `string1' into `string2' if the latter's empty -- but not if
++     `string1' is null.  */
++  if (size2 == 0 && string1 != NULL)
++    {
++      string2 = string1;
++      size2 = size1;
++      string1 = 0;
++      size1 = 0;
++#ifdef WCHAR
++      mbs_offset2 = mbs_offset1;
++      csize2 = csize1;
++      mbs_offset1 = NULL;
++      csize1 = 0;
++#endif
++    }
++  end1 = string1 + size1;
++  end2 = string2 + size2;
++
++  /* Compute where to stop matching, within the two strings.  */
++#ifdef WCHAR
++  if (stop <= csize1)
++    {
++      mcnt = count_mbs_length(mbs_offset1, stop);
++      end_match_1 = string1 + mcnt;
++      end_match_2 = string2;
++    }
++  else
++    {
++      if (stop > csize1 + csize2)
++	stop = csize1 + csize2;
++      end_match_1 = end1;
++      mcnt = count_mbs_length(mbs_offset2, stop-csize1);
++      end_match_2 = string2 + mcnt;
++    }
++  if (mcnt < 0)
++    { /* count_mbs_length return error.  */
++      FREE_VARIABLES ();
++      return -1;
++    }
++#else
++  if (stop <= size1)
++    {
++      end_match_1 = string1 + stop;
++      end_match_2 = string2;
++    }
++  else
++    {
++      end_match_1 = end1;
++      end_match_2 = string2 + stop - size1;
++    }
++#endif /* WCHAR */
++
++  /* `p' scans through the pattern as `d' scans through the data.
++     `dend' is the end of the input string that `d' points within.  `d'
++     is advanced into the following input string whenever necessary, but
++     this happens before fetching; therefore, at the beginning of the
++     loop, `d' can be pointing at the end of a string, but it cannot
++     equal `string2'.  */
++#ifdef WCHAR
++  if (size1 > 0 && pos <= csize1)
++    {
++      mcnt = count_mbs_length(mbs_offset1, pos);
++      d = string1 + mcnt;
++      dend = end_match_1;
++    }
++  else
++    {
++      mcnt = count_mbs_length(mbs_offset2, pos-csize1);
++      d = string2 + mcnt;
++      dend = end_match_2;
++    }
++
++  if (mcnt < 0)
++    { /* count_mbs_length return error.  */
++      FREE_VARIABLES ();
++      return -1;
++    }
++#else
++  if (size1 > 0 && pos <= size1)
++    {
++      d = string1 + pos;
++      dend = end_match_1;
++    }
++  else
++    {
++      d = string2 + pos - size1;
++      dend = end_match_2;
++    }
++#endif /* WCHAR */
++
++  DEBUG_PRINT1 ("The compiled pattern is:\n");
++  DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
++  DEBUG_PRINT1 ("The string to match is: `");
++  DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
++  DEBUG_PRINT1 ("'\n");
++
++  /* This loops over pattern commands.  It exits by returning from the
++     function if the match is complete, or it drops through if the match
++     fails at this starting point in the input data.  */
++  for (;;)
++    {
++#ifdef _LIBC
++      DEBUG_PRINT2 ("\n%p: ", p);
++#else
++      DEBUG_PRINT2 ("\n0x%x: ", p);
++#endif
++
++      if (p == pend)
++	{ /* End of pattern means we might have succeeded.  */
++          DEBUG_PRINT1 ("end of pattern ... ");
++
++	  /* If we haven't matched the entire string, and we want the
++             longest match, try backtracking.  */
++          if (d != end_match_2)
++	    {
++	      /* 1 if this match ends in the same string (string1 or string2)
++		 as the best previous match.  */
++	      boolean same_str_p = (FIRST_STRING_P (match_end)
++				    == MATCHING_IN_FIRST_STRING);
++	      /* 1 if this match is the best seen so far.  */
++	      boolean best_match_p;
++
++	      /* AIX compiler got confused when this was combined
++		 with the previous declaration.  */
++	      if (same_str_p)
++		best_match_p = d > match_end;
++	      else
++		best_match_p = !MATCHING_IN_FIRST_STRING;
++
++              DEBUG_PRINT1 ("backtracking.\n");
++
++              if (!FAIL_STACK_EMPTY ())
++                { /* More failure points to try.  */
++
++                  /* If exceeds best match so far, save it.  */
++                  if (!best_regs_set || best_match_p)
++                    {
++                      best_regs_set = true;
++                      match_end = d;
++
++                      DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
++
++                      for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++                        {
++                          best_regstart[mcnt] = regstart[mcnt];
++                          best_regend[mcnt] = regend[mcnt];
++                        }
++                    }
++                  goto fail;
++                }
++
++              /* If no failure points, don't restore garbage.  And if
++                 last match is real best match, don't restore second
++                 best one. */
++              else if (best_regs_set && !best_match_p)
++                {
++  	        restore_best_regs:
++                  /* Restore best match.  It may happen that `dend ==
++                     end_match_1' while the restored d is in string2.
++                     For example, the pattern `x.*y.*z' against the
++                     strings `x-' and `y-z-', if the two strings are
++                     not consecutive in memory.  */
++                  DEBUG_PRINT1 ("Restoring best registers.\n");
++
++                  d = match_end;
++                  dend = ((d >= string1 && d <= end1)
++		           ? end_match_1 : end_match_2);
++
++		  for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
++		    {
++		      regstart[mcnt] = best_regstart[mcnt];
++		      regend[mcnt] = best_regend[mcnt];
++		    }
++                }
++            } /* d != end_match_2 */
++
++	succeed_label:
++          DEBUG_PRINT1 ("Accepting match.\n");
++          /* If caller wants register contents data back, do it.  */
++          if (regs && !bufp->no_sub)
++	    {
++	      /* Have the register data arrays been allocated?  */
++              if (bufp->regs_allocated == REGS_UNALLOCATED)
++                { /* No.  So allocate them with malloc.  We need one
++                     extra element beyond `num_regs' for the `-1' marker
++                     GNU code uses.  */
++                  regs->num_regs = MAX (RE_NREGS, num_regs + 1);
++                  regs->start = TALLOC (regs->num_regs, regoff_t);
++                  regs->end = TALLOC (regs->num_regs, regoff_t);
++                  if (regs->start == NULL || regs->end == NULL)
++		    {
++		      FREE_VARIABLES ();
++		      return -2;
++		    }
++                  bufp->regs_allocated = REGS_REALLOCATE;
++                }
++              else if (bufp->regs_allocated == REGS_REALLOCATE)
++                { /* Yes.  If we need more elements than were already
++                     allocated, reallocate them.  If we need fewer, just
++                     leave it alone.  */
++                  if (regs->num_regs < num_regs + 1)
++                    {
++                      regs->num_regs = num_regs + 1;
++                      RETALLOC (regs->start, regs->num_regs, regoff_t);
++                      RETALLOC (regs->end, regs->num_regs, regoff_t);
++                      if (regs->start == NULL || regs->end == NULL)
++			{
++			  FREE_VARIABLES ();
++			  return -2;
++			}
++                    }
++                }
++              else
++		{
++		  /* These braces fend off a "empty body in an else-statement"
++		     warning under GCC when assert expands to nothing.  */
++		  assert (bufp->regs_allocated == REGS_FIXED);
++		}
++
++              /* Convert the pointer data in `regstart' and `regend' to
++                 indices.  Register zero has to be set differently,
++                 since we haven't kept track of any info for it.  */
++              if (regs->num_regs > 0)
++                {
++                  regs->start[0] = pos;
++#ifdef WCHAR
++		  if (MATCHING_IN_FIRST_STRING)
++		    regs->end[0] = mbs_offset1 != NULL ?
++					mbs_offset1[d-string1] : 0;
++		  else
++		    regs->end[0] = csize1 + (mbs_offset2 != NULL ?
++					     mbs_offset2[d-string2] : 0);
++#else
++                  regs->end[0] = (MATCHING_IN_FIRST_STRING
++				  ? ((regoff_t) (d - string1))
++			          : ((regoff_t) (d - string2 + size1)));
++#endif /* WCHAR */
++                }
++
++              /* Go through the first `min (num_regs, regs->num_regs)'
++                 registers, since that is all we initialized.  */
++	      for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
++		   mcnt++)
++		{
++                  if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
++                    regs->start[mcnt] = regs->end[mcnt] = -1;
++                  else
++                    {
++		      regs->start[mcnt]
++			= (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
++                      regs->end[mcnt]
++			= (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
++                    }
++		}
++
++              /* If the regs structure we return has more elements than
++                 were in the pattern, set the extra elements to -1.  If
++                 we (re)allocated the registers, this is the case,
++                 because we always allocate enough to have at least one
++                 -1 at the end.  */
++              for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
++                regs->start[mcnt] = regs->end[mcnt] = -1;
++	    } /* regs && !bufp->no_sub */
++
++          DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
++                        nfailure_points_pushed, nfailure_points_popped,
++                        nfailure_points_pushed - nfailure_points_popped);
++          DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
++
++#ifdef WCHAR
++	  if (MATCHING_IN_FIRST_STRING)
++	    mcnt = mbs_offset1 != NULL ? mbs_offset1[d-string1] : 0;
++	  else
++	    mcnt = (mbs_offset2 != NULL ? mbs_offset2[d-string2] : 0) +
++			csize1;
++          mcnt -= pos;
++#else
++          mcnt = d - pos - (MATCHING_IN_FIRST_STRING
++			    ? string1
++			    : string2 - size1);
++#endif /* WCHAR */
++
++          DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
++
++          FREE_VARIABLES ();
++          return mcnt;
++        }
++
++      /* Otherwise match next pattern command.  */
++      switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
++	{
++        /* Ignore these.  Used to ignore the n of succeed_n's which
++           currently have n == 0.  */
++        case no_op:
++          DEBUG_PRINT1 ("EXECUTING no_op.\n");
++          break;
++
++	case succeed:
++          DEBUG_PRINT1 ("EXECUTING succeed.\n");
++	  goto succeed_label;
++
++        /* Match the next n pattern characters exactly.  The following
++           byte in the pattern defines n, and the n bytes after that
++           are the characters to match.  */
++	case exactn:
++#ifdef MBS_SUPPORT
++	case exactn_bin:
++#endif
++	  mcnt = *p++;
++          DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
++
++          /* This is written out as an if-else so we don't waste time
++             testing `translate' inside the loop.  */
++          if (translate)
++	    {
++	      do
++		{
++		  PREFETCH ();
++#ifdef WCHAR
++		  if (*d <= 0xff)
++		    {
++		      if ((UCHAR_T) translate[(unsigned char) *d++]
++			  != (UCHAR_T) *p++)
++			goto fail;
++		    }
++		  else
++		    {
++		      if (*d++ != (CHAR_T) *p++)
++			goto fail;
++		    }
++#else
++		  if ((UCHAR_T) translate[(unsigned char) *d++]
++		      != (UCHAR_T) *p++)
++                    goto fail;
++#endif /* WCHAR */
++		}
++	      while (--mcnt);
++	    }
++	  else
++	    {
++	      do
++		{
++		  PREFETCH ();
++		  if (*d++ != (CHAR_T) *p++) goto fail;
++		}
++	      while (--mcnt);
++	    }
++	  SET_REGS_MATCHED ();
++          break;
++
++
++        /* Match any character except possibly a newline or a null.  */
++	case anychar:
++          DEBUG_PRINT1 ("EXECUTING anychar.\n");
++
++          PREFETCH ();
++
++          if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
++              || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
++	    goto fail;
++
++          SET_REGS_MATCHED ();
++          DEBUG_PRINT2 ("  Matched `%ld'.\n", (long int) *d);
++          d++;
++	  break;
++
++
++	case charset:
++	case charset_not:
++	  {
++	    register UCHAR_T c;
++#ifdef WCHAR
++	    unsigned int i, char_class_length, coll_symbol_length,
++              equiv_class_length, ranges_length, chars_length, length;
++	    CHAR_T *workp, *workp2, *charset_top;
++#define WORK_BUFFER_SIZE 128
++            CHAR_T str_buf[WORK_BUFFER_SIZE];
++# ifdef _LIBC
++	    uint32_t nrules;
++# endif /* _LIBC */
++#endif /* WCHAR */
++	    boolean negate = (re_opcode_t) *(p - 1) == charset_not;
++
++            DEBUG_PRINT2 ("EXECUTING charset%s.\n", negate ? "_not" : "");
++	    PREFETCH ();
++	    c = TRANSLATE (*d); /* The character to match.  */
++#ifdef WCHAR
++# ifdef _LIBC
++	    nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
++# endif /* _LIBC */
++	    charset_top = p - 1;
++	    char_class_length = *p++;
++	    coll_symbol_length = *p++;
++	    equiv_class_length = *p++;
++	    ranges_length = *p++;
++	    chars_length = *p++;
++	    /* p points charset[6], so the address of the next instruction
++	       (charset[l+m+n+2o+k+p']) equals p[l+m+n+2*o+p'],
++	       where l=length of char_classes, m=length of collating_symbol,
++	       n=equivalence_class, o=length of char_range,
++	       p'=length of character.  */
++	    workp = p;
++	    /* Update p to indicate the next instruction.  */
++	    p += char_class_length + coll_symbol_length+ equiv_class_length +
++              2*ranges_length + chars_length;
++
++            /* match with char_class?  */
++	    for (i = 0; i < char_class_length ; i += CHAR_CLASS_SIZE)
++	      {
++		wctype_t wctype;
++		uintptr_t alignedp = ((uintptr_t)workp
++				      + __alignof__(wctype_t) - 1)
++		  		      & ~(uintptr_t)(__alignof__(wctype_t) - 1);
++		wctype = *((wctype_t*)alignedp);
++		workp += CHAR_CLASS_SIZE;
++# ifdef _LIBC
++		if (__iswctype((wint_t)c, wctype))
++		  goto char_set_matched;
++# else
++		if (iswctype((wint_t)c, wctype))
++		  goto char_set_matched;
++# endif
++	      }
++
++            /* match with collating_symbol?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++		const unsigned char *extra = (const unsigned char *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
++
++		for (workp2 = workp + coll_symbol_length ; workp < workp2 ;
++		     workp++)
++		  {
++		    int32_t *wextra;
++		    wextra = (int32_t*)(extra + *workp++);
++		    for (i = 0; i < *wextra; ++i)
++		      if (TRANSLATE(d[i]) != wextra[1 + i])
++			break;
++
++		    if (i == *wextra)
++		      {
++			/* Update d, however d will be incremented at
++			   char_set_matched:, we decrement d here.  */
++			d += i - 1;
++			goto char_set_matched;
++		      }
++		  }
++	      }
++	    else /* (nrules == 0) */
++# endif
++	      /* If we can't look up collation data, we use wcscoll
++		 instead.  */
++	      {
++		for (workp2 = workp + coll_symbol_length ; workp < workp2 ;)
++		  {
++		    const CHAR_T *backup_d = d, *backup_dend = dend;
++# ifdef _LIBC
++		    length = __wcslen (workp);
++# else
++		    length = wcslen (workp);
++# endif
++
++		    /* If wcscoll(the collating symbol, whole string) > 0,
++		       any substring of the string never match with the
++		       collating symbol.  */
++# ifdef _LIBC
++		    if (__wcscoll (workp, d) > 0)
++# else
++		    if (wcscoll (workp, d) > 0)
++# endif
++		      {
++			workp += length + 1;
++			continue;
++		      }
++
++		    /* First, we compare the collating symbol with
++		       the first character of the string.
++		       If it don't match, we add the next character to
++		       the compare buffer in turn.  */
++		    for (i = 0 ; i < WORK_BUFFER_SIZE-1 ; i++, d++)
++		      {
++			int match;
++			if (d == dend)
++			  {
++			    if (dend == end_match_2)
++			      break;
++			    d = string2;
++			    dend = end_match_2;
++			  }
++
++			/* add next character to the compare buffer.  */
++			str_buf[i] = TRANSLATE(*d);
++			str_buf[i+1] = '\0';
++
++# ifdef _LIBC
++			match = __wcscoll (workp, str_buf);
++# else
++			match = wcscoll (workp, str_buf);
++# endif
++			if (match == 0)
++			  goto char_set_matched;
++
++			if (match < 0)
++			  /* (str_buf > workp) indicate (str_buf + X > workp),
++			     because for all X (str_buf + X > str_buf).
++			     So we don't need continue this loop.  */
++			  break;
++
++			/* Otherwise(str_buf < workp),
++			   (str_buf+next_character) may equals (workp).
++			   So we continue this loop.  */
++		      }
++		    /* not matched */
++		    d = backup_d;
++		    dend = backup_dend;
++		    workp += length + 1;
++		  }
++              }
++            /* match with equivalence_class?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++                const CHAR_T *backup_d = d, *backup_dend = dend;
++		/* Try to match the equivalence class against
++		   those known to the collate implementation.  */
++		const int32_t *table;
++		const int32_t *weights;
++		const int32_t *extra;
++		const int32_t *indirect;
++		int32_t idx, idx2;
++		wint_t *cp;
++		size_t len;
++
++		/* This #include defines a local function!  */
++#  include <locale/weightwc.h>
++
++		table = (const int32_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
++		weights = (const wint_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
++		extra = (const wint_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
++		indirect = (const int32_t *)
++		  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
++
++		/* Write 1 collating element to str_buf, and
++		   get its index.  */
++		idx2 = 0;
++
++		for (i = 0 ; idx2 == 0 && i < WORK_BUFFER_SIZE - 1; i++)
++		  {
++		    cp = (wint_t*)str_buf;
++		    if (d == dend)
++		      {
++			if (dend == end_match_2)
++			  break;
++			d = string2;
++			dend = end_match_2;
++		      }
++		    str_buf[i] = TRANSLATE(*(d+i));
++		    str_buf[i+1] = '\0'; /* sentinel */
++		    idx2 = findidx ((const wint_t**)&cp, i);
++		  }
++
++		/* Update d, however d will be incremented at
++		   char_set_matched:, we decrement d here.  */
++		d = backup_d + ((wchar_t*)cp - (wchar_t*)str_buf - 1);
++		if (d >= dend)
++		  {
++		    if (dend == end_match_2)
++			d = dend;
++		    else
++		      {
++			d = string2;
++			dend = end_match_2;
++		      }
++		  }
++
++		len = weights[idx2];
++
++		for (workp2 = workp + equiv_class_length ; workp < workp2 ;
++		     workp++)
++		  {
++		    idx = (int32_t)*workp;
++		    /* We already checked idx != 0 in regex_compile. */
++
++		    if (idx2 != 0 && len == weights[idx])
++		      {
++			int cnt = 0;
++			while (cnt < len && (weights[idx + 1 + cnt]
++					     == weights[idx2 + 1 + cnt]))
++			  ++cnt;
++
++			if (cnt == len)
++			  goto char_set_matched;
++		      }
++		  }
++		/* not matched */
++                d = backup_d;
++                dend = backup_dend;
++	      }
++	    else /* (nrules == 0) */
++# endif
++	      /* If we can't look up collation data, we use wcscoll
++		 instead.  */
++	      {
++		for (workp2 = workp + equiv_class_length ; workp < workp2 ;)
++		  {
++		    const CHAR_T *backup_d = d, *backup_dend = dend;
++# ifdef _LIBC
++		    length = __wcslen (workp);
++# else
++		    length = wcslen (workp);
++# endif
++
++		    /* If wcscoll(the collating symbol, whole string) > 0,
++		       any substring of the string never match with the
++		       collating symbol.  */
++# ifdef _LIBC
++		    if (__wcscoll (workp, d) > 0)
++# else
++		    if (wcscoll (workp, d) > 0)
++# endif
++		      {
++			workp += length + 1;
++			break;
++		      }
++
++		    /* First, we compare the equivalence class with
++		       the first character of the string.
++		       If it don't match, we add the next character to
++		       the compare buffer in turn.  */
++		    for (i = 0 ; i < WORK_BUFFER_SIZE - 1 ; i++, d++)
++		      {
++			int match;
++			if (d == dend)
++			  {
++			    if (dend == end_match_2)
++			      break;
++			    d = string2;
++			    dend = end_match_2;
++			  }
++
++			/* add next character to the compare buffer.  */
++			str_buf[i] = TRANSLATE(*d);
++			str_buf[i+1] = '\0';
++
++# ifdef _LIBC
++			match = __wcscoll (workp, str_buf);
++# else
++			match = wcscoll (workp, str_buf);
++# endif
++
++			if (match == 0)
++			  goto char_set_matched;
++
++			if (match < 0)
++			/* (str_buf > workp) indicate (str_buf + X > workp),
++			   because for all X (str_buf + X > str_buf).
++			   So we don't need continue this loop.  */
++			  break;
++
++			/* Otherwise(str_buf < workp),
++			   (str_buf+next_character) may equals (workp).
++			   So we continue this loop.  */
++		      }
++		    /* not matched */
++		    d = backup_d;
++		    dend = backup_dend;
++		    workp += length + 1;
++		  }
++	      }
++
++            /* match with char_range?  */
++# ifdef _LIBC
++	    if (nrules != 0)
++	      {
++		uint32_t collseqval;
++		const char *collseq = (const char *)
++		  _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
++
++		collseqval = collseq_table_lookup (collseq, c);
++
++		for (; workp < p - chars_length ;)
++		  {
++		    uint32_t start_val, end_val;
++
++		    /* We already compute the collation sequence value
++		       of the characters (or collating symbols).  */
++		    start_val = (uint32_t) *workp++; /* range_start */
++		    end_val = (uint32_t) *workp++; /* range_end */
++
++		    if (start_val <= collseqval && collseqval <= end_val)
++		      goto char_set_matched;
++		  }
++	      }
++	    else
++# endif
++	      {
++		/* We set range_start_char at str_buf[0], range_end_char
++		   at str_buf[4], and compared char at str_buf[2].  */
++		str_buf[1] = 0;
++		str_buf[2] = c;
++		str_buf[3] = 0;
++		str_buf[5] = 0;
++		for (; workp < p - chars_length ;)
++		  {
++		    wchar_t *range_start_char, *range_end_char;
++
++		    /* match if (range_start_char <= c <= range_end_char).  */
++
++		    /* If range_start(or end) < 0, we assume -range_start(end)
++		       is the offset of the collating symbol which is specified
++		       as the character of the range start(end).  */
++
++		    /* range_start */
++		    if (*workp < 0)
++		      range_start_char = charset_top - (*workp++);
++		    else
++		      {
++			str_buf[0] = *workp++;
++			range_start_char = str_buf;
++		      }
++
++		    /* range_end */
++		    if (*workp < 0)
++		      range_end_char = charset_top - (*workp++);
++		    else
++		      {
++			str_buf[4] = *workp++;
++			range_end_char = str_buf + 4;
++		      }
++
++# ifdef _LIBC
++		    if (__wcscoll (range_start_char, str_buf+2) <= 0
++			&& __wcscoll (str_buf+2, range_end_char) <= 0)
++# else
++		    if (wcscoll (range_start_char, str_buf+2) <= 0
++			&& wcscoll (str_buf+2, range_end_char) <= 0)
++# endif
++		      goto char_set_matched;
++		  }
++	      }
++
++            /* match with char?  */
++	    for (; workp < p ; workp++)
++	      if (c == *workp)
++		goto char_set_matched;
++
++	    negate = !negate;
++
++	  char_set_matched:
++	    if (negate) goto fail;
++#else
++            /* Cast to `unsigned' instead of `unsigned char' in case the
++               bit list is a full 32 bytes long.  */
++	    if (c < (unsigned) (*p * BYTEWIDTH)
++		&& p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
++	      negate = !negate;
++
++	    p += 1 + *p;
++
++	    if (!negate) goto fail;
++#undef WORK_BUFFER_SIZE
++#endif /* WCHAR */
++	    SET_REGS_MATCHED ();
++            d++;
++	    break;
++	  }
++
++
++        /* The beginning of a group is represented by start_memory.
++           The arguments are the register number in the next byte, and the
++           number of groups inner to this one in the next.  The text
++           matched within the group is recorded (in the internal
++           registers data structure) under the register number.  */
++        case start_memory:
++	  DEBUG_PRINT3 ("EXECUTING start_memory %ld (%ld):\n",
++			(long int) *p, (long int) p[1]);
++
++          /* Find out if this group can match the empty string.  */
++	  p1 = p;		/* To send to group_match_null_string_p.  */
++
++          if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
++            REG_MATCH_NULL_STRING_P (reg_info[*p])
++              = PREFIX(group_match_null_string_p) (&p1, pend, reg_info);
++
++          /* Save the position in the string where we were the last time
++             we were at this open-group operator in case the group is
++             operated upon by a repetition operator, e.g., with `(a*)*b'
++             against `ab'; then we want to ignore where we are now in
++             the string in case this attempt to match fails.  */
++          old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
++                             ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
++                             : regstart[*p];
++	  DEBUG_PRINT2 ("  old_regstart: %d\n",
++			 POINTER_TO_OFFSET (old_regstart[*p]));
++
++          regstart[*p] = d;
++	  DEBUG_PRINT2 ("  regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
++
++          IS_ACTIVE (reg_info[*p]) = 1;
++          MATCHED_SOMETHING (reg_info[*p]) = 0;
++
++	  /* Clear this whenever we change the register activity status.  */
++	  set_regs_matched_done = 0;
++
++          /* This is the new highest active register.  */
++          highest_active_reg = *p;
++
++          /* If nothing was active before, this is the new lowest active
++             register.  */
++          if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
++            lowest_active_reg = *p;
++
++          /* Move past the register number and inner group count.  */
++          p += 2;
++	  just_past_start_mem = p;
++
++          break;
++
++
++        /* The stop_memory opcode represents the end of a group.  Its
++           arguments are the same as start_memory's: the register
++           number, and the number of inner groups.  */
++	case stop_memory:
++	  DEBUG_PRINT3 ("EXECUTING stop_memory %ld (%ld):\n",
++			(long int) *p, (long int) p[1]);
++
++          /* We need to save the string position the last time we were at
++             this close-group operator in case the group is operated
++             upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
++             against `aba'; then we want to ignore where we are now in
++             the string in case this attempt to match fails.  */
++          old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
++                           ? REG_UNSET (regend[*p]) ? d : regend[*p]
++			   : regend[*p];
++	  DEBUG_PRINT2 ("      old_regend: %d\n",
++			 POINTER_TO_OFFSET (old_regend[*p]));
++
++          regend[*p] = d;
++	  DEBUG_PRINT2 ("      regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
++
++          /* This register isn't active anymore.  */
++          IS_ACTIVE (reg_info[*p]) = 0;
++
++	  /* Clear this whenever we change the register activity status.  */
++	  set_regs_matched_done = 0;
++
++          /* If this was the only register active, nothing is active
++             anymore.  */
++          if (lowest_active_reg == highest_active_reg)
++            {
++              lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++              highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++            }
++          else
++            { /* We must scan for the new highest active register, since
++                 it isn't necessarily one less than now: consider
++                 (a(b)c(d(e)f)g).  When group 3 ends, after the f), the
++                 new highest active register is 1.  */
++              UCHAR_T r = *p - 1;
++              while (r > 0 && !IS_ACTIVE (reg_info[r]))
++                r--;
++
++              /* If we end up at register zero, that means that we saved
++                 the registers as the result of an `on_failure_jump', not
++                 a `start_memory', and we jumped to past the innermost
++                 `stop_memory'.  For example, in ((.)*) we save
++                 registers 1 and 2 as a result of the *, but when we pop
++                 back to the second ), we are at the stop_memory 1.
++                 Thus, nothing is active.  */
++	      if (r == 0)
++                {
++                  lowest_active_reg = NO_LOWEST_ACTIVE_REG;
++                  highest_active_reg = NO_HIGHEST_ACTIVE_REG;
++                }
++              else
++                highest_active_reg = r;
++            }
++
++          /* If just failed to match something this time around with a
++             group that's operated on by a repetition operator, try to
++             force exit from the ``loop'', and restore the register
++             information for this group that we had before trying this
++             last match.  */
++          if ((!MATCHED_SOMETHING (reg_info[*p])
++               || just_past_start_mem == p - 1)
++	      && (p + 2) < pend)
++            {
++              boolean is_a_jump_n = false;
++
++              p1 = p + 2;
++              mcnt = 0;
++              switch ((re_opcode_t) *p1++)
++                {
++                  case jump_n:
++		    is_a_jump_n = true;
++                  case pop_failure_jump:
++		  case maybe_pop_jump:
++		  case jump:
++		  case dummy_failure_jump:
++                    EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++		    if (is_a_jump_n)
++		      p1 += OFFSET_ADDRESS_SIZE;
++                    break;
++
++                  default:
++                    /* do nothing */ ;
++                }
++	      p1 += mcnt;
++
++              /* If the next operation is a jump backwards in the pattern
++	         to an on_failure_jump right before the start_memory
++                 corresponding to this stop_memory, exit from the loop
++                 by forcing a failure after pushing on the stack the
++                 on_failure_jump's jump in the pattern, and d.  */
++              if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
++                  && (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == start_memory
++		  && p1[2+OFFSET_ADDRESS_SIZE] == *p)
++		{
++                  /* If this group ever matched anything, then restore
++                     what its registers were before trying this last
++                     failed match, e.g., with `(a*)*b' against `ab' for
++                     regstart[1], and, e.g., with `((a*)*(b*)*)*'
++                     against `aba' for regend[3].
++
++                     Also restore the registers for inner groups for,
++                     e.g., `((a*)(b*))*' against `aba' (register 3 would
++                     otherwise get trashed).  */
++
++                  if (EVER_MATCHED_SOMETHING (reg_info[*p]))
++		    {
++		      unsigned r;
++
++                      EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
++
++		      /* Restore this and inner groups' (if any) registers.  */
++                      for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
++			   r++)
++                        {
++                          regstart[r] = old_regstart[r];
++
++                          /* xx why this test?  */
++                          if (old_regend[r] >= regstart[r])
++                            regend[r] = old_regend[r];
++                        }
++                    }
++		  p1++;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
++
++                  goto fail;
++                }
++            }
++
++          /* Move past the register number and the inner group count.  */
++          p += 2;
++          break;
++
++
++	/* \<digit> has been turned into a `duplicate' command which is
++           followed by the numeric value of <digit> as the register number.  */
++        case duplicate:
++	  {
++	    register const CHAR_T *d2, *dend2;
++	    int regno = *p++;   /* Get which register to match against.  */
++	    DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
++
++	    /* Can't back reference a group which we've never matched.  */
++            if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
++              goto fail;
++
++            /* Where in input to try to start matching.  */
++            d2 = regstart[regno];
++
++            /* Where to stop matching; if both the place to start and
++               the place to stop matching are in the same string, then
++               set to the place to stop, otherwise, for now have to use
++               the end of the first string.  */
++
++            dend2 = ((FIRST_STRING_P (regstart[regno])
++		      == FIRST_STRING_P (regend[regno]))
++		     ? regend[regno] : end_match_1);
++	    for (;;)
++	      {
++		/* If necessary, advance to next segment in register
++                   contents.  */
++		while (d2 == dend2)
++		  {
++		    if (dend2 == end_match_2) break;
++		    if (dend2 == regend[regno]) break;
++
++                    /* End of string1 => advance to string2. */
++                    d2 = string2;
++                    dend2 = regend[regno];
++		  }
++		/* At end of register contents => success */
++		if (d2 == dend2) break;
++
++		/* If necessary, advance to next segment in data.  */
++		PREFETCH ();
++
++		/* How many characters left in this segment to match.  */
++		mcnt = dend - d;
++
++		/* Want how many consecutive characters we can match in
++                   one shot, so, if necessary, adjust the count.  */
++                if (mcnt > dend2 - d2)
++		  mcnt = dend2 - d2;
++
++		/* Compare that many; failure if mismatch, else move
++                   past them.  */
++		if (translate
++                    ? PREFIX(bcmp_translate) (d, d2, mcnt, translate)
++                    : memcmp (d, d2, mcnt*sizeof(UCHAR_T)))
++		  goto fail;
++		d += mcnt, d2 += mcnt;
++
++		/* Do this because we've match some characters.  */
++		SET_REGS_MATCHED ();
++	      }
++	  }
++	  break;
++
++
++        /* begline matches the empty string at the beginning of the string
++           (unless `not_bol' is set in `bufp'), and, if
++           `newline_anchor' is set, after newlines.  */
++	case begline:
++          DEBUG_PRINT1 ("EXECUTING begline.\n");
++
++          if (AT_STRINGS_BEG (d))
++            {
++              if (!bufp->not_bol) break;
++            }
++          else if (d[-1] == '\n' && bufp->newline_anchor)
++            {
++              break;
++            }
++          /* In all other cases, we fail.  */
++          goto fail;
++
++
++        /* endline is the dual of begline.  */
++	case endline:
++          DEBUG_PRINT1 ("EXECUTING endline.\n");
++
++          if (AT_STRINGS_END (d))
++            {
++              if (!bufp->not_eol) break;
++            }
++
++          /* We have to ``prefetch'' the next character.  */
++          else if ((d == end1 ? *string2 : *d) == '\n'
++                   && bufp->newline_anchor)
++            {
++              break;
++            }
++          goto fail;
++
++
++	/* Match at the very beginning of the data.  */
++        case begbuf:
++          DEBUG_PRINT1 ("EXECUTING begbuf.\n");
++          if (AT_STRINGS_BEG (d))
++            break;
++          goto fail;
++
++
++	/* Match at the very end of the data.  */
++        case endbuf:
++          DEBUG_PRINT1 ("EXECUTING endbuf.\n");
++	  if (AT_STRINGS_END (d))
++	    break;
++          goto fail;
++
++
++        /* on_failure_keep_string_jump is used to optimize `.*\n'.  It
++           pushes NULL as the value for the string on the stack.  Then
++           `pop_failure_point' will keep the current value for the
++           string, instead of restoring it.  To see why, consider
++           matching `foo\nbar' against `.*\n'.  The .* matches the foo;
++           then the . fails against the \n.  But the next thing we want
++           to do is match the \n against the \n; if we restored the
++           string value, we would be back at the foo.
++
++           Because this is used only in specific cases, we don't need to
++           check all the things that `on_failure_jump' does, to make
++           sure the right things get saved on the stack.  Hence we don't
++           share its code.  The only reason to push anything on the
++           stack at all is that otherwise we would have to change
++           `anychar's code to do something besides goto fail in this
++           case; that seems worse than this.  */
++        case on_failure_keep_string_jump:
++          DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
++
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++          DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
++#else
++          DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
++#endif
++
++          PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
++          break;
++
++
++	/* Uses of on_failure_jump:
++
++           Each alternative starts with an on_failure_jump that points
++           to the beginning of the next alternative.  Each alternative
++           except the last ends with a jump that in effect jumps past
++           the rest of the alternatives.  (They really jump to the
++           ending jump of the following alternative, because tensioning
++           these jumps is a hassle.)
++
++           Repeats start with an on_failure_jump that points past both
++           the repetition text and either the following jump or
++           pop_failure_jump back to this on_failure_jump.  */
++	case on_failure_jump:
++        on_failure:
++          DEBUG_PRINT1 ("EXECUTING on_failure_jump");
++
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++          DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
++#else
++          DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
++#endif
++
++          /* If this on_failure_jump comes right before a group (i.e.,
++             the original * applied to a group), save the information
++             for that group and all inner ones, so that if we fail back
++             to this point, the group's information will be correct.
++             For example, in \(a*\)*\1, we need the preceding group,
++             and in \(zz\(a*\)b*\)\2, we need the inner group.  */
++
++          /* We can't use `p' to check ahead because we push
++             a failure point to `p + mcnt' after we do this.  */
++          p1 = p;
++
++          /* We need to skip no_op's before we look for the
++             start_memory in case this on_failure_jump is happening as
++             the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
++             against aba.  */
++          while (p1 < pend && (re_opcode_t) *p1 == no_op)
++            p1++;
++
++          if (p1 < pend && (re_opcode_t) *p1 == start_memory)
++            {
++              /* We have a new highest active register now.  This will
++                 get reset at the start_memory we are about to get to,
++                 but we will have saved all the registers relevant to
++                 this repetition op, as described above.  */
++              highest_active_reg = *(p1 + 1) + *(p1 + 2);
++              if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
++                lowest_active_reg = *(p1 + 1);
++            }
++
++          DEBUG_PRINT1 (":\n");
++          PUSH_FAILURE_POINT (p + mcnt, d, -2);
++          break;
++
++
++        /* A smart repeat ends with `maybe_pop_jump'.
++	   We change it to either `pop_failure_jump' or `jump'.  */
++        case maybe_pop_jump:
++          EXTRACT_NUMBER_AND_INCR (mcnt, p);
++          DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
++          {
++	    register UCHAR_T *p2 = p;
++
++            /* Compare the beginning of the repeat with what in the
++               pattern follows its end. If we can establish that there
++               is nothing that they would both match, i.e., that we
++               would have to backtrack because of (as in, e.g., `a*a')
++               then we can change to pop_failure_jump, because we'll
++               never have to backtrack.
++
++               This is not true in the case of alternatives: in
++               `(a|ab)*' we do need to backtrack to the `ab' alternative
++               (e.g., if the string was `ab').  But instead of trying to
++               detect that here, the alternative has put on a dummy
++               failure point which is what we will end up popping.  */
++
++	    /* Skip over open/close-group commands.
++	       If what follows this loop is a ...+ construct,
++	       look at what begins its body, since we will have to
++	       match at least one of that.  */
++	    while (1)
++	      {
++		if (p2 + 2 < pend
++		    && ((re_opcode_t) *p2 == stop_memory
++			|| (re_opcode_t) *p2 == start_memory))
++		  p2 += 3;
++		else if (p2 + 2 + 2 * OFFSET_ADDRESS_SIZE < pend
++			 && (re_opcode_t) *p2 == dummy_failure_jump)
++		  p2 += 2 + 2 * OFFSET_ADDRESS_SIZE;
++		else
++		  break;
++	      }
++
++	    p1 = p + mcnt;
++	    /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
++	       to the `maybe_finalize_jump' of this case.  Examine what
++	       follows.  */
++
++            /* If we're at the end of the pattern, we can change.  */
++            if (p2 == pend)
++	      {
++		/* Consider what happens when matching ":\(.*\)"
++		   against ":/".  I don't really understand this code
++		   yet.  */
++  	        p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
++		  pop_failure_jump;
++                DEBUG_PRINT1
++                  ("  End of pattern: change to `pop_failure_jump'.\n");
++              }
++
++            else if ((re_opcode_t) *p2 == exactn
++#ifdef MBS_SUPPORT
++		     || (re_opcode_t) *p2 == exactn_bin
++#endif
++		     || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
++	      {
++		register UCHAR_T c
++                  = *p2 == (UCHAR_T) endline ? '\n' : p2[2];
++
++                if (((re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn
++#ifdef MBS_SUPPORT
++		     || (re_opcode_t) p1[1+OFFSET_ADDRESS_SIZE] == exactn_bin
++#endif
++		    ) && p1[3+OFFSET_ADDRESS_SIZE] != c)
++                  {
++  		    p[-(1+OFFSET_ADDRESS_SIZE)] = (UCHAR_T)
++		      pop_failure_jump;
++#ifdef WCHAR
++		      DEBUG_PRINT3 ("  %C != %C => pop_failure_jump.\n",
++				    (wint_t) c,
++				    (wint_t) p1[3+OFFSET_ADDRESS_SIZE]);
++#else
++		      DEBUG_PRINT3 ("  %c != %c => pop_failure_jump.\n",
++				    (char) c,
++				    (char) p1[3+OFFSET_ADDRESS_SIZE]);
++#endif
++                  }
++
++#ifndef WCHAR
++		else if ((re_opcode_t) p1[3] == charset
++			 || (re_opcode_t) p1[3] == charset_not)
++		  {
++		    int negate = (re_opcode_t) p1[3] == charset_not;
++
++		    if (c < (unsigned) (p1[4] * BYTEWIDTH)
++			&& p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
++		      negate = !negate;
++
++                    /* `negate' is equal to 1 if c would match, which means
++                        that we can't change to pop_failure_jump.  */
++		    if (!negate)
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++#endif /* not WCHAR */
++	      }
++#ifndef WCHAR
++            else if ((re_opcode_t) *p2 == charset)
++	      {
++		/* We win if the first character of the loop is not part
++                   of the charset.  */
++                if ((re_opcode_t) p1[3] == exactn
++ 		    && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
++ 			  && (p2[2 + p1[5] / BYTEWIDTH]
++ 			      & (1 << (p1[5] % BYTEWIDTH)))))
++		  {
++		    p[-3] = (unsigned char) pop_failure_jump;
++		    DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                  }
++
++		else if ((re_opcode_t) p1[3] == charset_not)
++		  {
++		    int idx;
++		    /* We win if the charset_not inside the loop
++		       lists every character listed in the charset after.  */
++		    for (idx = 0; idx < (int) p2[1]; idx++)
++		      if (! (p2[2 + idx] == 0
++			     || (idx < (int) p1[4]
++				 && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
++			break;
++
++		    if (idx == p2[1])
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++		else if ((re_opcode_t) p1[3] == charset)
++		  {
++		    int idx;
++		    /* We win if the charset inside the loop
++		       has no overlap with the one after the loop.  */
++		    for (idx = 0;
++			 idx < (int) p2[1] && idx < (int) p1[4];
++			 idx++)
++		      if ((p2[2 + idx] & p1[5 + idx]) != 0)
++			break;
++
++		    if (idx == p2[1] || idx == p1[4])
++                      {
++  		        p[-3] = (unsigned char) pop_failure_jump;
++                        DEBUG_PRINT1 ("  No match => pop_failure_jump.\n");
++                      }
++		  }
++	      }
++#endif /* not WCHAR */
++	  }
++	  p -= OFFSET_ADDRESS_SIZE;	/* Point at relative address again.  */
++	  if ((re_opcode_t) p[-1] != pop_failure_jump)
++	    {
++	      p[-1] = (UCHAR_T) jump;
++              DEBUG_PRINT1 ("  Match => jump.\n");
++	      goto unconditional_jump;
++	    }
++        /* Note fall through.  */
++
++
++	/* The end of a simple repeat has a pop_failure_jump back to
++           its matching on_failure_jump, where the latter will push a
++           failure point.  The pop_failure_jump takes off failure
++           points put on by this pop_failure_jump's matching
++           on_failure_jump; we got through the pattern to here from the
++           matching on_failure_jump, so didn't fail.  */
++        case pop_failure_jump:
++          {
++            /* We need to pass separate storage for the lowest and
++               highest registers, even though we don't care about the
++               actual values.  Otherwise, we will restore only one
++               register from the stack, since lowest will == highest in
++               `pop_failure_point'.  */
++            active_reg_t dummy_low_reg, dummy_high_reg;
++            UCHAR_T *pdummy = NULL;
++            const CHAR_T *sdummy = NULL;
++
++            DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
++            POP_FAILURE_POINT (sdummy, pdummy,
++                               dummy_low_reg, dummy_high_reg,
++                               reg_dummy, reg_dummy, reg_info_dummy);
++          }
++	  /* Note fall through.  */
++
++	unconditional_jump:
++#ifdef _LIBC
++	  DEBUG_PRINT2 ("\n%p: ", p);
++#else
++	  DEBUG_PRINT2 ("\n0x%x: ", p);
++#endif
++          /* Note fall through.  */
++
++        /* Unconditionally jump (without popping any failure points).  */
++        case jump:
++	  EXTRACT_NUMBER_AND_INCR (mcnt, p);	/* Get the amount to jump.  */
++          DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
++	  p += mcnt;				/* Do the jump.  */
++#ifdef _LIBC
++          DEBUG_PRINT2 ("(to %p).\n", p);
++#else
++          DEBUG_PRINT2 ("(to 0x%x).\n", p);
++#endif
++	  break;
++
++
++        /* We need this opcode so we can detect where alternatives end
++           in `group_match_null_string_p' et al.  */
++        case jump_past_alt:
++          DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
++          goto unconditional_jump;
++
++
++        /* Normally, the on_failure_jump pushes a failure point, which
++           then gets popped at pop_failure_jump.  We will end up at
++           pop_failure_jump, also, and with a pattern of, say, `a+', we
++           are skipping over the on_failure_jump, so we have to push
++           something meaningless for pop_failure_jump to pop.  */
++        case dummy_failure_jump:
++          DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
++          /* It doesn't matter what we push for the string here.  What
++             the code at `fail' tests is the value for the pattern.  */
++          PUSH_FAILURE_POINT (NULL, NULL, -2);
++          goto unconditional_jump;
++
++
++        /* At the end of an alternative, we need to push a dummy failure
++           point in case we are followed by a `pop_failure_jump', because
++           we don't want the failure point for the alternative to be
++           popped.  For example, matching `(a|ab)*' against `aab'
++           requires that we match the `ab' alternative.  */
++        case push_dummy_failure:
++          DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
++          /* See comments just above at `dummy_failure_jump' about the
++             two zeroes.  */
++          PUSH_FAILURE_POINT (NULL, NULL, -2);
++          break;
++
++        /* Have to succeed matching what follows at least n times.
++           After that, handle like `on_failure_jump'.  */
++        case succeed_n:
++          EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
++          DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
++
++          assert (mcnt >= 0);
++          /* Originally, this is how many times we HAVE to succeed.  */
++          if (mcnt > 0)
++            {
++               mcnt--;
++	       p += OFFSET_ADDRESS_SIZE;
++               STORE_NUMBER_AND_INCR (p, mcnt);
++#ifdef _LIBC
++               DEBUG_PRINT3 ("  Setting %p to %d.\n", p - OFFSET_ADDRESS_SIZE
++			     , mcnt);
++#else
++               DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p - OFFSET_ADDRESS_SIZE
++			     , mcnt);
++#endif
++            }
++	  else if (mcnt == 0)
++            {
++#ifdef _LIBC
++              DEBUG_PRINT2 ("  Setting two bytes from %p to no_op.\n",
++			    p + OFFSET_ADDRESS_SIZE);
++#else
++              DEBUG_PRINT2 ("  Setting two bytes from 0x%x to no_op.\n",
++			    p + OFFSET_ADDRESS_SIZE);
++#endif /* _LIBC */
++
++#ifdef WCHAR
++	      p[1] = (UCHAR_T) no_op;
++#else
++	      p[2] = (UCHAR_T) no_op;
++              p[3] = (UCHAR_T) no_op;
++#endif /* WCHAR */
++              goto on_failure;
++            }
++          break;
++
++        case jump_n:
++          EXTRACT_NUMBER (mcnt, p + OFFSET_ADDRESS_SIZE);
++          DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
++
++          /* Originally, this is how many times we CAN jump.  */
++          if (mcnt)
++            {
++               mcnt--;
++               STORE_NUMBER (p + OFFSET_ADDRESS_SIZE, mcnt);
++
++#ifdef _LIBC
++               DEBUG_PRINT3 ("  Setting %p to %d.\n", p + OFFSET_ADDRESS_SIZE,
++			     mcnt);
++#else
++               DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p + OFFSET_ADDRESS_SIZE,
++			     mcnt);
++#endif /* _LIBC */
++	       goto unconditional_jump;
++            }
++          /* If don't have to jump any more, skip over the rest of command.  */
++	  else
++	    p += 2 * OFFSET_ADDRESS_SIZE;
++          break;
++
++	case set_number_at:
++	  {
++            DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
++
++            EXTRACT_NUMBER_AND_INCR (mcnt, p);
++            p1 = p + mcnt;
++            EXTRACT_NUMBER_AND_INCR (mcnt, p);
++#ifdef _LIBC
++            DEBUG_PRINT3 ("  Setting %p to %d.\n", p1, mcnt);
++#else
++            DEBUG_PRINT3 ("  Setting 0x%x to %d.\n", p1, mcnt);
++#endif
++	    STORE_NUMBER (p1, mcnt);
++            break;
++          }
++
++#if 0
++	/* The DEC Alpha C compiler 3.x generates incorrect code for the
++	   test  WORDCHAR_P (d - 1) != WORDCHAR_P (d)  in the expansion of
++	   AT_WORD_BOUNDARY, so this code is disabled.  Expanding the
++	   macro and introducing temporary variables works around the bug.  */
++
++	case wordbound:
++	  DEBUG_PRINT1 ("EXECUTING wordbound.\n");
++	  if (AT_WORD_BOUNDARY (d))
++	    break;
++	  goto fail;
++
++	case notwordbound:
++	  DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
++	  if (AT_WORD_BOUNDARY (d))
++	    goto fail;
++	  break;
++#else
++	case wordbound:
++	{
++	  boolean prevchar, thischar;
++
++	  DEBUG_PRINT1 ("EXECUTING wordbound.\n");
++	  if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
++	    break;
++
++	  prevchar = WORDCHAR_P (d - 1);
++	  thischar = WORDCHAR_P (d);
++	  if (prevchar != thischar)
++	    break;
++	  goto fail;
++	}
++
++      case notwordbound:
++	{
++	  boolean prevchar, thischar;
++
++	  DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
++	  if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
++	    goto fail;
++
++	  prevchar = WORDCHAR_P (d - 1);
++	  thischar = WORDCHAR_P (d);
++	  if (prevchar != thischar)
++	    goto fail;
++	  break;
++	}
++#endif
++
++	case wordbeg:
++          DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
++	  if (!AT_STRINGS_END (d) && WORDCHAR_P (d)
++	      && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
++	    break;
++          goto fail;
++
++	case wordend:
++          DEBUG_PRINT1 ("EXECUTING wordend.\n");
++	  if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
++              && (AT_STRINGS_END (d) || !WORDCHAR_P (d)))
++	    break;
++          goto fail;
++
++#ifdef emacs
++  	case before_dot:
++          DEBUG_PRINT1 ("EXECUTING before_dot.\n");
++ 	  if (PTR_CHAR_POS ((unsigned char *) d) >= point)
++  	    goto fail;
++  	  break;
++
++  	case at_dot:
++          DEBUG_PRINT1 ("EXECUTING at_dot.\n");
++ 	  if (PTR_CHAR_POS ((unsigned char *) d) != point)
++  	    goto fail;
++  	  break;
++
++  	case after_dot:
++          DEBUG_PRINT1 ("EXECUTING after_dot.\n");
++          if (PTR_CHAR_POS ((unsigned char *) d) <= point)
++  	    goto fail;
++  	  break;
++
++	case syntaxspec:
++          DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
++	  mcnt = *p++;
++	  goto matchsyntax;
++
++        case wordchar:
++          DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
++	  mcnt = (int) Sword;
++        matchsyntax:
++	  PREFETCH ();
++	  /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
++	  d++;
++	  if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
++	    goto fail;
++          SET_REGS_MATCHED ();
++	  break;
++
++	case notsyntaxspec:
++          DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
++	  mcnt = *p++;
++	  goto matchnotsyntax;
++
++        case notwordchar:
++          DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
++	  mcnt = (int) Sword;
++        matchnotsyntax:
++	  PREFETCH ();
++	  /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
++	  d++;
++	  if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
++	    goto fail;
++	  SET_REGS_MATCHED ();
++          break;
++
++#else /* not emacs */
++	case wordchar:
++          DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
++	  PREFETCH ();
++          if (!WORDCHAR_P (d))
++            goto fail;
++	  SET_REGS_MATCHED ();
++          d++;
++	  break;
++
++	case notwordchar:
++          DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
++	  PREFETCH ();
++	  if (WORDCHAR_P (d))
++            goto fail;
++          SET_REGS_MATCHED ();
++          d++;
++	  break;
++#endif /* not emacs */
++
++        default:
++          abort ();
++	}
++      continue;  /* Successfully executed one pattern command; keep going.  */
++
++
++    /* We goto here if a matching operation fails. */
++    fail:
++      if (!FAIL_STACK_EMPTY ())
++	{ /* A restart point is known.  Restore to that state.  */
++          DEBUG_PRINT1 ("\nFAIL:\n");
++          POP_FAILURE_POINT (d, p,
++                             lowest_active_reg, highest_active_reg,
++                             regstart, regend, reg_info);
++
++          /* If this failure point is a dummy, try the next one.  */
++          if (!p)
++	    goto fail;
++
++          /* If we failed to the end of the pattern, don't examine *p.  */
++	  assert (p <= pend);
++          if (p < pend)
++            {
++              boolean is_a_jump_n = false;
++
++              /* If failed to a backwards jump that's part of a repetition
++                 loop, need to pop this failure point and use the next one.  */
++              switch ((re_opcode_t) *p)
++                {
++                case jump_n:
++                  is_a_jump_n = true;
++                case maybe_pop_jump:
++                case pop_failure_jump:
++                case jump:
++                  p1 = p + 1;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  p1 += mcnt;
++
++                  if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
++                      || (!is_a_jump_n
++                          && (re_opcode_t) *p1 == on_failure_jump))
++                    goto fail;
++                  break;
++                default:
++                  /* do nothing */ ;
++                }
++            }
++
++          if (d >= string1 && d <= end1)
++	    dend = end_match_1;
++        }
++      else
++        break;   /* Matching at this starting point really fails.  */
++    } /* for (;;) */
++
++  if (best_regs_set)
++    goto restore_best_regs;
++
++  FREE_VARIABLES ();
++
++  return -1;         			/* Failure to match.  */
++} /* re_match_2 */
++\f
++/* Subroutine definitions for re_match_2.  */
++
++
++/* We are passed P pointing to a register number after a start_memory.
++
++   Return true if the pattern up to the corresponding stop_memory can
++   match the empty string, and false otherwise.
++
++   If we find the matching stop_memory, sets P to point to one past its number.
++   Otherwise, sets P to an undefined byte less than or equal to END.
++
++   We don't handle duplicates properly (yet).  */
++
++static boolean
++PREFIX(group_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
++                                   PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  /* Point to after the args to the start_memory.  */
++  UCHAR_T *p1 = *p + 2;
++
++  while (p1 < end)
++    {
++      /* Skip over opcodes that can match nothing, and return true or
++	 false, as appropriate, when we get to one that can't, or to the
++         matching stop_memory.  */
++
++      switch ((re_opcode_t) *p1)
++        {
++        /* Could be either a loop or a series of alternatives.  */
++        case on_failure_jump:
++          p1++;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++
++          /* If the next operation is not a jump backwards in the
++	     pattern.  */
++
++	  if (mcnt >= 0)
++	    {
++              /* Go through the on_failure_jumps of the alternatives,
++                 seeing if any of the alternatives cannot match nothing.
++                 The last alternative starts with only a jump,
++                 whereas the rest start with on_failure_jump and end
++                 with a jump, e.g., here is the pattern for `a|b|c':
++
++                 /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
++                 /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
++                 /exactn/1/c
++
++                 So, we have to first go through the first (n-1)
++                 alternatives and then deal with the last one separately.  */
++
++
++              /* Deal with the first (n-1) alternatives, which start
++                 with an on_failure_jump (see above) that jumps to right
++                 past a jump_past_alt.  */
++
++              while ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] ==
++		     jump_past_alt)
++                {
++                  /* `mcnt' holds how many bytes long the alternative
++                     is, including the ending `jump_past_alt' and
++                     its number.  */
++
++                  if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt -
++						(1 + OFFSET_ADDRESS_SIZE),
++						reg_info))
++                    return false;
++
++                  /* Move to right after this alternative, including the
++		     jump_past_alt.  */
++                  p1 += mcnt;
++
++                  /* Break if it's the beginning of an n-th alternative
++                     that doesn't begin with an on_failure_jump.  */
++                  if ((re_opcode_t) *p1 != on_failure_jump)
++                    break;
++
++		  /* Still have to check that it's not an n-th
++		     alternative that starts with an on_failure_jump.  */
++		  p1++;
++                  EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++                  if ((re_opcode_t) p1[mcnt-(1+OFFSET_ADDRESS_SIZE)] !=
++		      jump_past_alt)
++                    {
++		      /* Get to the beginning of the n-th alternative.  */
++                      p1 -= 1 + OFFSET_ADDRESS_SIZE;
++                      break;
++                    }
++                }
++
++              /* Deal with the last alternative: go back and get number
++                 of the `jump_past_alt' just before it.  `mcnt' contains
++                 the length of the alternative.  */
++              EXTRACT_NUMBER (mcnt, p1 - OFFSET_ADDRESS_SIZE);
++
++              if (!PREFIX(alt_match_null_string_p) (p1, p1 + mcnt, reg_info))
++                return false;
++
++              p1 += mcnt;	/* Get past the n-th alternative.  */
++            } /* if mcnt > 0 */
++          break;
++
++
++        case stop_memory:
++	  assert (p1[1] == **p);
++          *p = p1 + 2;
++          return true;
++
++
++        default:
++          if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
++            return false;
++        }
++    } /* while p1 < end */
++
++  return false;
++} /* group_match_null_string_p */
++
++
++/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
++   It expects P to be the first byte of a single alternative and END one
++   byte past the last. The alternative can contain groups.  */
++
++static boolean
++PREFIX(alt_match_null_string_p) (UCHAR_T *p, UCHAR_T *end,
++                                 PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  UCHAR_T *p1 = p;
++
++  while (p1 < end)
++    {
++      /* Skip over opcodes that can match nothing, and break when we get
++         to one that can't.  */
++
++      switch ((re_opcode_t) *p1)
++        {
++	/* It's a loop.  */
++        case on_failure_jump:
++          p1++;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++          p1 += mcnt;
++          break;
++
++	default:
++          if (!PREFIX(common_op_match_null_string_p) (&p1, end, reg_info))
++            return false;
++        }
++    }  /* while p1 < end */
++
++  return true;
++} /* alt_match_null_string_p */
++
++
++/* Deals with the ops common to group_match_null_string_p and
++   alt_match_null_string_p.
++
++   Sets P to one after the op and its arguments, if any.  */
++
++static boolean
++PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
++                                       PREFIX(register_info_type) *reg_info)
++{
++  int mcnt;
++  boolean ret;
++  int reg_no;
++  UCHAR_T *p1 = *p;
++
++  switch ((re_opcode_t) *p1++)
++    {
++    case no_op:
++    case begline:
++    case endline:
++    case begbuf:
++    case endbuf:
++    case wordbeg:
++    case wordend:
++    case wordbound:
++    case notwordbound:
++#ifdef emacs
++    case before_dot:
++    case at_dot:
++    case after_dot:
++#endif
++      break;
++
++    case start_memory:
++      reg_no = *p1;
++      assert (reg_no > 0 && reg_no <= MAX_REGNUM);
++      ret = PREFIX(group_match_null_string_p) (&p1, end, reg_info);
++
++      /* Have to set this here in case we're checking a group which
++         contains a group and a back reference to it.  */
++
++      if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
++        REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
++
++      if (!ret)
++        return false;
++      break;
++
++    /* If this is an optimized succeed_n for zero times, make the jump.  */
++    case jump:
++      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++      if (mcnt >= 0)
++        p1 += mcnt;
++      else
++        return false;
++      break;
++
++    case succeed_n:
++      /* Get to the number of times to succeed.  */
++      p1 += OFFSET_ADDRESS_SIZE;
++      EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++
++      if (mcnt == 0)
++        {
++          p1 -= 2 * OFFSET_ADDRESS_SIZE;
++          EXTRACT_NUMBER_AND_INCR (mcnt, p1);
++          p1 += mcnt;
++        }
++      else
++        return false;
++      break;
++
++    case duplicate:
++      if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
++        return false;
++      break;
++
++    case set_number_at:
++      p1 += 2 * OFFSET_ADDRESS_SIZE;
++
++    default:
++      /* All other opcodes mean we cannot match the empty string.  */
++      return false;
++  }
++
++  *p = p1;
++  return true;
++} /* common_op_match_null_string_p */
++
++
++/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
++   bytes; nonzero otherwise.  */
++
++static int
++PREFIX(bcmp_translate) (const CHAR_T *s1, const CHAR_T *s2, register int len,
++                        RE_TRANSLATE_TYPE translate)
++{
++  register const UCHAR_T *p1 = (const UCHAR_T *) s1;
++  register const UCHAR_T *p2 = (const UCHAR_T *) s2;
++  while (len)
++    {
++#ifdef WCHAR
++      if (((*p1<=0xff)?translate[*p1++]:*p1++)
++	  != ((*p2<=0xff)?translate[*p2++]:*p2++))
++	return 1;
++#else /* BYTE */
++      if (translate[*p1++] != translate[*p2++]) return 1;
++#endif /* WCHAR */
++      len--;
++    }
++  return 0;
++}
++\f
++
++#else /* not INSIDE_RECURSION */
++
++/* Entry points for GNU code.  */
++
++/* re_compile_pattern is the GNU regular expression compiler: it
++   compiles PATTERN (of length SIZE) and puts the result in BUFP.
++   Returns 0 if the pattern was valid, otherwise an error string.
++
++   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
++   are set in BUFP on entry.
++
++   We call regex_compile to do the actual compilation.  */
++
++const char *
++re_compile_pattern (const char *pattern, size_t length,
++                    struct re_pattern_buffer *bufp)
++{
++  reg_errcode_t ret;
++
++  /* GNU code is written to assume at least RE_NREGS registers will be set
++     (and at least one extra will be -1).  */
++  bufp->regs_allocated = REGS_UNALLOCATED;
++
++  /* And GNU code determines whether or not to get register information
++     by passing null for the REGS argument to re_match, etc., not by
++     setting no_sub.  */
++  bufp->no_sub = 0;
++
++  /* Match anchors at newline.  */
++  bufp->newline_anchor = 1;
++
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (pattern, length, re_syntax_options, bufp);
++  else
++# endif
++    ret = byte_regex_compile (pattern, length, re_syntax_options, bufp);
++
++  if (!ret)
++    return NULL;
++  return gettext (re_error_msgid[(int) ret]);
++}
++#ifdef _LIBC
++weak_alias (__re_compile_pattern, re_compile_pattern)
++#endif
++\f
++/* Entry points compatible with 4.2 BSD regex library.  We don't define
++   them unless specifically requested.  */
++
++#if defined _REGEX_RE_COMP || defined _LIBC
++
++/* BSD has one and only one pattern buffer.  */
++static struct re_pattern_buffer re_comp_buf;
++
++char *
++#ifdef _LIBC
++/* Make these definitions weak in libc, so POSIX programs can redefine
++   these names if they don't use our functions, and still use
++   regcomp/regexec below without link errors.  */
++weak_function
++#endif
++re_comp (const char *s)
++{
++  reg_errcode_t ret;
++
++  if (!s)
++    {
++      if (!re_comp_buf.buffer)
++	return (char *) gettext ("No previous regular expression");
++      return 0;
++    }
++
++  if (!re_comp_buf.buffer)
++    {
++      re_comp_buf.buffer = (unsigned char *) malloc (200);
++      if (re_comp_buf.buffer == NULL)
++        return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
++      re_comp_buf.allocated = 200;
++
++      re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
++      if (re_comp_buf.fastmap == NULL)
++	return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
++    }
++
++  /* Since `re_exec' always passes NULL for the `regs' argument, we
++     don't need to initialize the pattern buffer fields which affect it.  */
++
++  /* Match anchors at newlines.  */
++  re_comp_buf.newline_anchor = 1;
++
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
++  else
++# endif
++    ret = byte_regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
++
++  if (!ret)
++    return NULL;
++
++  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
++  return (char *) gettext (re_error_msgid[(int) ret]);
++}
++
++
++int
++#ifdef _LIBC
++weak_function
++#endif
++re_exec (const char *s)
++{
++  const int len = strlen (s);
++  return
++    0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
++}
++
++#endif /* _REGEX_RE_COMP */
++\f
++/* POSIX.2 functions.  Don't define these for Emacs.  */
++
++#ifndef emacs
++
++/* regcomp takes a regular expression as a string and compiles it.
++
++   PREG is a regex_t *.  We do not expect any fields to be initialized,
++   since POSIX says we shouldn't.  Thus, we set
++
++     `buffer' to the compiled pattern;
++     `used' to the length of the compiled pattern;
++     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
++       REG_EXTENDED bit in CFLAGS is set; otherwise, to
++       RE_SYNTAX_POSIX_BASIC;
++     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
++     `fastmap' to an allocated space for the fastmap;
++     `fastmap_accurate' to zero;
++     `re_nsub' to the number of subexpressions in PATTERN.
++
++   PATTERN is the address of the pattern string.
++
++   CFLAGS is a series of bits which affect compilation.
++
++     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
++     use POSIX basic syntax.
++
++     If REG_NEWLINE is set, then . and [^...] don't match newline.
++     Also, regexec will try a match beginning after every newline.
++
++     If REG_ICASE is set, then we considers upper- and lowercase
++     versions of letters to be equivalent when matching.
++
++     If REG_NOSUB is set, then when PREG is passed to regexec, that
++     routine will report only success or failure, and nothing about the
++     registers.
++
++   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
++   the return codes and their meanings.)  */
++
++int
++regcomp (regex_t *preg, const char *pattern, int cflags)
++{
++  reg_errcode_t ret;
++  reg_syntax_t syntax
++    = (cflags & REG_EXTENDED) ?
++      RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
++
++  /* regex_compile will allocate the space for the compiled pattern.  */
++  preg->buffer = 0;
++  preg->allocated = 0;
++  preg->used = 0;
++
++  /* Try to allocate space for the fastmap.  */
++  preg->fastmap = (char *) malloc (1 << BYTEWIDTH);
++
++  if (cflags & REG_ICASE)
++    {
++      int i;
++
++      preg->translate
++	= (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
++				      * sizeof (*(RE_TRANSLATE_TYPE)0));
++      if (preg->translate == NULL)
++        return (int) REG_ESPACE;
++
++      /* Map uppercase characters to corresponding lowercase ones.  */
++      for (i = 0; i < CHAR_SET_SIZE; i++)
++        preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i;
++    }
++  else
++    preg->translate = NULL;
++
++  /* If REG_NEWLINE is set, newlines are treated differently.  */
++  if (cflags & REG_NEWLINE)
++    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
++      syntax &= ~RE_DOT_NEWLINE;
++      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
++      /* It also changes the matching behavior.  */
++      preg->newline_anchor = 1;
++    }
++  else
++    preg->newline_anchor = 0;
++
++  preg->no_sub = !!(cflags & REG_NOSUB);
++
++  /* POSIX says a null character in the pattern terminates it, so we
++     can use strlen here in compiling the pattern.  */
++# ifdef MBS_SUPPORT
++  if (MB_CUR_MAX != 1)
++    ret = wcs_regex_compile (pattern, strlen (pattern), syntax, preg);
++  else
++# endif
++    ret = byte_regex_compile (pattern, strlen (pattern), syntax, preg);
++
++  /* POSIX doesn't distinguish between an unmatched open-group and an
++     unmatched close-group: both are REG_EPAREN.  */
++  if (ret == REG_ERPAREN) ret = REG_EPAREN;
++
++  if (ret == REG_NOERROR && preg->fastmap)
++    {
++      /* Compute the fastmap now, since regexec cannot modify the pattern
++	 buffer.  */
++      if (re_compile_fastmap (preg) == -2)
++	{
++	  /* Some error occurred while computing the fastmap, just forget
++	     about it.  */
++	  free (preg->fastmap);
++	  preg->fastmap = NULL;
++	}
++    }
++
++  return (int) ret;
++}
++#ifdef _LIBC
++weak_alias (__regcomp, regcomp)
++#endif
++
++
++/* regexec searches for a given pattern, specified by PREG, in the
++   string STRING.
++
++   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
++   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
++   least NMATCH elements, and we set them to the offsets of the
++   corresponding matched substrings.
++
++   EFLAGS specifies `execution flags' which affect matching: if
++   REG_NOTBOL is set, then ^ does not match at the beginning of the
++   string; if REG_NOTEOL is set, then $ does not match at the end.
++
++   We return 0 if we find a match and REG_NOMATCH if not.  */
++
++int
++regexec (const regex_t *preg, const char *string, size_t nmatch,
++         regmatch_t pmatch[], int eflags)
++{
++  int ret;
++  struct re_registers regs;
++  regex_t private_preg;
++  int len = strlen (string);
++  boolean want_reg_info = !preg->no_sub && nmatch > 0;
++
++  private_preg = *preg;
++
++  private_preg.not_bol = !!(eflags & REG_NOTBOL);
++  private_preg.not_eol = !!(eflags & REG_NOTEOL);
++
++  /* The user has told us exactly how many registers to return
++     information about, via `nmatch'.  We have to pass that on to the
++     matching routines.  */
++  private_preg.regs_allocated = REGS_FIXED;
++
++  if (want_reg_info)
++    {
++      regs.num_regs = nmatch;
++      regs.start = TALLOC (nmatch * 2, regoff_t);
++      if (regs.start == NULL)
++        return (int) REG_NOMATCH;
++      regs.end = regs.start + nmatch;
++    }
++
++  /* Perform the searching operation.  */
++  ret = re_search (&private_preg, string, len,
++                   /* start: */ 0, /* range: */ len,
++                   want_reg_info ? &regs : (struct re_registers *) 0);
++
++  /* Copy the register information to the POSIX structure.  */
++  if (want_reg_info)
++    {
++      if (ret >= 0)
++        {
++          unsigned r;
++
++          for (r = 0; r < nmatch; r++)
++            {
++              pmatch[r].rm_so = regs.start[r];
++              pmatch[r].rm_eo = regs.end[r];
++            }
++        }
++
++      /* If we needed the temporary register info, free the space now.  */
++      free (regs.start);
++    }
++
++  /* We want zero return to mean success, unlike `re_search'.  */
++  return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
++}
++#ifdef _LIBC
++/* EGLIBC: This is handled in regexec-compat.c.  */
++/*weak_alias (__regexec, regexec)*/
++#include "regexec-compat.c"
++#endif
++
++
++/* Returns a message corresponding to an error code, ERRCODE, returned
++   from either regcomp or regexec.   We don't use PREG here.  */
++
++size_t
++regerror (int errcode, const regex_t *preg __attribute__ ((unused)),
++          char *errbuf, size_t errbuf_size)
++{
++  const char *msg;
++  size_t msg_size;
++
++  if (errcode < 0
++      || errcode >= (int) (sizeof (re_error_msgid)
++			   / sizeof (re_error_msgid[0])))
++    /* Only error codes returned by the rest of the code should be passed
++       to this routine.  If we are given anything else, or if other regex
++       code generates an invalid error code, then the program has a bug.
++       Dump core so we can fix it.  */
++    abort ();
++
++  msg = gettext (re_error_msgid[errcode]);
++
++  msg_size = strlen (msg) + 1; /* Includes the null.  */
++
++  if (errbuf_size != 0)
++    {
++      if (msg_size > errbuf_size)
++        {
++#if defined HAVE_MEMPCPY || defined _LIBC
++	  *((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
++#else
++          memcpy (errbuf, msg, errbuf_size - 1);
++          errbuf[errbuf_size - 1] = 0;
++#endif
++        }
++      else
++        memcpy (errbuf, msg, msg_size);
++    }
++
++  return msg_size;
++}
++#ifdef _LIBC
++weak_alias (__regerror, regerror)
++#endif
++
++
++/* Free dynamically allocated space used by PREG.  */
++
++void
++regfree (regex_t *preg)
++{
++  if (preg->buffer != NULL)
++    free (preg->buffer);
++  preg->buffer = NULL;
++
++  preg->allocated = 0;
++  preg->used = 0;
++
++  if (preg->fastmap != NULL)
++    free (preg->fastmap);
++  preg->fastmap = NULL;
++  preg->fastmap_accurate = 0;
++
++  if (preg->translate != NULL)
++    free (preg->translate);
++  preg->translate = NULL;
++}
++#ifdef _LIBC
++weak_alias (__regfree, regfree)
++#endif
++
++#endif /* not emacs  */
++
++#endif /* not INSIDE_RECURSION */
++
++\f
++#undef STORE_NUMBER
++#undef STORE_NUMBER_AND_INCR
++#undef EXTRACT_NUMBER
++#undef EXTRACT_NUMBER_AND_INCR
++
++#undef DEBUG_PRINT_COMPILED_PATTERN
++#undef DEBUG_PRINT_DOUBLE_STRING
++
++#undef INIT_FAIL_STACK
++#undef RESET_FAIL_STACK
++#undef DOUBLE_FAIL_STACK
++#undef PUSH_PATTERN_OP
++#undef PUSH_FAILURE_POINTER
++#undef PUSH_FAILURE_INT
++#undef PUSH_FAILURE_ELT
++#undef POP_FAILURE_POINTER
++#undef POP_FAILURE_INT
++#undef POP_FAILURE_ELT
++#undef DEBUG_PUSH
++#undef DEBUG_POP
++#undef PUSH_FAILURE_POINT
++#undef POP_FAILURE_POINT
++
++#undef REG_UNSET_VALUE
++#undef REG_UNSET
++
++#undef PATFETCH
++#undef PATFETCH_RAW
++#undef PATUNFETCH
++#undef TRANSLATE
++
++#undef INIT_BUF_SIZE
++#undef GET_BUFFER_SPACE
++#undef BUF_PUSH
++#undef BUF_PUSH_2
++#undef BUF_PUSH_3
++#undef STORE_JUMP
++#undef STORE_JUMP2
++#undef INSERT_JUMP
++#undef INSERT_JUMP2
++#undef EXTEND_BUFFER
++#undef GET_UNSIGNED_NUMBER
++#undef FREE_STACK_RETURN
++
++# undef POINTER_TO_OFFSET
++# undef MATCHING_IN_FRST_STRING
++# undef PREFETCH
++# undef AT_STRINGS_BEG
++# undef AT_STRINGS_END
++# undef WORDCHAR_P
++# undef FREE_VAR
++# undef FREE_VARIABLES
++# undef NO_HIGHEST_ACTIVE_REG
++# undef NO_LOWEST_ACTIVE_REG
++
++# undef CHAR_T
++# undef UCHAR_T
++# undef COMPILED_BUFFER_VAR
++# undef OFFSET_ADDRESS_SIZE
++# undef CHAR_CLASS_SIZE
++# undef PREFIX
++# undef ARG_PREFIX
++# undef PUT_CHAR
++# undef BYTE
++# undef WCHAR
++
++# define DEFINED_ONCE
+Index: git/pwd/Makefile
+===================================================================
+--- git.orig/pwd/Makefile	2014-08-29 20:00:53.316070587 -0700
++++ git/pwd/Makefile	2014-08-29 20:01:15.232070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for pwd portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= pwd
+ 
+ include ../Makeconfig
+Index: git/resolv/Makefile
+===================================================================
+--- git.orig/resolv/Makefile	2014-08-29 20:00:53.320070587 -0700
++++ git/resolv/Makefile	2014-08-29 20:01:15.232070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for resolv portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= resolv
+ 
+ include ../Makeconfig
+@@ -27,20 +29,21 @@
+ 	   arpa/nameser.h arpa/nameser_compat.h \
+ 	   sys/bitypes.h
+ 
+-routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
+-	    res_hconf res_libc res-state
++routines-$(OPTION_EGLIBC_INET) \
++	+= herror inet_addr inet_ntop inet_pton nsap_addr res_init \
++	   res_hconf res_libc res-state
+ 
+-tests = tst-aton tst-leaks tst-inet_ntop
+-xtests = tst-leaks2
++tests-$(OPTION_EGLIBC_INET) += tst-aton tst-leaks tst-inet_ntop
++xtests-$(OPTION_EGLIBC_INET) += tst-leaks2
+ 
+ generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
+ 
+-extra-libs := libresolv libnss_dns
++extra-libs-$(OPTION_EGLIBC_INET) += libresolv libnss_dns
+ ifeq ($(have-thread-library),yes)
+-extra-libs += libanl
+-routines += gai_sigqueue
++extra-libs-$(OPTION_EGLIBC_INET_ANL) += libanl
++routines-$(OPTION_EGLIBC_INET) += gai_sigqueue
+ endif
+-extra-libs-others = $(extra-libs)
++extra-libs-others-y += $(extra-libs-y)
+ libresolv-routines := gethnamaddr res_comp res_debug	\
+ 		      res_data res_mkquery res_query res_send		\
+ 		      inet_net_ntop inet_net_pton inet_neta base64	\
+@@ -60,7 +63,7 @@
+ static-only-routines    += $(libnss_dns-routines) $(libresolv-routines)
+ endif
+ 
+-ifeq (yesyes,$(build-shared)$(have-thread-library))
++ifeq (yesyesy,$(build-shared)$(have-thread-library)$(OPTION_EGLIBC_INET_ANL))
+ tests: $(objpfx)ga_test
+ endif
+ 
+Index: git/stdio-common/fxprintf.c
+===================================================================
+--- git.orig/stdio-common/fxprintf.c	2014-08-29 20:00:53.544070587 -0700
++++ git/stdio-common/fxprintf.c	2014-08-29 20:01:15.232070587 -0700
+@@ -23,6 +23,7 @@
+ #include <wchar.h>
+ #include <string.h>
+ #include <libioP.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -37,6 +38,7 @@
+   int res;
+   if (_IO_fwide (fp, 0) > 0)
+     {
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+       size_t len = strlen (fmt) + 1;
+       wchar_t wfmt[len];
+       for (size_t i = 0; i < len; ++i)
+@@ -45,6 +47,9 @@
+ 	  wfmt[i] = fmt[i];
+ 	}
+       res = __vfwprintf (fp, wfmt, ap);
++#else
++      abort();
++#endif
+     }
+   else
+     res = _IO_vfprintf (fp, fmt, ap);
+Index: git/stdio-common/_i18n_number.h
+===================================================================
+--- git.orig/stdio-common/_i18n_number.h	2014-08-29 20:00:53.500070587 -0700
++++ git/stdio-common/_i18n_number.h	2014-08-29 20:01:15.232070587 -0700
+@@ -19,10 +19,13 @@
+ #include <stdbool.h>
+ #include <wchar.h>
+ #include <wctype.h>
++#include <gnu/option-groups.h>
+ 
+ #include "../locale/outdigits.h"
+ #include "../locale/outdigitswc.h"
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
++
+ static CHAR_T *
+ _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
+ {
+@@ -115,3 +118,13 @@
+ 
+   return w;
+ }
++
++#else
++
++static CHAR_T *
++_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
++{
++  return w;
++}
++
++#endif
+Index: git/stdio-common/Makefile
+===================================================================
+--- git.orig/stdio-common/Makefile	2014-08-29 20:00:53.500070587 -0700
++++ git/stdio-common/Makefile	2014-08-29 20:01:15.232070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Specific makefile for stdio-common.
+ #
++include ../option-groups.mak
++
+ subdir	:= stdio-common
+ 
+ include ../Makeconfig
+@@ -30,7 +32,7 @@
+ 	vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex	      \
+ 	reg-modifier reg-type						      \
+ 	printf_size fprintf printf snprintf sprintf asprintf dprintf	      \
+-	vfwprintf vfscanf vfwscanf					      \
++	vfscanf								      \
+ 	fscanf scanf sscanf						      \
+ 	perror psignal							      \
+ 	tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname		      \
+@@ -41,23 +43,37 @@
+ 	isoc99_vsscanf							      \
+ 	psiginfo
+ 
+-aux	:= errlist siglist printf-parsemb printf-parsewc fxprintf
++# Ideally, _itowa and itowa-digits would be in this option group as
++# well, but it is used unconditionally by printf_fp and printf_fphex,
++# and it didn't seem straightforward to disentangle it.
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	vfwprintf vfwscanf
++
++aux    := errlist siglist printf-parsemb fxprintf
++aux-$(OPTION_POSIX_C_LANG_WIDE_CHAR) += printf-parsewc
+ 
+ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
+ 	 temptest tst-fileno test-fwrite tst-ungetc tst-ferror \
+ 	 xbug errnobug \
+ 	 bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \
+-	 tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \
++	 tfformat tiformat tllformat tstdiomisc tst-printfsz \
+ 	 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \
+-	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
+-	 tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
+-	 tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \
++	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
++	 scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf \
++	 tst-fseek tst-fmemopen tst-gets \
++	 tst-sprintf tst-rndseek tst-fdopen tst-fphex \
+ 	 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
+-	 tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
+-	 bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
+-	 scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
+-	 bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
+-	 bug25 tst-printf-round bug26
++	 tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
++	 bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17 \
++	 tst-setvbuf1 bug23 bug24 bug-vfprintf-nargs tst-sprintf3 bug25 \
++	 tst-printf-round bug26
++
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++      += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
++      += tst-perror bug19a bug20 tst-long-dbl-fphex tst-fphex-wide
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++      += bug18a tst-swscanf tst-wc-printf
+ 
+ test-srcs = tst-unbputc tst-printf
+ 
+Index: git/stdio-common/printf_fp.c
+===================================================================
+--- git.orig/stdio-common/printf_fp.c	2014-08-29 20:00:53.548070587 -0700
++++ git/stdio-common/printf_fp.c	2014-08-29 20:01:15.232070587 -0700
+@@ -39,6 +39,7 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ #include <stdbool.h>
+ #include <rounding-mode.h>
+ 
+@@ -148,6 +149,10 @@
+ 			      wchar_t thousands_sep, int ngroups)
+      internal_function;
+ 
++/* Ideally, when OPTION_EGLIBC_LOCALE_CODE is disabled, this should do
++   all its work in ordinary characters, rather than doing it in wide
++   characters and then converting at the end.  But that is a challenge
++   for another day.  */
+ 
+ int
+ ___printf_fp (FILE *fp,
+@@ -206,7 +211,14 @@
+   mp_limb_t cy;
+ 
+   /* Nonzero if this is output on a wide character stream.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+ 
+   /* Buffer in which we produce the output.  */
+   wchar_t *wbuffer = NULL;
+@@ -258,6 +270,7 @@
+ 
+ 
+   /* Figure out the decimal point character.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->extra == 0)
+     {
+       decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+@@ -277,7 +290,13 @@
+   /* The decimal point character must not be zero.  */
+   assert (*decimal != '\0');
+   assert (decimalwc != L'\0');
++#else
++  /* Hard-code values from 'C' locale.  */
++  decimal = ".";
++  decimalwc = L'.';
++#endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->group)
+     {
+       if (info->extra == 0)
+@@ -321,6 +340,9 @@
+     }
+   else
+     grouping = NULL;
++#else
++  grouping = NULL;
++#endif
+ 
+   /* Fetch the argument value.	*/
+ #ifndef __NO_LONG_DOUBLE_MATH
+Index: git/stdio-common/printf_fphex.c
+===================================================================
+--- git.orig/stdio-common/printf_fphex.c	2014-08-29 20:00:53.548070587 -0700
++++ git/stdio-common/printf_fphex.c	2014-08-29 20:01:15.232070587 -0700
+@@ -28,6 +28,7 @@
+ #include <_itoa.h>
+ #include <_itowa.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ #include <stdbool.h>
+ #include <rounding-mode.h>
+ 
+@@ -139,10 +140,18 @@
+   int done = 0;
+ 
+   /* Nonzero if this is output on a wide character stream.  */
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+ 
+ 
+   /* Figure out the decimal point character.  */
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (info->extra == 0)
+     {
+       decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+@@ -156,6 +165,10 @@
+     }
+   /* The decimal point character must never be zero.  */
+   assert (*decimal != '\0' && decimalwc != L'\0');
++#else
++  decimal = ".";
++  decimalwc = L'.';
++#endif
+ 
+ 
+   /* Fetch the argument value.	*/
+Index: git/stdio-common/printf_size.c
+===================================================================
+--- git.orig/stdio-common/printf_size.c	2014-08-29 20:00:53.548070587 -0700
++++ git/stdio-common/printf_size.c	2014-08-29 20:01:15.232070587 -0700
+@@ -23,6 +23,7 @@
+ #include <math.h>
+ #include <printf.h>
+ #include <libioP.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ /* This defines make it possible to use the same code for GNU C library and
+@@ -116,7 +117,14 @@
+ 
+   struct printf_info fp_info;
+   int done = 0;
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   int wide = info->wide;
++#else
++  /* This should never be called on a wide-oriented stream when
++     OPTION_POSIX_C_LANG_WIDE_CHAR is disabled, but the compiler can't
++     be trusted to figure that out.  */
++  const int wide = 0;
++#endif
+   int res;
+ 
+   /* Fetch the argument value.	*/
+Index: git/stdio-common/scanf14.c
+===================================================================
+--- git.orig/stdio-common/scanf14.c	2014-08-29 20:00:53.548070587 -0700
++++ git/stdio-common/scanf14.c	2014-08-29 20:01:15.232070587 -0700
+@@ -2,6 +2,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ #define FAIL() \
+   do {							\
+@@ -36,6 +37,7 @@
+     FAIL ();
+   else if (d != 2.25 || memcmp (c, " x", 2) != 0)
+     FAIL ();
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2)
+     FAIL ();
+   else
+@@ -45,6 +47,7 @@
+       memset (lsp, 'x', sizeof L"3.25");
+       free (lsp);
+     }
++#endif
+   if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2)
+     FAIL ();
+   else
+Index: git/stdio-common/tstdiomisc.c
+===================================================================
+--- git.orig/stdio-common/tstdiomisc.c	2014-08-29 20:00:53.584070587 -0700
++++ git/stdio-common/tstdiomisc.c	2014-08-29 20:01:15.232070587 -0700
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ t1 (void)
+@@ -125,6 +126,7 @@
+   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+ 	  buf);
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
+ 	    qnanval, qnanval, qnanval, qnanval,
+ 	    qnanval, qnanval, qnanval, qnanval);
+@@ -162,6 +164,7 @@
+   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+ 	  wbuf);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   lqnanval = NAN;
+ 
+@@ -206,6 +209,7 @@
+   printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+ 	  buf);
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
+ 	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
+ 	    lqnanval, lqnanval, lqnanval, lqnanval,
+@@ -250,6 +254,7 @@
+   result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+   printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+ 	  wbuf);
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+   return result;
+ }
+Index: git/stdio-common/tst-popen.c
+===================================================================
+--- git.orig/stdio-common/tst-popen.c	2014-08-29 20:00:53.576070587 -0700
++++ git/stdio-common/tst-popen.c	2014-08-29 20:01:15.232070587 -0700
+@@ -19,6 +19,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <wchar.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ do_test (void)
+@@ -34,12 +35,14 @@
+       return 1;
+     }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+   /* POSIX says that pipe streams are byte-oriented.  */
+   if (fwide (f, 0) >= 0)
+     {
+       puts ("popen did not return byte-oriented stream");
+       result = 1;
+     }
++#endif
+ 
+   if (getline (&line, &len, f) != 5)
+     {
+Index: git/stdio-common/tst-sprintf.c
+===================================================================
+--- git.orig/stdio-common/tst-sprintf.c	2014-08-29 20:00:53.580070587 -0700
++++ git/stdio-common/tst-sprintf.c	2014-08-29 20:01:15.236070587 -0700
+@@ -2,6 +2,7 @@
+ #include <stdlib.h>
+ #include <locale.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ int
+@@ -10,12 +11,14 @@
+   char buf[100];
+   int result = 0;
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
+   if (sprintf (buf, "%.0ls", L"foo") != 0
+       || strlen (buf) != 0)
+     {
+       puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output");
+       result = 1;
+     }
++#endif /* __OPTION_POSIX_C_LANG_WIDE_CHAR */
+ 
+ #define SIZE (1024*70000)
+ #define STR(x) #x
+Index: git/stdio-common/vfprintf.c
+===================================================================
+--- git.orig/stdio-common/vfprintf.c	2014-08-29 20:00:53.588070587 -0700
++++ git/stdio-common/vfprintf.c	2014-08-29 20:01:15.236070587 -0700
+@@ -29,6 +29,7 @@
+ #include <_itoa.h>
+ #include <locale/localeinfo.h>
+ #include <stdio.h>
++#include <gnu/option-groups.h>
+ 
+ /* This code is shared between the standard stdio implementation found
+    in GNU C library and the libio implementation originally found in
+@@ -138,6 +139,18 @@
+ # define EOF WEOF
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define MULTIBYTE_SUPPORT (1)
++#else
++# define MULTIBYTE_SUPPORT (0)
++#endif
++
++#if __OPTION_EGLIBC_LOCALE_CODE
++# define LOCALE_SUPPORT (1)
++#else
++# define LOCALE_SUPPORT (0)
++#endif
++
+ #include "_i18n_number.h"
+ 
+ /* Include the shared code for parsing the format string.  */
+@@ -1123,8 +1136,11 @@
+ # define process_string_arg(fspec) \
+     LABEL (form_character):						      \
+       /* Character.  */							      \
+-      if (is_long)							      \
+-	goto LABEL (form_wcharacter);					      \
++      if (is_long)                                                            \
++        {                                                                     \
++          assert (MULTIBYTE_SUPPORT);                                         \
++          goto LABEL (form_wcharacter);                                       \
++        }                                                                     \
+       --width;	/* Account for the character itself.  */		      \
+       if (!left)							      \
+ 	PAD (' ');							      \
+@@ -1137,6 +1153,7 @@
+       break;								      \
+ 									      \
+     LABEL (form_wcharacter):						      \
++      assert (MULTIBYTE_SUPPORT);                                             \
+       {									      \
+ 	/* Wide character.  */						      \
+ 	char buf[MB_CUR_MAX];						      \
+@@ -1203,6 +1220,7 @@
+ 	  }								      \
+ 	else								      \
+ 	  {								      \
++            assert (MULTIBYTE_SUPPORT);                                       \
+ 	    const wchar_t *s2 = (const wchar_t *) string;		      \
+ 	    mbstate_t mbstate;						      \
+ 									      \
+@@ -1403,7 +1421,9 @@
+     LABEL (flag_quote):
+       group = 1;
+ 
+-      if (grouping == (const char *) -1)
++      if (! LOCALE_SUPPORT)
++        grouping = NULL;
++      else if (grouping == (const char *) -1)
+ 	{
+ #ifdef COMPILE_WPRINTF
+ 	  thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+@@ -1702,7 +1722,9 @@
+       free (workstart);
+     workstart = NULL;
+ 
+-    if (grouping == (const char *) -1)
++    if (! LOCALE_SUPPORT)
++      grouping = NULL;
++    else if (grouping == (const char *) -1)
+       {
+ #ifdef COMPILE_WPRINTF
+ 	thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+Index: git/stdio-common/vfscanf.c
+===================================================================
+--- git.orig/stdio-common/vfscanf.c	2014-08-29 20:00:53.588070587 -0700
++++ git/stdio-common/vfscanf.c	2014-08-29 20:01:15.236070587 -0700
+@@ -29,6 +29,7 @@
+ #include <wctype.h>
+ #include <bits/libc-lock.h>
+ #include <locale/localeinfo.h>
++#include <gnu/option-groups.h>
+ 
+ #ifdef	__GNUC__
+ # define HAVE_LONGLONG
+@@ -133,6 +134,12 @@
+ # define WINT_T		int
+ #endif
+ 
++#if __OPTION_POSIX_C_LANG_WIDE_CHAR
++# define MULTIBYTE_SUPPORT (1)
++#else
++# define MULTIBYTE_SUPPORT (0)
++#endif
++
+ #define encode_error() do {						      \
+ 			  errval = 4;					      \
+ 			  __set_errno (EILSEQ);				      \
+@@ -316,24 +323,35 @@
+   ARGCHECK (s, format);
+ 
+  {
+-#ifndef COMPILE_WSCANF
++#if __OPTION_EGLIBC_LOCALE_CODE && !defined (COMPILE_WSCANF)
+    struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
+ #endif
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+    /* Figure out the decimal point character.  */
+-#ifdef COMPILE_WSCANF
++# ifdef COMPILE_WSCANF
+    decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
+-#else
++# else
+    decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
+-#endif
++# endif
+    /* Figure out the thousands separator character.  */
+-#ifdef COMPILE_WSCANF
++# ifdef COMPILE_WSCANF
+    thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
+-#else
++# else
+    thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
+    if (*thousands == '\0')
+      thousands = NULL;
+-#endif
++# endif
++#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
++   /* Hard-code values from the C locale.  */
++# ifdef COMPILE_WSCANF
++   decimal = L'.';
++   thousands = L'\0';
++# else
++   decimal = ".";
++   thousands = NULL;
++# endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+  }
+ 
+   /* Lock the stream.  */
+@@ -385,6 +403,8 @@
+ #ifndef COMPILE_WSCANF
+       if (!isascii ((unsigned char) *f))
+ 	{
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  /* Non-ASCII, may be a multibyte.  */
+ 	  int len = __mbrlen (f, strlen (f), &state);
+ 	  if (len > 0)
+@@ -830,6 +850,8 @@
+ 	    }
+ 	  /* FALLTHROUGH */
+ 	case L_('C'):
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  if (width == -1)
+ 	    width = 1;
+ 
+@@ -1172,6 +1194,8 @@
+ 	  /* FALLTHROUGH */
+ 
+ 	case L_('S'):
++          assert (MULTIBYTE_SUPPORT);
++
+ 	  {
+ #ifndef COMPILE_WSCANF
+ 	    mbstate_t cstate;
+@@ -1419,10 +1443,17 @@
+ 	      const char *mbdigits[10];
+ 	      const char *mbdigits_extended[10];
+ #endif
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	      /*  "to_inpunct" is a map from ASCII digits to their
+ 		  equivalent in locale. This is defined for locales
+ 		  which use an extra digits set.  */
+ 	      wctrans_t map = __wctrans ("to_inpunct");
++#else
++              /* This will always be the case when
++                 OPTION_EGLIBC_LOCALE_CODE is disabled, but the
++                 compiler can't figure that out.  */
++              wctrans_t map = NULL;
++#endif
+ 	      int n;
+ 
+ 	      from_level = 0;
+@@ -2088,6 +2119,7 @@
+ 		--width;
+ 	    }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ 	  wctrans_t map;
+ 	  if (__builtin_expect ((flags & I18N) != 0, 0)
+ 	      /* Hexadecimal floats make no sense, fixing localized
+@@ -2304,6 +2336,7 @@
+ 	      ;
+ #endif
+ 	    }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 
+ 	  /* Have we read any character?  If we try to read a number
+ 	     in hexadecimal notation and we have read only the `0x'
+@@ -2343,7 +2376,10 @@
+ 
+ 	case L_('['):	/* Character class.  */
+ 	  if (flags & LONG)
+-	    STRING_ARG (wstr, wchar_t, 100);
++            {
++              assert (MULTIBYTE_SUPPORT);
++              STRING_ARG (wstr, wchar_t, 100);
++            }
+ 	  else
+ 	    STRING_ARG (str, char, 100);
+ 
+@@ -2417,6 +2453,7 @@
+ 	  if (flags & LONG)
+ 	    {
+ 	      size_t now = read_in;
++              assert (MULTIBYTE_SUPPORT);
+ #ifdef COMPILE_WSCANF
+ 	      if (__glibc_unlikely (inchar () == WEOF))
+ 		input_error ();
+Index: git/stdlib/Makefile
+===================================================================
+--- git.orig/stdlib/Makefile	2014-08-29 20:00:53.588070587 -0700
++++ git/stdlib/Makefile	2014-08-29 20:01:15.236070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for stdlib routines
+ #
++include ../option-groups.mak
++
+ subdir	:= stdlib
+ 
+ include ../Makeconfig
+@@ -30,7 +32,7 @@
+ 	   alloca.h fmtmsg.h						      \
+ 	   bits/stdlib-bsearch.h
+ 
+-routines	:=							      \
++routines-y	:=							      \
+ 	atof atoi atol atoll						      \
+ 	abort								      \
+ 	bsearch qsort msort						      \
+@@ -39,7 +41,6 @@
+ 	quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl     \
+ 	abs labs llabs							      \
+ 	div ldiv lldiv							      \
+-	mblen mbstowcs mbtowc wcstombs wctomb				      \
+ 	random random_r rand rand_r					      \
+ 	drand48 erand48 lrand48 nrand48 mrand48 jrand48			      \
+ 	srand48 seed48 lcong48						      \
+@@ -52,9 +53,18 @@
+ 	strtof_l strtod_l strtold_l					      \
+ 	system canonicalize						      \
+ 	a64l l64a							      \
+-	rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg		      \
+-	strtoimax strtoumax wcstoimax wcstoumax				      \
++	getsubopt xpg_basename						      \
++	strtoimax strtoumax						      \
+ 	getcontext setcontext makecontext swapcontext
++routines-$(OPTION_EGLIBC_LOCALE_CODE) +=				      \
++	strfmon strfmon_l
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) +=				      \
++	mblen mbstowcs mbtowc wcstombs wctomb				      \
++	wcstoimax wcstoumax
++ifeq (yy,$(OPTION_EGLIBC_LOCALE_CODE)$(OPTION_POSIX_REGEXP))
++routines-y += rpmatch
++endif
++routines-$(OPTION_EGLIBC_FMTMSG) += fmtmsg
+ aux =	grouping groupingwc tens_in_limb
+ 
+ # These routines will be omitted from the libc shared object.
+@@ -62,20 +72,22 @@
+ # linked against when the shared library will be used.
+ static-only-routines = atexit at_quick_exit
+ 
+-test-srcs	:= tst-fmtmsg
+-tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
++test-srcs-$(OPTION_EGLIBC_FMTMSG) := tst-fmtmsg
++tests		:= tst-strtol tst-strtod testrand testsort testdiv          \
+ 		   test-canon test-canon2 tst-strtoll tst-environ	    \
+ 		   tst-xpg-basename tst-random tst-random2 tst-bsearch	    \
+ 		   tst-limits tst-rand48 bug-strtod tst-setcontext	    \
+-		   test-a64l tst-qsort tst-system testmb2 bug-strtod2	    \
+-		   tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
+-		   tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2	    \
+-		   tst-makecontext2 tst-strtod6 tst-unsetenv1		    \
+-		   tst-makecontext3 bug-getcontext bug-fmtmsg1		    \
++		   test-a64l tst-qsort tst-system bug-strtod2		    \
++		   tst-atof1 tst-atof2 tst-strtod2 tst-rand48-2             \
++		   tst-makecontext tst-qsort2 tst-makecontext2 tst-strtod6  \
++		   tst-unsetenv1 tst-makecontext3 bug-getcontext bug-fmtmsg1 \
+ 		   tst-secure-getenv tst-strtod-overflow tst-strtod-round   \
+ 		   tst-tininess tst-strtod-underflow tst-tls-atexit
+ tests-static	:= tst-secure-getenv
+-
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= tst-strtod3 tst-strtod4 tst-strtod5 testmb2
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++		+= testmb
+ modules-names	= tst-tls-atexit-lib
+ 
+ ifeq ($(build-shared),yes)
+@@ -115,8 +127,10 @@
+ tests-special += $(objpfx)isomac.out
+ 
+ ifeq ($(run-built-tests),yes)
++ifeq (y,$(OPTION_EGLIBC_FMTMSG))
+ tests-special += $(objpfx)tst-fmtmsg.out
+ endif
++endif
+ 
+ include ../Rules
+ 
+Index: git/stdlib/strtod_l.c
+===================================================================
+--- git.orig/stdlib/strtod_l.c	2014-08-29 20:00:53.648070587 -0700
++++ git/stdlib/strtod_l.c	2014-08-29 20:01:15.236070587 -0700
+@@ -17,6 +17,7 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <gnu/option-groups.h>
+ #include <xlocale.h>
+ 
+ extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
+@@ -548,6 +549,7 @@
+   /* Used in several places.  */
+   int cnt;
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   struct __locale_data *current = loc->__locales[LC_NUMERIC];
+ 
+   if (__glibc_unlikely (group))
+@@ -586,6 +588,17 @@
+   decimal_len = strlen (decimal);
+   assert (decimal_len > 0);
+ #endif
++#else /* if ! __OPTION_EGLIBC_LOCALE_CODE */
++  /* Hard-code values from the 'C' locale.  */
++  grouping = NULL;
++#ifdef USE_WIDE_CHAR
++  decimal = L'.';
++# define decimal_len 1
++#else
++  decimal = ".";
++  decimal_len = 1;
++#endif
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+ 
+   /* Prepare number representation.  */
+   exponent = 0;
+Index: git/stdlib/tst-strtod.c
+===================================================================
+--- git.orig/stdlib/tst-strtod.c	2014-08-29 20:00:53.700070587 -0700
++++ git/stdlib/tst-strtod.c	2014-08-29 20:01:15.236070587 -0700
+@@ -23,6 +23,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <math.h>
++#include <gnu/option-groups.h>
+ 
+ struct ltest
+   {
+@@ -176,7 +177,9 @@
+ 
+   status |= long_dbl ();
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   status |= locale_test ();
++#endif
+ 
+   return status ? EXIT_FAILURE : EXIT_SUCCESS;
+ }
+@@ -219,6 +222,7 @@
+   return 0;
+ }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ /* Perform a few tests in a locale with thousands separators.  */
+ static int
+ locale_test (void)
+@@ -276,3 +280,4 @@
+ 
+   return result;
+ }
++#endif /* __OPTION_EGLIBC_LOCALE_CODE */
+Index: git/streams/Makefile
+===================================================================
+--- git.orig/streams/Makefile	2014-08-29 20:00:53.712070587 -0700
++++ git/streams/Makefile	2014-08-29 20:01:15.236070587 -0700
+@@ -18,11 +18,14 @@
+ #
+ #	Makefile for streams.
+ #
++include ../option-groups.mak
++
+ subdir	:= streams
+ 
+ include ../Makeconfig
+ 
+ headers		= stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
+-routines	= isastream getmsg getpmsg putmsg putpmsg fattach fdetach
++routines-$(OPTION_EGLIBC_STREAMS) \
++	+= isastream getmsg getpmsg putmsg putpmsg fattach fdetach
+ 
+ include ../Rules
+Index: git/string/Makefile
+===================================================================
+--- git.orig/string/Makefile	2014-08-29 20:00:53.716070587 -0700
++++ git/string/Makefile	2014-08-29 20:01:15.236070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for string portion of library.
+ #
++include ../option-groups.mak
++
+ subdir	:= string
+ 
+ include ../Makeconfig
+@@ -39,10 +41,12 @@
+ 		   $(addprefix argz-,append count create ctsep next	\
+ 				     delete extract insert stringify	\
+ 				     addsep replace)			\
+-		   envz basename					\
++		   basename						\
+ 		   strcoll_l strxfrm_l string-inlines memrchr		\
+ 		   xpg-strerror strerror_l
+ 
++routines-$(OPTION_EGLIBC_ENVZ) += envz
++
+ strop-tests	:= memchr memcmp memcpy memmove mempcpy memset memccpy	\
+ 		   stpcpy stpncpy strcat strchr strcmp strcpy strcspn	\
+ 		   strlen strncmp strncpy strpbrk strrchr strspn memmem	\
+@@ -51,10 +55,12 @@
+ tests		:= tester inl-tester noinl-tester testcopy test-ffs	\
+ 		   tst-strlen stratcliff tst-svc tst-inlcall		\
+ 		   bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap	\
+-		   tst-strtok tst-strxfrm bug-strcoll1 tst-strfry	\
++		   tst-strtok tst-strfry	\
+ 		   bug-strtok1 $(addprefix test-,$(strop-tests))	\
+-		   bug-envz1 tst-strxfrm2 tst-endian tst-svc2		\
+-		   tst-strtok_r
++		   tst-strxfrm2 tst-endian tst-svc2 tst-strtok_r
++tests-$(OPTION_EGLIBC_ENVZ) += bug-envz1
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++		+= tst-strxfrm bug-strcoll1
+ 
+ xtests = tst-strcoll-overflow
+ 
+Index: git/string/strcoll_l.c
+===================================================================
+--- git.orig/string/strcoll_l.c	2014-08-29 20:00:53.744070587 -0700
++++ git/string/strcoll_l.c	2014-08-29 20:01:15.240070587 -0700
+@@ -25,6 +25,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ #ifndef STRING_TYPE
+ # define STRING_TYPE char
+@@ -472,7 +473,11 @@
+ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ {
+   struct __locale_data *current = l->__locales[LC_COLLATE];
++#if __OPTION_EGLIBC_LOCALE_CODE
+   uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++#else
++  const uint_fast32_t nrules = 0;
++#endif
+   /* We don't assign the following values right away since it might be
+      unnecessary in case there are no rules.  */
+   const unsigned char *rulesets;
+Index: git/string/strerror_l.c
+===================================================================
+--- git.orig/string/strerror_l.c	2014-08-29 20:00:53.744070587 -0700
++++ git/string/strerror_l.c	2014-08-29 20:01:15.240070587 -0700
+@@ -21,6 +21,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ static __thread char *last_value;
+@@ -29,10 +30,14 @@
+ static const char *
+ translate (const char *str, locale_t loc)
+ {
++#if __OPTION_EGLIBC_LOCALE_CODE
+   locale_t oldloc = __uselocale (loc);
+   const char *res = _(str);
+   __uselocale (oldloc);
+   return res;
++#else
++  return str;
++#endif
+ }
+ 
+ 
+Index: git/string/strxfrm_l.c
+===================================================================
+--- git.orig/string/strxfrm_l.c	2014-08-29 20:00:53.748070587 -0700
++++ git/string/strxfrm_l.c	2014-08-29 20:01:15.240070587 -0700
+@@ -24,6 +24,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <gnu/option-groups.h>
+ 
+ #ifndef STRING_TYPE
+ # define STRING_TYPE char
+@@ -85,7 +86,11 @@
+ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
+ {
+   struct __locale_data *current = l->__locales[LC_COLLATE];
++#if __OPTION_EGLIBC_LOCALE_CODE
+   uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++#else
++  const uint_fast32_t nrules = 0;
++#endif
+   /* We don't assign the following values right away since it might be
+      unnecessary in case there are no rules.  */
+   const unsigned char *rulesets;
+Index: git/string/test-strcmp.c
+===================================================================
+--- git.orig/string/test-strcmp.c	2014-08-29 20:00:53.752070587 -0700
++++ git/string/test-strcmp.c	2014-08-29 20:01:15.240070587 -0700
+@@ -329,34 +329,6 @@
+ 		FOR_EACH_IMPL (impl, 0)
+ 		check_result (impl, s1 + i1, s2 + i2, exp_result);
+       }
+-
+-  /* Test cases where there are multiple zero bytes after the first.  */
+-
+-  for (size_t i = 0; i < 16 + 1; i++)
+-    {
+-      s1[i] = 0x00;
+-      s2[i] = 0x00;
+-    }
+-
+-  for (size_t i = 0; i < 16; i++)
+-    {
+-      int exp_result;
+-
+-      for (int val = 0x01; val < 0x100; val++)
+-	{
+-	  for (size_t j = 0; j < i; j++)
+-	    {
+-	      s1[j] = val;
+-	      s2[j] = val;
+-	    }
+-
+-	  s2[i] = val;
+-
+-	  exp_result = SIMPLE_STRCMP (s1, s2);
+-	  FOR_EACH_IMPL (impl, 0)
+-	    check_result (impl, s1, s2, exp_result);
+-	}
+-    }
+ }
+ 
+ 
+Index: git/string/tst-strxfrm2.c
+===================================================================
+--- git.orig/string/tst-strxfrm2.c	2014-08-29 20:00:53.756070587 -0700
++++ git/string/tst-strxfrm2.c	2014-08-29 20:01:15.240070587 -0700
+@@ -1,6 +1,7 @@
+ #include <locale.h>
+ #include <stdio.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ static int
+ do_test (void)
+@@ -38,6 +39,7 @@
+       res = 1;
+     }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+   if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL)
+     {
+       puts ("setlocale failed");
+@@ -75,6 +77,7 @@
+ 	  res = 1;
+ 	}
+     }
++#endif
+ 
+   return res;
+ }
+Index: git/string/tst-strxfrm.c
+===================================================================
+--- git.orig/string/tst-strxfrm.c	2014-08-29 20:00:53.756070587 -0700
++++ git/string/tst-strxfrm.c	2014-08-29 20:01:15.240070587 -0700
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ char const string[] = "";
+@@ -64,8 +65,10 @@
+   int result = 0;
+ 
+   result |= test ("C");
++#if __OPTION_EGLIBC_LOCALE_CODE
+   result |= test ("en_US.ISO-8859-1");
+   result |= test ("de_DE.UTF-8");
++#endif
+ 
+   return result;
+ }
+Index: git/sunrpc/Makefile
+===================================================================
+--- git.orig/sunrpc/Makefile	2014-08-29 20:00:53.760070587 -0700
++++ git/sunrpc/Makefile	2014-08-29 20:01:15.240070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Sub-makefile for sunrpc portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= sunrpc
+ 
+ include ../Makeconfig
+@@ -55,7 +57,6 @@
+ headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \
+ 		       $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h
+ headers = rpc/netdb.h
+-install-others = $(inst_sysconfdir)/rpc
+ generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \
+ 	     $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen
+ generated-dirs += rpcsvc
+@@ -65,18 +66,28 @@
+ endif
+ 
+ ifeq ($(build-shared),yes)
+-need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
++need-export-routines-$(OPTION_EGLIBC_SUNRPC) += \
++			auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
+ 			clnt_udp get_myaddr key_call netname pm_getport \
+-			rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \
++			rpc_thread svc svc_tcp svc_udp xdr_array xdr \
+ 			xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \
+ 			svc_run
+ 
+-routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
++need-export-routines-y += xcrypt
++
++need-export-routines := $(need-export-routines-y)
++
++routines-$(OPTION_EGLIBC_SUNRPC) \
++	 += auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
+ 	    rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \
+ 	    pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \
+ 	    svc_simple xdr_float xdr_rec publickey authdes_prot \
+-	    des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \
+-	    clnt_unix svc_unix create_xid $(need-export-routines)
++	    key_prot openchild rtime svcauth_des \
++	    clnt_unix svc_unix create_xid
++
++# xdecrypt is also used by nss/nss_files/files-key.c.
++routines-y += des_crypt des_impl des_soft $(need-export-routines)
++
+ ifneq ($(link-obsolete-rpc),yes)
+ # We only add the RPC for compatibility to libc.so.
+ shared-only-routines = $(routines)
+@@ -85,25 +96,28 @@
+ 
+ # We do not build rpcinfo anymore.  It is not needed for a bootstrap
+ # and not wanted on complete systems.
+-# others := rpcinfo
+-# install-sbin := rpcinfo
+-install-bin := rpcgen
++# others-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
++# install-sbin-$(OPTION_EGLIBC_SUNRPC) += rpcinfo
++install-bin-$(OPTION_EGLIBC_SUNRPC) += rpcgen
+ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
+ 	      rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
+ 	      rpc_tblout.o rpc_sample.o
+-extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
+-others += rpcgen
++extra-objs-$(OPTION_EGLIBC_SUNRPC) = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
++others-$(OPTION_EGLIBC_SUNRPC) += rpcgen
++
++install-others-$(OPTION_EGLIBC_SUNRPC) += $(inst_sysconfdir)/rpc
+ 
+-tests = tst-xdrmem tst-xdrmem2
+-xtests := tst-getmyaddr
++tests-$(OPTION_EGLIBC_SUNRPC) = tst-xdrmem tst-xdrmem2
++xtests-$(OPTION_EGLIBC_SUNRPC) := tst-getmyaddr
+ 
+ ifeq ($(have-thread-library),yes)
+-xtests += thrsvc
++xtests-$(OPTION_EGLIBC_SUNRPC) += thrsvc
+ endif
+ 
+ headers += $(rpcsvc:%.x=rpcsvc/%.h)
+-extra-libs := librpcsvc
+-extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass.
++extra-libs-$(OPTION_EGLIBC_SUNRPC) += librpcsvc
++# Make it in `others' pass, not `lib' pass.
++extra-libs-others-y += $(extra-libs-y)
+ librpcsvc-routines = $(rpcsvc:%.x=x%)
+ librpcsvc-inhibit-o = .os # Build no shared rpcsvc library.
+ omit-deps = $(librpcsvc-routines)
+Index: git/sysdeps/generic/ldsodefs.h
+===================================================================
+--- git.orig/sysdeps/generic/ldsodefs.h	2014-08-29 20:00:53.904070587 -0700
++++ git/sysdeps/generic/ldsodefs.h	2014-08-29 20:01:15.240070587 -0700
+@@ -425,6 +425,12 @@
+ # undef __rtld_global_attribute__
+ #endif
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
++# define GLRO_dl_debug_mask GLRO(dl_debug_mask)
++#else
++# define GLRO_dl_debug_mask 0
++#endif
++
+ #ifndef SHARED
+ # define GLRO(name) _##name
+ #else
+@@ -437,8 +443,10 @@
+ {
+ #endif
+ 
++#if __OPTION_EGLIBC_RTLD_DEBUG
+   /* If nonzero the appropriate debug information is printed.  */
+   EXTERN int _dl_debug_mask;
++#endif
+ #define DL_DEBUG_LIBS	    (1 << 0)
+ #define DL_DEBUG_IMPCALLS   (1 << 1)
+ #define DL_DEBUG_BINDINGS   (1 << 2)
+Index: git/sysdeps/gnu/Makefile
+===================================================================
+--- git.orig/sysdeps/gnu/Makefile	2014-08-29 20:00:53.924070587 -0700
++++ git/sysdeps/gnu/Makefile	2014-08-29 20:01:15.240070587 -0700
+@@ -57,7 +57,8 @@
+ endif
+ 
+ ifeq ($(subdir),login)
+-sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
++sysdep_routines-$(OPTION_EGLIBC_UTMPX) \
++		+= setutxent getutxent endutxent getutxid getutxline \
+ 		   pututxline utmpxname updwtmpx getutmpx getutmp
+ 
+ sysdep_headers += utmpx.h bits/utmpx.h
+Index: git/sysdeps/ieee754/ldbl-opt/Makefile
+===================================================================
+--- git.orig/sysdeps/ieee754/ldbl-opt/Makefile	2014-08-29 20:00:54.452070587 -0700
++++ git/sysdeps/ieee754/ldbl-opt/Makefile	2014-08-29 20:01:15.244070587 -0700
+@@ -11,19 +11,18 @@
+ routines += math_ldbl_opt nldbl-compat
+ 
+ extra-libs += libnldbl
+-libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
++libnldbl-calls = asprintf dprintf fprintf fscanf iovfscanf \
+ 		 obstack_printf obstack_vprintf printf scanf snprintf \
+-		 sprintf sscanf swprintf swscanf vasprintf vdprintf vfprintf \
+-		 vfscanf vfwprintf vfwscanf vprintf vscanf vsnprintf \
+-		 vsprintf vsscanf vswprintf vswscanf vwprintf vwscanf \
+-		 wprintf wscanf printf_fp printf_size \
+-		 fprintf_chk fwprintf_chk printf_chk snprintf_chk sprintf_chk \
+-		 swprintf_chk vfprintf_chk vfwprintf_chk vprintf_chk \
+-		 vsnprintf_chk vsprintf_chk vswprintf_chk vwprintf_chk \
+-		 wprintf_chk asprintf_chk vasprintf_chk dprintf_chk \
++		 sprintf sscanf vasprintf vdprintf vfprintf \
++		 vfscanf vprintf vscanf vsnprintf \
++		 vsprintf vsscanf \
++		 printf_fp printf_size \
++		 fprintf_chk printf_chk snprintf_chk sprintf_chk \
++		 vfprintf_chk vprintf_chk \
++		 vsnprintf_chk vsprintf_chk \
++		 asprintf_chk vasprintf_chk dprintf_chk \
+ 		 vdprintf_chk obstack_printf_chk obstack_vprintf_chk \
+ 		 syslog syslog_chk vsyslog vsyslog_chk \
+-		 strfmon strfmon_l \
+ 		 strtold strtold_l strtoldint wcstold wcstold_l wcstoldint \
+ 		 qecvt qfcvt qgcvt qecvt_r qfcvt_r \
+ 		 isinf isnan finite signbit scalb log2 lgamma_r ceil \
+@@ -38,9 +37,15 @@
+ 		 casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \
+ 		 cabs carg cimag creal clog10 \
+ 		 isoc99_scanf isoc99_fscanf isoc99_sscanf \
+-		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
++		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf
++libnldbl-calls-$(OPTION_EGLIBC_LOCALE_CODE) += strfmon strfmon_l
++libnldbl-calls-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += fwprintf fwscanf \
++		 swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf \
++		 vwprintf vwscanf wprintf wscanf fwprintf_chk swprintf_chk \
++		 vfwprintf_chk vswprintf_chk vwprintf_chk wprintf_chk \
+ 		 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
+ 		 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
++libnldbl-calls += $(libnldbl-calls-y)
+ libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
+ libnldbl-inhibit-o = $(object-suffixes)
+ libnldbl-static-only-routines = $(libnldbl-routines)
+Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
+===================================================================
+--- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.c	2014-08-29 20:00:54.468070587 -0700
++++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.c	2014-08-29 20:01:15.244070587 -0700
+@@ -26,6 +26,7 @@
+ #include <locale/localeinfo.h>
+ #include <sys/syslog.h>
+ #include <bits/libc-lock.h>
++#include <gnu/option-groups.h>
+ 
+ #include "nldbl-compat.h"
+ 
+@@ -33,20 +34,14 @@
+ libc_hidden_proto (__nldbl_vsscanf)
+ libc_hidden_proto (__nldbl_vsprintf)
+ libc_hidden_proto (__nldbl_vfscanf)
+-libc_hidden_proto (__nldbl_vfwscanf)
+ libc_hidden_proto (__nldbl_vdprintf)
+-libc_hidden_proto (__nldbl_vswscanf)
+-libc_hidden_proto (__nldbl_vfwprintf)
+-libc_hidden_proto (__nldbl_vswprintf)
+ libc_hidden_proto (__nldbl_vsnprintf)
+ libc_hidden_proto (__nldbl_vasprintf)
+ libc_hidden_proto (__nldbl_obstack_vprintf)
+-libc_hidden_proto (__nldbl___vfwprintf_chk)
+ libc_hidden_proto (__nldbl___vsnprintf_chk)
+ libc_hidden_proto (__nldbl___vfprintf_chk)
+ libc_hidden_proto (__nldbl___vsyslog_chk)
+ libc_hidden_proto (__nldbl___vsprintf_chk)
+-libc_hidden_proto (__nldbl___vswprintf_chk)
+ libc_hidden_proto (__nldbl___vasprintf_chk)
+ libc_hidden_proto (__nldbl___vdprintf_chk)
+ libc_hidden_proto (__nldbl___obstack_vprintf_chk)
+@@ -54,8 +49,17 @@
+ libc_hidden_proto (__nldbl___vstrfmon_l)
+ libc_hidden_proto (__nldbl___isoc99_vsscanf)
+ libc_hidden_proto (__nldbl___isoc99_vfscanf)
++
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++libc_hidden_proto (__nldbl_vfwscanf)
++libc_hidden_proto (__nldbl_vswscanf)
++libc_hidden_proto (__nldbl_vfwprintf)
++libc_hidden_proto (__nldbl_vswprintf)
++libc_hidden_proto (__nldbl___vfwprintf_chk)
++libc_hidden_proto (__nldbl___vswprintf_chk)
+ libc_hidden_proto (__nldbl___isoc99_vswscanf)
+ libc_hidden_proto (__nldbl___isoc99_vfwscanf)
++#endif
+ 
+ static void
+ __nldbl_cleanup (void *arg)
+@@ -117,6 +121,7 @@
+ }
+ weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...)
+@@ -130,6 +135,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -226,6 +232,7 @@
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...)
+@@ -239,6 +246,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section weak_function
+@@ -264,6 +272,7 @@
+ }
+ libc_hidden_def (__nldbl_vdprintf)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -275,6 +284,7 @@
+   return res;
+ }
+ libc_hidden_def (__nldbl_vfwprintf)
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -297,6 +307,7 @@
+ libc_hidden_def (__nldbl_vsnprintf)
+ weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section weak_function
+ __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt,
+@@ -330,6 +341,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -419,6 +431,7 @@
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -491,6 +504,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -506,6 +520,7 @@
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...)
+@@ -519,6 +534,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -563,6 +579,7 @@
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen,
+@@ -577,6 +594,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -590,6 +608,7 @@
+ }
+ libc_hidden_def (__nldbl___vfprintf_chk)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap)
+@@ -601,6 +620,7 @@
+   return res;
+ }
+ libc_hidden_def (__nldbl___vfwprintf_chk)
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -635,6 +655,7 @@
+ }
+ libc_hidden_def (__nldbl___vsprintf_chk)
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen,
+@@ -668,6 +689,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ int
+ attribute_compat_text_section
+@@ -775,6 +797,7 @@
+   return ___printf_fp (fp, &info_no_ldbl, args);
+ }
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ ssize_t
+ attribute_compat_text_section
+ __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...)
+@@ -829,6 +852,7 @@
+   return res;
+ }
+ libc_hidden_def (__nldbl___vstrfmon_l)
++#endif
+ 
+ void
+ attribute_compat_text_section
+@@ -941,6 +965,7 @@
+   return done;
+ }
+ 
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ int
+ attribute_compat_text_section
+ __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap)
+@@ -1014,6 +1039,7 @@
+ 
+   return done;
+ }
++#endif
+ 
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+ compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0);
+@@ -1057,6 +1083,7 @@
+ compat_symbol (libc, __nldbl___strfmon_l, __strfmon_l, GLIBC_2_1);
+ #endif
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_2)
++# if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
+ compat_symbol (libc, __nldbl_swprintf, swprintf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_vwprintf, vwprintf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_wprintf, wprintf, GLIBC_2_2);
+@@ -1069,6 +1096,7 @@
+ compat_symbol (libc, __nldbl_vswscanf, vswscanf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_vwscanf, vwscanf, GLIBC_2_2);
+ compat_symbol (libc, __nldbl_wscanf, wscanf, GLIBC_2_2);
++# endif
+ #endif
+ #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
+ compat_symbol (libc, __nldbl_strfmon_l, strfmon_l, GLIBC_2_3);
+Index: git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
+===================================================================
+--- git.orig/sysdeps/ieee754/ldbl-opt/nldbl-compat.h	2014-08-29 20:00:54.468070587 -0700
++++ git/sysdeps/ieee754/ldbl-opt/nldbl-compat.h	2014-08-29 20:01:15.244070587 -0700
+@@ -30,6 +30,7 @@
+ #include <math.h>
+ #include <monetary.h>
+ #include <sys/syslog.h>
++#include <gnu/option-groups.h>
+ 
+ 
+ /* Declare the __nldbl_NAME function the wrappers call that's in libc.so.  */
+@@ -37,19 +38,15 @@
+ 
+ NLDBL_DECL (_IO_vfscanf);
+ NLDBL_DECL (vfscanf);
+-NLDBL_DECL (vfwscanf);
+ NLDBL_DECL (obstack_vprintf);
+ NLDBL_DECL (vasprintf);
+ NLDBL_DECL (dprintf);
+ NLDBL_DECL (vdprintf);
+ NLDBL_DECL (fprintf);
+ NLDBL_DECL (vfprintf);
+-NLDBL_DECL (vfwprintf);
+ NLDBL_DECL (vsnprintf);
+ NLDBL_DECL (vsprintf);
+ NLDBL_DECL (vsscanf);
+-NLDBL_DECL (vswprintf);
+-NLDBL_DECL (vswscanf);
+ NLDBL_DECL (__asprintf);
+ NLDBL_DECL (asprintf);
+ NLDBL_DECL (__printf_fp);
+@@ -66,12 +63,18 @@
+ NLDBL_DECL (__isoc99_vscanf);
+ NLDBL_DECL (__isoc99_vfscanf);
+ NLDBL_DECL (__isoc99_vsscanf);
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++NLDBL_DECL (vfwscanf);
++NLDBL_DECL (vfwprintf);
++NLDBL_DECL (vswprintf);
++NLDBL_DECL (vswscanf);
+ NLDBL_DECL (__isoc99_wscanf);
+ NLDBL_DECL (__isoc99_fwscanf);
+ NLDBL_DECL (__isoc99_swscanf);
+ NLDBL_DECL (__isoc99_vwscanf);
+ NLDBL_DECL (__isoc99_vfwscanf);
+ NLDBL_DECL (__isoc99_vswscanf);
++#endif
+ 
+ /* This one does not exist in the normal interface, only
+    __nldbl___vstrfmon really exists.  */
+@@ -82,22 +85,23 @@
+    since we don't compile with _FORTIFY_SOURCE.  */
+ extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
+ 				   const char *__restrict, _G_va_list);
+-extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
+-				    const wchar_t *__restrict, __gnuc_va_list);
+ extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
+ 				   const char *__restrict, _G_va_list) __THROW;
+ extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
+ 				    const char *__restrict, _G_va_list)
+   __THROW;
+-extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
+-				    const wchar_t *__restrict, __gnuc_va_list)
+-  __THROW;
+ extern int __nldbl___vasprintf_chk (char **, int, const char *, _G_va_list)
+   __THROW;
+ extern int __nldbl___vdprintf_chk (int, int, const char *, _G_va_list);
+ extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *,
+ 					  _G_va_list) __THROW;
+ extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
+-
++#if __OPTION_POSIX_WIDE_CHAR_DEVICE_IO
++extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
++				    const wchar_t *__restrict, __gnuc_va_list);
++extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
++				    const wchar_t *__restrict, __gnuc_va_list)
++  __THROW;
++#endif
+ 
+ #endif /* __NLDBL_COMPAT_H */
+Index: git/sysdeps/unix/sysv/linux/gethostid.c
+===================================================================
+--- git.orig/sysdeps/unix/sysv/linux/gethostid.c	2014-08-29 20:00:58.840070587 -0700
++++ git/sysdeps/unix/sysv/linux/gethostid.c	2014-08-29 20:01:15.244070587 -0700
+@@ -21,6 +21,7 @@
+ #include <unistd.h>
+ #include <netdb.h>
+ #include <not-cancel.h>
++#include <gnu/option-groups.h>
+ 
+ #define HOSTIDFILE "/etc/hostid"
+ 
+@@ -89,6 +90,7 @@
+ 	return id;
+     }
+ 
++#if __OPTION_EGLIBC_INET
+   /* Getting from the file was not successful.  An intelligent guess for
+      a unique number of a host is its IP address.  Return this.  */
+   if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0')
+@@ -115,5 +117,9 @@
+   /* For the return value to be not exactly the IP address we do some
+      bit fiddling.  */
+   return (int32_t) (in.s_addr << 16 | in.s_addr >> 16);
++#else
++  /* Return an arbitrary value.  */
++  return 0;
++#endif
+ }
+ #endif
+Index: git/sysdeps/unix/sysv/linux/libc_fatal.c
+===================================================================
+--- git.orig/sysdeps/unix/sysv/linux/libc_fatal.c	2014-08-29 20:00:58.980070587 -0700
++++ git/sysdeps/unix/sysv/linux/libc_fatal.c	2014-08-29 20:01:15.244070587 -0700
+@@ -23,6 +23,7 @@
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/uio.h>
++#include <gnu/option-groups.h>
+ 
+ static bool
+ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
+@@ -40,6 +41,7 @@
+ static void
+ backtrace_and_maps (int do_abort, bool written, int fd)
+ {
++#if __OPTION_EGLIBC_BACKTRACE
+   if (do_abort > 1 && written)
+     {
+       void *addrs[64];
+@@ -62,6 +64,7 @@
+           close_not_cancel_no_status (fd2);
+         }
+     }
++#endif /* __OPTION_EGLIBC_BACKTRACE */
+ }
+ #define BEFORE_ABORT		backtrace_and_maps
+ 
+Index: git/time/Makefile
+===================================================================
+--- git.orig/time/Makefile	2014-08-29 20:00:59.504070587 -0700
++++ git/time/Makefile	2014-08-29 20:01:15.244070587 -0700
+@@ -18,6 +18,8 @@
+ #
+ #	Makefile for time routines
+ #
++include ../option-groups.mak
++
+ subdir	:= time
+ 
+ include ../Makeconfig
+@@ -30,14 +32,20 @@
+ 	    tzfile getitimer setitimer			 \
+ 	    stime dysize timegm ftime			 \
+ 	    getdate strptime strptime_l			 \
+-	    strftime wcsftime strftime_l wcsftime_l	 \
++	    strftime strftime_l				 \
+ 	    timespec_get
+-aux :=	    era alt_digit lc-time-cleanup
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR)		 \
++	 := wcsftime wcsftime_l
++aux-$(OPTION_EGLIBC_LOCALE_CODE) += alt_digit era lc-time-cleanup
+ 
+-tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
+-	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
++tests	:= test_time clocktest tst-posixtz \
++	   tst-getdate tst-mktime tst-mktime2 tst-strftime \
+ 	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
+ 	   tst-strptime3 bug-getdate1 tst-strptime-whitespace
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++	+= tst-strptime tst-ftime_l
++tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \
++	+= tst_wcsftime
+ 
+ include ../Rules
+ 
+Index: git/time/strftime_l.c
+===================================================================
+--- git.orig/time/strftime_l.c	2014-08-29 20:00:59.528070587 -0700
++++ git/time/strftime_l.c	2014-08-29 20:01:15.244070587 -0700
+@@ -35,6 +35,10 @@
+ # include "../locale/localeinfo.h"
+ #endif
+ 
++#ifdef _LIBC
++# include <gnu/option-groups.h>
++#endif
++
+ #if defined emacs && !defined HAVE_BCOPY
+ # define HAVE_MEMCPY 1
+ #endif
+@@ -882,7 +886,7 @@
+ 	case L_('C'):
+ 	  if (modifier == L_('E'))
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+@@ -955,7 +959,7 @@
+ 
+ 	  if (modifier == L_('O') && 0 <= number_value)
+ 	    {
+-#ifdef _NL_CURRENT
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
+ 	      /* Get the locale specific alternate representation of
+ 		 the number NUMBER_VALUE.  If none exist NULL is returned.  */
+ 	      const CHAR_T *cp = nl_get_alt_digit (number_value
+@@ -1260,7 +1264,7 @@
+ 	case L_('Y'):
+ 	  if (modifier == 'E')
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+@@ -1285,7 +1289,7 @@
+ 	case L_('y'):
+ 	  if (modifier == L_('E'))
+ 	    {
+-#if HAVE_STRUCT_ERA_ENTRY
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && HAVE_STRUCT_ERA_ENTRY
+ 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
+ 	      if (era)
+ 		{
+Index: git/time/strptime_l.c
+===================================================================
+--- git.orig/time/strptime_l.c	2014-08-29 20:00:59.528070587 -0700
++++ git/time/strptime_l.c	2014-08-29 20:01:15.244070587 -0700
+@@ -29,6 +29,7 @@
+ 
+ #ifdef _LIBC
+ # define HAVE_LOCALTIME_R 0
++# include <gnu/option-groups.h>
+ # include "../locale/localeinfo.h"
+ #endif
+ 
+@@ -84,7 +85,7 @@
+     if (val < from || val > to)						      \
+       return NULL;							      \
+   } while (0)
+-#ifdef _NL_CURRENT
++#if (! _LIBC || __OPTION_EGLIBC_LOCALE_CODE) && defined (_NL_CURRENT)
+ # define get_alt_number(from, to, n) \
+   ({									      \
+      __label__ do_normal;						      \
+@@ -820,6 +821,7 @@
+ 	      s.want_xday = 1;
+ 	      break;
+ 	    case 'C':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  if (s.era_cnt >= 0)
+@@ -856,10 +858,12 @@
+ 
+ 		  s.decided = raw;
+ 		}
++#endif
+ 	      /* The C locale has no era information, so use the
+ 		 normal representation.  */
+ 	      goto match_century;
+  	    case 'y':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  get_number(0, 9999, 4);
+@@ -918,9 +922,10 @@
+ 
+ 		  s.decided = raw;
+ 		}
+-
++#endif
+ 	      goto match_year_in_century;
+ 	    case 'Y':
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+ 	      if (s.decided != raw)
+ 		{
+ 		  num_eras = _NL_CURRENT_WORD (LC_TIME,
+@@ -948,6 +953,7 @@
+ 
+ 		  s.decided = raw;
+ 		}
++#endif
+ 	      get_number (0, 9999, 4);
+ 	      tm->tm_year = val - 1900;
+ 	      s.want_century = 0;
+@@ -1118,6 +1124,7 @@
+ 	tm->tm_year = (s.century - 19) * 100;
+     }
+ 
++#if ! _LIBC || __OPTION_EGLIBC_LOCALE_CODE
+   if (s.era_cnt != -1)
+     {
+       era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);
+@@ -1132,6 +1139,7 @@
+ 	tm->tm_year = era->start_date[0];
+     }
+   else
++#endif
+     if (s.want_era)
+       {
+ 	/* No era found but we have seen an E modifier.  Rectify some
+Index: git/timezone/Makefile
+===================================================================
+--- git.orig/timezone/Makefile	2014-08-29 20:01:14.044070587 -0700
++++ git/timezone/Makefile	2014-08-29 20:01:15.244070587 -0700
+@@ -115,7 +115,7 @@
+ 
+ $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
+ 	sed -e 's|/bin/bash|/bin/sh|' \
+-	    -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
++	    -e '/TZDIR=/s|\$$(pwd)|$(zonedir)|' \
+ 	    -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
+ 	    -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
+ 	    -e '/REPORT_BUGS_TO=/s|=.*|="$(REPORT_BUGS_TO)"|' \
+Index: git/wcsmbs/Makefile
+===================================================================
+--- git.orig/wcsmbs/Makefile	2014-08-29 20:00:59.548070587 -0700
++++ git/wcsmbs/Makefile	2014-08-29 20:01:15.244070587 -0700
+@@ -18,15 +18,21 @@
+ #
+ #	Sub-makefile for wcsmbs portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= wcsmbs
+ 
+ include ../Makeconfig
+ 
+ headers	:= wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h
+ 
+-routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
++# These functions are used by printf_fp.c, even in the plain case; see
++# comments there for OPTION_EGLIBC_LOCALE_CODE.
++routines  := wmemcpy wmemset
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++	  := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
+ 	    wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
+-	    wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy wmempcpy \
++	    wmemcmp wmemmove wcpcpy wcpncpy wmempcpy \
+ 	    btowc wctob mbsinit \
+ 	    mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
+ 	    mbsnrtowcs wcsnrtombs wcsnlen wcschrnul \
+@@ -38,14 +44,19 @@
+ 	    wcscoll_l wcsxfrm_l \
+ 	    wcscasecmp wcsncase wcscasecmp_l wcsncase_l \
+ 	    wcsmbsload mbsrtowcs_l \
+-	    isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \
+ 	    isoc99_swscanf isoc99_vswscanf \
+ 	    mbrtoc16 c16rtomb
++routines-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO)				\
++	 += isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf
+ 
+ strop-tests :=  wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy
+-tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \
+-	 tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \
+-	 tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests))
++tests := tst-wchar-h
++tests-$(OPTION_EGLIBC_LOCALE_CODE) \
++      += tst-btowc tst-mbrtowc tst-mbrtowc2 tst-wcrtomb tst-c16c32-1
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++      += tst-wcstof wcsmbs-tst1 tst-wcsnlen \
++	 tst-wcpncpy tst-mbsrtowcs \
++	 wcsatcliff $(addprefix test-,$(strop-tests))
+ tests-ifunc := $(strop-tests:%=test-%-ifunc)
+ tests += $(tests-ifunc)
+ 
+Index: git/wcsmbs/wcsmbsload.c
+===================================================================
+--- git.orig/wcsmbs/wcsmbsload.c	2014-08-29 20:00:59.580070587 -0700
++++ git/wcsmbs/wcsmbsload.c	2014-08-29 20:01:15.248070587 -0700
+@@ -21,6 +21,7 @@
+ #include <limits.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <gnu/option-groups.h>
+ 
+ #include <locale/localeinfo.h>
+ #include <wcsmbsload.h>
+@@ -143,6 +144,7 @@
+   })
+ 
+ 
++#if __OPTION_EGLIBC_LOCALE_CODE
+ /* Some of the functions here must not be used while setlocale is called.  */
+ __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
+ 
+@@ -211,6 +213,17 @@
+ 
+   __libc_rwlock_unlock (__libc_setlocale_lock);
+ }
++#else
++void
++internal_function
++__wcsmbs_load_conv (struct __locale_data *new_category)
++{
++  /* When OPTION_EGLIBC_LOCALE_CODE is disabled, we should never reach
++     this point: there is no way to change locales, so every locale
++     passed to get_gconv_fcts should be _nl_C_LC_CTYPE.  */
++  abort ();
++}
++#endif
+ 
+ 
+ /* Clone the current conversion function set.  */
+Index: git/wctype/Makefile
+===================================================================
+--- git.orig/wctype/Makefile	2014-08-29 20:00:59.584070587 -0700
++++ git/wctype/Makefile	2014-08-29 20:01:15.248070587 -0700
+@@ -18,14 +18,20 @@
+ #
+ #	Sub-makefile for wctype portion of the library.
+ #
++include ../option-groups.mak
++
+ subdir	:= wctype
+ 
+ include ../Makeconfig
+ 
+ headers		:= wctype.h
+-routines	:= wcfuncs wctype iswctype wctrans towctrans \
+-		   wcfuncs_l wctype_l iswctype_l wctrans_l towctrans_l
++routines 	:= wctrans towctrans towctrans_l
++routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++		:= wcfuncs wctype iswctype \
++		   wcfuncs_l wctype_l iswctype_l wctrans_l
+ 
+-tests	:= test_wctype test_wcfuncs bug-wctypeh
++tests	:=
++tests-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
++     += test_wctype test_wcfuncs bug-wctypeh
+ 
+ include ../Rules
+Index: git/sysdeps/nptl/Makefile
+===================================================================
+--- git.orig/sysdeps/nptl/Makefile	2014-08-29 20:00:58.036070587 -0700
++++ git/sysdeps/nptl/Makefile	2014-08-29 20:01:15.248070587 -0700
+@@ -18,6 +18,9 @@
+ 
+ ifeq ($(subdir),nptl)
+ libpthread-sysdep_routines += errno-loc
++ifeq ($(OPTION_EGLIBC_BIG_MACROS),n)
++sysdep_routines += small-macros-fns
++endif
+ endif
+ 
+ ifeq ($(subdir),rt)
+Index: git/sysdeps/nptl/bits/libc-lock.h
+===================================================================
+--- git.orig/sysdeps/nptl/bits/libc-lock.h	2014-08-29 20:00:58.036070587 -0700
++++ git/sysdeps/nptl/bits/libc-lock.h	2014-08-29 20:01:15.248070587 -0700
+@@ -24,6 +24,14 @@
+ #include <stddef.h>
+ 
+ 
++#ifdef _LIBC
++# include <lowlevellock.h>
++# include <tls.h>
++# include <pthread-functions.h>
++# include <errno.h> /* For EBUSY.  */
++# include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS.  */
++#endif
++
+ /* Mutex type.  */
+ #if defined _LIBC || defined _IO_MTSAFE_IO
+ # if (defined NOT_IN_libc && !defined IS_IN_libpthread) || !defined _LIBC
+@@ -87,6 +95,14 @@
+ 
+ /* Lock the recursive named lock variable.  */
+ #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_lock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_lock_recursive(NAME) \
+   do {									      \
+     void *self = THREAD_SELF;						      \
+@@ -97,6 +113,10 @@
+       }									      \
+     ++(NAME).cnt;							      \
+   } while (0)
++# else
++# define __libc_lock_lock_recursive(NAME)				\
++  __libc_lock_lock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_lock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+@@ -104,6 +124,14 @@
+ 
+ /* Try to lock the recursive named lock variable.  */
+ #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_trylock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_trylock_recursive(NAME) \
+   ({									      \
+     int result = 0;							      \
+@@ -122,6 +150,10 @@
+       ++(NAME).cnt;							      \
+     result;								      \
+   })
++# else
++# define __libc_lock_trylock_recursive(NAME) \
++  __libc_lock_trylock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_trylock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0)
+@@ -129,6 +161,14 @@
+ 
+ /* Unlock the recursive named lock variable.  */
+ #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *);
++libc_hidden_proto (__libc_lock_unlock_recursive_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ /* We do no error checking here.  */
+ # define __libc_lock_unlock_recursive(NAME) \
+   do {									      \
+@@ -138,6 +178,10 @@
+ 	lll_unlock ((NAME).lock, LLL_PRIVATE);				      \
+       }									      \
+   } while (0)
++# else
++# define __libc_lock_unlock_recursive(NAME) \
++  __libc_lock_unlock_recursive_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_unlock_recursive(NAME) \
+   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+Index: git/sysdeps/nptl/bits/libc-lockP.h
+===================================================================
+--- git.orig/sysdeps/nptl/bits/libc-lockP.h	2014-08-29 20:00:58.044070587 -0700
++++ git/sysdeps/nptl/bits/libc-lockP.h	2014-08-29 20:01:15.248070587 -0700
+@@ -33,6 +33,8 @@
+ #include <lowlevellock.h>
+ #include <tls.h>
+ #include <pthread-functions.h>
++#include <errno.h> /* For EBUSY.  */
++#include <gnu/option-groups.h> /* For __OPTION_EGLIBC_BIG_MACROS.  */
+ 
+ /* Mutex type.  */
+ #if defined NOT_IN_libc && !defined IS_IN_libpthread
+@@ -159,10 +161,22 @@
+ 
+ /* Lock the named lock variable.  */
+ #if !defined NOT_IN_libc || defined IS_IN_libpthread
+-# ifndef __libc_lock_lock
+-#  define __libc_lock_lock(NAME) \
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_lock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_lock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
++#  ifndef __libc_lock_lock
++#   define __libc_lock_lock(NAME) \
+   ({ lll_lock (NAME, LLL_PRIVATE); 0; })
+-# endif
++#  endif
++# else
++#  define __libc_lock_lock(NAME)		\
++  __libc_lock_lock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # undef __libc_lock_lock
+ # define __libc_lock_lock(NAME) \
+@@ -175,10 +189,22 @@
+ 
+ /* Try to lock the named lock variable.  */
+ #if !defined NOT_IN_libc || defined IS_IN_libpthread
+-# ifndef __libc_lock_trylock
+-#  define __libc_lock_trylock(NAME) \
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern int __libc_lock_trylock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_trylock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
++#  ifndef __libc_lock_trylock
++#   define __libc_lock_trylock(NAME) \
+   lll_trylock (NAME)
+-# endif
++#  endif
++# else
++# define __libc_lock_trylock(NAME) \
++  __libc_lock_trylock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # undef __libc_lock_trylock
+ # define __libc_lock_trylock(NAME) \
+@@ -194,8 +220,20 @@
+ 
+ /* Unlock the named lock variable.  */
+ #if !defined NOT_IN_libc || defined IS_IN_libpthread
++# if __OPTION_EGLIBC_BIG_MACROS != 1
++/* EGLIBC: Declare wrapper function for a big macro if either
++   !__OPTION_EGLIBC_BIG_MACROS, or we are using a back door from
++   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS == 2).  */
++extern void __libc_lock_unlock_fn (__libc_lock_t *);
++libc_hidden_proto (__libc_lock_unlock_fn);
++# endif /* __OPTION_EGLIBC_BIG_MACROS != 1 */
++# if __OPTION_EGLIBC_BIG_MACROS
+ # define __libc_lock_unlock(NAME) \
+   lll_unlock (NAME, LLL_PRIVATE)
++# else
++# define __libc_lock_unlock(NAME) \
++  __libc_lock_unlock_fn (&(NAME))
++# endif /* __OPTION_EGLIBC_BIG_MACROS */
+ #else
+ # define __libc_lock_unlock(NAME) \
+   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
+Index: git/sysdeps/nptl/small-macros-fns.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/nptl/small-macros-fns.c	2014-08-29 20:01:15.248070587 -0700
+@@ -0,0 +1,72 @@
++/* EGLIBC: function wrappers for big macros.
++   Copyright (C) 2009 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; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++
++#include <gnu/option-groups.h>
++
++/* Handle macros from ./bits/libc-lock.h.  */
++#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
++
++/* Get the macros for function bodies through a back door.  */
++# undef __OPTION_EGLIBC_BIG_MACROS
++# define __OPTION_EGLIBC_BIG_MACROS 2
++# include <bits/libc-lock.h>
++
++void
++__libc_lock_lock_fn (__libc_lock_t *name)
++{
++  __libc_lock_lock (*name);
++}
++libc_hidden_def (__libc_lock_lock_fn);
++
++void
++__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  __libc_lock_lock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_lock_recursive_fn);
++
++int
++__libc_lock_trylock_fn (__libc_lock_t *name)
++{
++  return __libc_lock_trylock (*name);
++}
++libc_hidden_def (__libc_lock_trylock_fn);
++
++int
++__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  return __libc_lock_trylock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_trylock_recursive_fn);
++
++void
++__libc_lock_unlock_fn (__libc_lock_t *name)
++{
++  __libc_lock_unlock (*name);
++}
++libc_hidden_def (__libc_lock_unlock_fn);
++
++void
++__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name)
++{
++  __libc_lock_unlock_recursive (*name);
++}
++libc_hidden_def (__libc_lock_unlock_recursive_fn);
++
++#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/
+Index: git/crypt/crypt_common.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/crypt/crypt_common.c	2014-08-29 20:01:15.248070587 -0700
+@@ -0,0 +1,42 @@
++/*
++ * crypt: crypt(3) implementation
++ *
++ * Copyright (C) 1991-2014 Free Software Foundation, Inc.
++ *
++ * This 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.
++ *
++ * This 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 this library; see the file COPYING.LIB.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * General Support routines
++ *
++ */
++
++#include "crypt-private.h"
++
++/* Table with characters for base64 transformation.  */
++static const char b64t[64] =
++"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
++
++void
++__b64_from_24bit (char **cp, int *buflen,
++		  unsigned int b2, unsigned int b1, unsigned int b0,
++		  int n)
++{
++  unsigned int w = (b2 << 16) | (b1 << 8) | b0;
++  while (n-- > 0 && (*buflen) > 0)
++    {
++      *(*cp)++ = b64t[w & 0x3f];
++      --(*buflen);
++      w >>= 6;
++    }
++}
+Index: git/crypt/crypt_util.c
+===================================================================
+--- git.orig/crypt/crypt_util.c	2014-08-29 20:00:43.028070587 -0700
++++ git/crypt/crypt_util.c	2014-08-29 20:01:15.248070587 -0700
+@@ -242,10 +242,6 @@
+  */
+ static ufc_long efp[16][64][2];
+ 
+-/* Table with characters for base64 transformation.  */
+-static const char b64t[64] =
+-"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+-
+ /*
+  * For use by the old, non-reentrant routines
+  * (crypt/encrypt/setkey)
+@@ -949,17 +945,3 @@
+ {
+   __setkey_r(__key, &_ufc_foobar);
+ }
+-
+-void
+-__b64_from_24bit (char **cp, int *buflen,
+-		  unsigned int b2, unsigned int b1, unsigned int b0,
+-		  int n)
+-{
+-  unsigned int w = (b2 << 16) | (b1 << 8) | b0;
+-  while (n-- > 0 && (*buflen) > 0)
+-    {
+-      *(*cp)++ = b64t[w & 0x3f];
+-      --(*buflen);
+-      w >>= 6;
+-    }
+-}
+Index: git/sysdeps/arm/Makefile
+===================================================================
+--- git.orig/sysdeps/arm/Makefile	2014-08-29 20:29:37.000000000 -0700
++++ git/sysdeps/arm/Makefile	2014-08-29 20:31:09.904070587 -0700
+@@ -37,10 +37,13 @@
+ # get offset to rtld_global._dl_hwcap
+ gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym
+ aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math
+-aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \
++aeabi_routines = aeabi_assert aeabi_errno_addr \
+ 		 aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \
+ 		 aeabi_memmove aeabi_memset \
+ 		 aeabi_read_tp libc-aeabi_read_tp
++ifeq (y,$(OPTION_EGLIBC_LOCALE_CODE))
++aeabi_routines += aeabi_localeconv
++endif
+ 
+ sysdep_routines += $(aeabi_constants) $(aeabi_routines)
+ static-only-routines += $(aeabi_constants) aeabi_read_tp
diff --git a/recipes-core/glibc/glibc/eglibc.patch b/recipes-core/glibc/glibc/eglibc.patch
new file mode 100644
index 0000000..fdfabc3
--- /dev/null
+++ b/recipes-core/glibc/glibc/eglibc.patch
@@ -0,0 +1,602 @@
+Instruction documents from eglibc
+
+Upstream-Status: Pending
+
+Index: git/EGLIBC.cross-building
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/EGLIBC.cross-building	2014-08-27 07:27:25.580070587 +0000
+@@ -0,0 +1,383 @@
++                                                        -*- mode: text -*-
++
++                        Cross-Compiling EGLIBC
++                  Jim Blandy <jimb@codesourcery.com>
++
++
++Introduction
++
++Most GNU tools have a simple build procedure: you run their
++'configure' script, and then you run 'make'.  Unfortunately, the
++process of cross-compiling the GNU C library is quite a bit more
++involved:
++
++1) Build a cross-compiler, with certain facilities disabled.
++
++2) Configure the C library using the compiler you built in step 1).
++   Build a few of the C run-time object files, but not the rest of the
++   library.  Install the library's header files and the run-time
++   object files, and create a dummy libc.so.
++
++3) Build a second cross-compiler, using the header files and object
++   files you installed in step 2.
++
++4) Configure, build, and install a fresh C library, using the compiler
++   built in step 3.
++
++5) Build a third cross-compiler, based on the C library built in step 4.
++
++The reason for this complexity is that, although GCC and the GNU C
++library are distributed separately, they are not actually independent
++of each other: GCC requires the C library's headers and some object
++files to compile its own libraries, while the C library depends on
++GCC's libraries.  EGLIBC includes features and bug fixes to the stock
++GNU C library that simplify this process, but the fundamental
++interdependency stands.
++
++In this document, we explain how to cross-compile an EGLIBC/GCC pair
++from source.  Our intended audience is developers who are already
++familiar with the GNU toolchain and comfortable working with
++cross-development tools.  While we do present a worked example to
++accompany the explanation, for clarity's sake we do not cover many of
++the options available to cross-toolchain users.
++
++
++Preparation
++
++EGLIBC requires recent versions of the GNU binutils, GCC, and the
++Linux kernel.  The web page <http://www.eglibc.org/prerequisites>
++documents the current requirements, and lists patches needed for
++certain target architectures.  As of this writing, these build
++instructions have been tested with binutils 2.22.51, GCC 4.6.2,
++and Linux 3.1.
++
++First, let's set some variables, to simplify later commands.  We'll
++build EGLIBC and GCC for an ARM target, known to the Linux kernel
++as 'arm', and we'll do the build on an Intel x86_64 Linux box:
++
++    $ build=x86_64-pc-linux-gnu
++    $ host=$build
++    $ target=arm-none-linux-gnueabi
++    $ linux_arch=arm
++
++We're using the aforementioned versions of Binutils, GCC, and Linux:
++
++    $ binutilsv=binutils-2.22.51
++    $ gccv=gcc-4.6.2
++    $ linuxv=linux-3.1
++
++We're carrying out the entire process under '~/cross-build', which
++contains unpacked source trees for binutils, gcc, and linux kernel,
++along with EGLIBC svn trunk (which can be checked-out with
++'svn co http://www.eglibc.org/svn/trunk eglibc'):
++
++    $ top=$HOME/cross-build/$target
++    $ src=$HOME/cross-build/src
++    $ ls $src
++    binutils-2.22.51  eglibc  gcc-4.6.2  linux-3.1
++
++We're going to place our build directories in a subdirectory 'obj',
++we'll install the cross-development toolchain in 'tools', and we'll
++place our sysroot (containing files to be installed on the target
++system) in 'sysroot':
++
++    $ obj=$top/obj
++    $ tools=$top/tools
++    $ sysroot=$top/sysroot
++
++
++Binutils
++
++Configuring and building binutils for the target is straightforward:
++
++    $ mkdir -p $obj/binutils
++    $ cd $obj/binutils
++    $ $src/$binutilsv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --with-sysroot=$sysroot
++    $ make
++    $ make install
++
++
++The First GCC
++
++For our work, we need a cross-compiler targeting an ARM Linux
++system.  However, that configuration includes the shared library
++'libgcc_s.so', which is compiled against the EGLIBC headers (which we
++haven't installed yet) and linked against 'libc.so' (which we haven't
++built yet).
++
++Fortunately, there are configuration options for GCC which tell it not
++to build 'libgcc_s.so'.  The '--without-headers' option is supposed to
++take care of this, but its implementation is incomplete, so you must
++also configure with the '--with-newlib' option.  While '--with-newlib'
++appears to mean "Use the Newlib C library", its effect is to tell the
++GCC build machinery, "Don't assume there is a C library available."
++
++We also need to disable some of the libraries that would normally be
++built along with GCC, and specify that only the compiler for the C
++language is needed.
++
++So, we create a build directory, configure, make, and install.
++
++    $ mkdir -p $obj/gcc1
++    $ cd $obj/gcc1
++    $ $src/$gccv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --without-headers --with-newlib \
++    >     --disable-shared --disable-threads --disable-libssp \
++    >     --disable-libgomp --disable-libmudflap --disable-libquadmath \
++    >     --disable-decimal-float --disable-libffi \
++    >     --enable-languages=c
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install
++
++
++Linux Kernel Headers
++
++To configure EGLIBC, we also need Linux kernel headers in place.
++Fortunately, the Linux makefiles have a target that installs them for
++us.  Since the process does modify the source tree a bit, we make a
++copy first:
++
++    $ cp -r $src/$linuxv $obj/linux
++    $ cd $obj/linux
++
++Now we're ready to install the headers into the sysroot:
++
++    $ PATH=$tools/bin:$PATH \
++    > make headers_install \
++    >      ARCH=$linux_arch CROSS_COMPILE=$target- \
++    >      INSTALL_HDR_PATH=$sysroot/usr
++
++
++EGLIBC Headers and Preliminary Objects
++
++Using the cross-compiler we've just built, we can now configure EGLIBC
++well enough to install the headers and build the object files that the
++full cross-compiler will need:
++
++    $ mkdir -p $obj/eglibc-headers
++    $ cd $obj/eglibc-headers
++    $ BUILD_CC=gcc \
++    > CC=$tools/bin/$target-gcc \
++    > CXX=$tools/bin/$target-g++ \
++    > AR=$tools/bin/$target-ar \
++    > RANLIB=$tools/bin/$target-ranlib \
++    > $src/eglibc/libc/configure \
++    >     --prefix=/usr \
++    >     --with-headers=$sysroot/usr/include \
++    >     --build=$build \
++    >     --host=$target \
++    >     --disable-profile --without-gd --without-cvs \
++    >     --enable-add-ons=nptl,libidn,../ports
++
++The option '--prefix=/usr' may look strange, but you should never
++configure EGLIBC with a prefix other than '/usr': in various places,
++EGLIBC's build system checks whether the prefix is '/usr', and does
++special handling only if that is the case.  Unless you use this
++prefix, you will get a sysroot that does not use the standard Linux
++directory layouts and cannot be used as a basis for the root
++filesystem on your target system compatibly with normal GLIBC
++installations.
++
++The '--with-headers' option tells EGLIBC where the Linux headers have
++been installed.
++
++The '--enable-add-ons=nptl,libidn,../ports' option tells EGLIBC to look
++for the listed glibc add-ons. Most notably the ports add-on (located
++just above the libc sources in the EGLIBC svn tree) is required to
++support ARM targets.
++
++We can now use the 'install-headers' makefile target to install the
++headers:
++
++    $ make install-headers install_root=$sysroot \
++    >                      install-bootstrap-headers=yes
++
++The 'install_root' variable indicates where the files should actually
++be installed; its value is treated as the parent of the '--prefix'
++directory we passed to the configure script, so the headers will go in
++'$sysroot/usr/include'.  The 'install-bootstrap-headers' variable
++requests special handling for certain tricky header files.
++
++Next, there are a few object files needed to link shared libraries,
++which we build and install by hand:
++
++    $ mkdir -p $sysroot/usr/lib
++    $ make csu/subdir_lib
++    $ cp csu/crt1.o csu/crti.o csu/crtn.o $sysroot/usr/lib
++
++Finally, 'libgcc_s.so' requires a 'libc.so' to link against.  However,
++since we will never actually execute its code, it doesn't matter what
++it contains.  So, treating '/dev/null' as a C source file, we produce
++a dummy 'libc.so' in one step:
++
++    $ $tools/bin/$target-gcc -nostdlib -nostartfiles -shared -x c /dev/null \
++    >                        -o $sysroot/usr/lib/libc.so
++
++
++The Second GCC
++
++With the EGLIBC headers and selected object files installed, we can
++now build a GCC that is capable of compiling EGLIBC.  We configure,
++build, and install the second GCC, again building only the C compiler,
++and avoiding libraries we won't use:
++
++    $ mkdir -p $obj/gcc2
++    $ cd $obj/gcc2
++    $ $src/$gccv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --with-sysroot=$sysroot \
++    >     --disable-libssp --disable-libgomp --disable-libmudflap \
++    >     --disable-libffi --disable-libquadmath \
++    >     --enable-languages=c
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install
++
++
++EGLIBC, Complete
++
++With the second compiler built and installed, we're now ready for the
++full EGLIBC build:
++
++    $ mkdir -p $obj/eglibc
++    $ cd $obj/eglibc
++    $ BUILD_CC=gcc \
++    > CC=$tools/bin/$target-gcc \
++    > CXX=$tools/bin/$target-g++ \
++    > AR=$tools/bin/$target-ar \
++    > RANLIB=$tools/bin/$target-ranlib \
++    > $src/eglibc/libc/configure \
++    >     --prefix=/usr \
++    >     --with-headers=$sysroot/usr/include \
++    >     --with-kconfig=$obj/linux/scripts/kconfig \
++    >     --build=$build \
++    >     --host=$target \
++    >     --disable-profile --without-gd --without-cvs \
++    >     --enable-add-ons=nptl,libidn,../ports
++
++Note the additional '--with-kconfig' option. This tells EGLIBC where to
++find the host config tools used by the kernel 'make config' and 'make
++menuconfig'.  These tools can be re-used by EGLIBC for its own 'make
++*config' support, which will create 'option-groups.config' for you.
++But first make sure those tools have been built by running some
++dummy 'make *config' calls in the kernel directory:
++
++    $ cd $obj/linux
++    $ PATH=$tools/bin:$PATH make config \
++    >      ARCH=$linux_arch CROSS_COMPILE=$target- \
++    $ PATH=$tools/bin:$PATH make menuconfig \
++    >      ARCH=$linux_arch CROSS_COMPILE=$target- \
++
++Now we can configure and build the full EGLIBC:
++
++    $ cd $obj/eglibc
++    $ PATH=$tools/bin:$PATH make defconfig
++    $ PATH=$tools/bin:$PATH make menuconfig
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install install_root=$sysroot
++
++At this point, we have a complete EGLIBC installation in '$sysroot',
++with header files, library files, and most of the C runtime startup
++files in place.
++
++
++The Third GCC
++
++Finally, we recompile GCC against this full installation, enabling
++whatever languages and libraries we would like to use:
++
++    $ mkdir -p $obj/gcc3
++    $ cd $obj/gcc3
++    $ $src/$gccv/configure \
++    >     --target=$target \
++    >     --prefix=$tools \
++    >     --with-sysroot=$sysroot \
++    >     --enable-__cxa_atexit \
++    >     --disable-libssp --disable-libgomp --disable-libmudflap \
++    >     --enable-languages=c,c++
++    $ PATH=$tools/bin:$PATH make
++    $ PATH=$tools/bin:$PATH make install
++
++The '--enable-__cxa_atexit' option tells GCC what sort of C++
++destructor support to expect from the C library; it's required with
++EGLIBC.
++
++And since GCC's installation process isn't designed to help construct
++sysroot trees, we must manually copy certain libraries into place in
++the sysroot.
++
++    $ cp -d $tools/$target/lib/libgcc_s.so* $sysroot/lib
++    $ cp -d $tools/$target/lib/libstdc++.so* $sysroot/usr/lib
++
++
++Trying Things Out
++
++At this point, '$tools' contains a cross toolchain ready to use
++the EGLIBC installation in '$sysroot':
++
++    $ cat > hello.c <<EOF
++    > #include <stdio.h>
++    > int
++    > main (int argc, char **argv)
++    > {
++    >   puts ("Hello, world!");
++    >   return 0;
++    > }
++    > EOF
++    $ $tools/bin/$target-gcc -Wall hello.c -o hello
++    $ cat > c++-hello.cc <<EOF
++    > #include <iostream>
++    > int
++    > main (int argc, char **argv)
++    > {
++    >   std::cout << "Hello, C++ world!" << std::endl;
++    >   return 0;
++    > }
++    > EOF
++    $ $tools/bin/$target-g++ -Wall c++-hello.cc -o c++-hello
++
++
++We can use 'readelf' to verify that these are indeed executables for
++our target, using our dynamic linker:
++
++    $ $tools/bin/$target-readelf -hl hello
++    ELF Header:
++    ...
++      Type:                              EXEC (Executable file)
++      Machine:                           ARM
++
++    ...
++    Program Headers:
++      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
++      PHDR           0x000034 0x10000034 0x10000034 0x00100 0x00100 R E 0x4
++      INTERP         0x000134 0x00008134 0x00008134 0x00013 0x00013 R   0x1
++          [Requesting program interpreter: /lib/ld-linux.so.3]
++      LOAD           0x000000 0x00008000 0x00008000 0x0042c 0x0042c R E 0x8000
++    ...
++
++Looking at the dynamic section of the installed 'libgcc_s.so', we see
++that the 'NEEDED' entry for the C library does include the '.6'
++suffix, indicating that was linked against our fully build EGLIBC, and
++not our dummy 'libc.so':
++
++    $ $tools/bin/$target-readelf -d $sysroot/lib/libgcc_s.so.1
++    Dynamic section at offset 0x1083c contains 24 entries:
++      Tag        Type                         Name/Value
++     0x00000001 (NEEDED)                     Shared library: [libc.so.6]
++     0x0000000e (SONAME)                     Library soname: [libgcc_s.so.1]
++    ...
++
++
++And on the target machine, we can run our programs:
++
++    $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \
++    > ./hello
++    Hello, world!
++    $ $sysroot/lib/ld.so.1 --library-path $sysroot/lib:$sysroot/usr/lib \
++    > ./c++-hello
++    Hello, C++ world!
+Index: git/EGLIBC.cross-testing
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/EGLIBC.cross-testing	2014-08-27 07:24:41.532070587 +0000
+@@ -0,0 +1,205 @@
++                                                        -*- mode: text -*-
++
++                      Cross-Testing With EGLIBC
++                  Jim Blandy <jimb@codesourcery.com>
++
++
++Introduction
++
++Developers writing software for embedded systems often use a desktop
++or other similarly capable computer for development, but need to run
++tests on the embedded system, or perhaps on a simulator.  When
++configured for cross-compilation, the stock GNU C library simply
++disables running tests altogether: the command 'make tests' builds
++test programs, but does not run them.  EGLIBC, however, provides
++facilities for compiling tests and generating data files on the build
++system, but running the test programs themselves on a remote system or
++simulator.
++
++
++Test environment requirements
++
++The test environment must meet certain conditions for EGLIBC's
++cross-testing facilities to work:
++
++- Shared filesystems.  The 'build' system, on which you configure and
++  compile EGLIBC, and the 'host' system, on which you intend to run
++  EGLIBC, must share a filesystem containing the EGLIBC build and
++  source trees.  Files must appear at the same paths on both systems.
++
++- Remote-shell like invocation.  There must be a way to run a program
++  on the host system from the build system, passing it properly quoted
++  command-line arguments, setting environment variables, and
++  inheriting the caller's standard input and output.
++
++
++Usage
++
++To use EGLIBC's cross-testing support, provide values for the
++following Make variables when you invoke 'make':
++
++- cross-test-wrapper
++
++  This should be the name of the cross-testing wrapper command, along
++  with any arguments.
++
++- cross-localedef
++
++  This should be the name of a cross-capable localedef program, like
++  that included in the EGLIBC 'localedef' module, along with any
++  arguments needed.
++
++These are each explained in detail below.
++
++
++The Cross-Testing Wrapper
++
++To run test programs reliably, the stock GNU C library takes care to
++ensure that test programs use the newly compiled dynamic linker and
++shared libraries, and never the host system's installed libraries.  To
++accomplish this, it runs the tests by explicitly invoking the dynamic
++linker from the build tree, passing it a list of build tree
++directories to search for shared libraries, followed by the name of
++the executable to run and its arguments.
++
++For example, where one might normally run a test program like this:
++
++    $ ./tst-foo arg1 arg2
++
++the GNU C library might run that program like this:
++
++    $ $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++(where $objdir is the path to the top of the build tree, and the
++trailing backslash indicates a continuation of the command).  In other
++words, each test program invocation is 'wrapped up' inside an explicit
++invocation of the dynamic linker, which must itself execute the test
++program, having loaded shared libraries from the appropriate
++directories.
++
++To support cross-testing, EGLIBC allows the developer to optionally
++set the 'cross-test-wrapper' Make variable to another wrapper command,
++to which it passes the entire dynamic linker invocation shown above as
++arguments.  For example, if the developer supplies a wrapper of
++'my-wrapper hostname', then EGLIBC would run the test above as
++follows:
++
++    $ my-wrapper hostname \
++      $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++The 'my-wrapper' command is responsible for executing the command
++given on the host system.
++
++Since tests are run in varying directories, the wrapper should either
++be in your command search path, or 'cross-test-wrapper' should give an
++absolute path for the wrapper.
++
++The wrapper must meet several requirements:
++
++- It must preserve the current directory.  As explained above, the
++  build directory tree must be visible on both the build and host
++  systems, at the same path.  The test wrapper must ensure that the
++  current directory it inherits is also inherited by the dynamic
++  linker (and thus the test program itself).
++
++- It must preserve environment variables' values.  Many EGLIBC tests
++  set environment variables for test runs; in native testing, it
++  invokes programs like this:
++
++    $ GCONV_PATH=$objdir/iconvdata \
++      $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++  With the cross-testing wrapper, that invocation becomes:
++
++    $ GCONV_PATH=$objdir/iconvdata \
++      my-wrapper hostname \
++      $objdir/elf/ld-linux.so.3 --library-path $objdir \
++      ./tst-foo arg1 arg2
++
++  Here, 'my-wrapper' must ensure that the value it sees for
++  'GCONV_PATH' will be seen by the dynamic linker, and thus 'tst-foo'
++  itself.  (The wrapper supplied with GLIBC simply preserves the
++  values of *all* enviroment variables, with a fixed set of
++  exceptions.)
++
++  If your wrapper is a shell script, take care to correctly propagate
++  environment variables whose values contain spaces and shell
++  metacharacters.
++
++- It must pass the command's arguments, unmodified.  The arguments
++  seen by the test program should be exactly those seen by the wrapper
++  (after whatever arguments are given to the wrapper itself).  The
++  EGLIBC test framework performs all needed shell word splitting and
++  expansion (wildcard expansion, parameter substitution, and so on)
++  before invoking the wrapper; further expansion may break the tests.
++
++
++The 'cross-test-ssh.sh' script
++
++If you want to use 'ssh' (or something sufficiently similar) to run
++test programs on your host system, EGLIBC includes a shell script,
++'scripts/cross-test-ssh.sh', which you can use as your wrapper
++command.  This script takes care of setting the test command's current
++directory, propagating environment variable values, and carrying
++command-line arguments, all across an 'ssh' connection.  You may even
++supply an alternative to 'ssh' on the command line, if needed.
++
++For more details, pass 'cross-test-ssh.sh' the '--help' option.
++
++
++The Cross-Compiling Locale Definition Command
++
++Some EGLIBC tests rely on locales generated especially for the test
++process.  In a native configuration, these tests simply run the
++'localedef' command built by the normal EGLIBC build process,
++'locale/localedef', to process and install their locales.  However, in
++a cross-compiling configuration, this 'localedef' is built for the
++host system, not the build system, and since it requires quite a bit
++of memory to run (we have seen it fail on systems with 64MiB of
++memory), it may not be practical to run it on the host system.
++
++If set, EGLIBC uses the 'cross-localedef' Make variable as the command
++to run on the build system to process and install locales.  The
++localedef program built from the EGLIBC 'localedef' module is
++suitable.
++
++The value of 'cross-localedef' may also include command-line arguments
++to be passed to the program; if you are using EGLIBC's 'localedef',
++you may include endianness and 'uint32_t' alignment arguments here.
++
++
++Example
++
++In developing EGLIBC's cross-testing facility, we invoked 'make' with
++the following script:
++
++    #!/bin/sh
++
++    srcdir=...
++    test_hostname=...
++    localedefdir=...
++    cross_gxx=...-g++
++
++    wrapper="$srcdir/scripts/cross-test-ssh.sh $test_hostname"
++    localedef="$localedefdir/localedef --little-endian --uint32-align=4"
++
++    make cross-test-wrapper="$wrapper" \
++         cross-localedef="$localedef" \
++         CXX="$cross_gxx" \
++         "$@"
++
++
++Other Cross-Testing Concerns
++
++Here are notes on some other issues which you may encounter in running
++the EGLIBC tests in a cross-compiling environment:
++
++- Some tests require a C++ cross-compiler; you should set the 'CXX'
++  Make variable to the name of an appropriate cross-compiler.
++
++- Some tests require access to libstdc++.so.6 and libgcc_s.so.1; we
++  simply place copies of these libraries in the top EGLIBC build
++  directory.
diff --git a/recipes-core/glibc/glibc/etc/ld.so.conf b/recipes-core/glibc/glibc/etc/ld.so.conf
new file mode 100644
index 0000000..e69de29
diff --git a/recipes-core/glibc/glibc/fix-tibetian-locales.patch b/recipes-core/glibc/glibc/fix-tibetian-locales.patch
new file mode 100644
index 0000000..9ab9fdc
--- /dev/null
+++ b/recipes-core/glibc/glibc/fix-tibetian-locales.patch
@@ -0,0 +1,38 @@
+cross localedef fails to compile these locales because name_fmt field is empty
+It is not acceptable for cross localedef and it errors out
+
+LC_NAME: field `name_fmt' not defined
+
+We therefore give a dummy string to the format, the real fix needs some native
+tibetian person to define proper name_fmt
+
+Upstream-Status: Pending
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Index: git/localedata/locales/bo_CN
+===================================================================
+--- git.orig/localedata/locales/bo_CN	2014-08-29 10:35:22.464070587 -0700
++++ git/localedata/locales/bo_CN	2014-08-29 10:35:22.456070587 -0700
+@@ -146,7 +146,7 @@
+ LC_NAME
+ % FIXME
+ 
+-name_fmt  ""
++name_fmt  "FIXME"
+ % name_gen	"FIXME"
+ % name_miss	"FIXME"
+ % name_mr	"FIXME"
+Index: git/localedata/locales/bo_IN
+===================================================================
+--- git.orig/localedata/locales/bo_IN	2014-08-29 10:35:22.464070587 -0700
++++ git/localedata/locales/bo_IN	2014-08-29 10:35:22.456070587 -0700
+@@ -71,7 +71,7 @@
+ 
+ LC_NAME
+ % FIXME
+-name_fmt	""
++name_fmt	"FIXME"
+ % name_gen	"FIXME"
+ % name_miss	"FIXME"
+ % name_mr	"FIXME"
diff --git a/recipes-core/glibc/glibc/fix_am_rootsbindir.patch b/recipes-core/glibc/glibc/fix_am_rootsbindir.patch
new file mode 100644
index 0000000..668e8bf
--- /dev/null
+++ b/recipes-core/glibc/glibc/fix_am_rootsbindir.patch
@@ -0,0 +1,29 @@
+sysdeps/gnu/configure.ac: handle correctly $libc_cv_rootsbindir
+
+Upstream-Status:Pending
+Signed-off-by: Matthieu Crapet <Matthieu.Crapet@ingenico.com>
+
+Index: git/sysdeps/gnu/configure
+===================================================================
+--- git.orig/sysdeps/gnu/configure	2014-08-27 07:24:38.572070587 +0000
++++ git/sysdeps/gnu/configure	2014-08-27 07:24:41.308070587 +0000
+@@ -32,6 +32,6 @@
+   else
+     libc_cv_localstatedir=$localstatedir
+    fi
+-  libc_cv_rootsbindir=/sbin
++  test -n "$libc_cv_rootsbindir" || libc_cv_rootsbindir=/sbin
+   ;;
+ esac
+Index: git/sysdeps/gnu/configure.ac
+===================================================================
+--- git.orig/sysdeps/gnu/configure.ac	2014-08-27 07:24:38.572070587 +0000
++++ git/sysdeps/gnu/configure.ac	2014-08-27 07:24:41.308070587 +0000
+@@ -21,6 +21,6 @@
+   else
+     libc_cv_localstatedir=$localstatedir
+    fi
+-  libc_cv_rootsbindir=/sbin
++  test -n "$libc_cv_rootsbindir" || libc_cv_rootsbindir=/sbin
+   ;;
+ esac
diff --git a/recipes-core/glibc/glibc/fsl-ppc-no-fsqrt.patch b/recipes-core/glibc/glibc/fsl-ppc-no-fsqrt.patch
new file mode 100644
index 0000000..f88eaf4
--- /dev/null
+++ b/recipes-core/glibc/glibc/fsl-ppc-no-fsqrt.patch
@@ -0,0 +1,100 @@
+Create e5500 specific math_private.h and let it include when compiling for e5500/64bit core
+We prefefine __CPU_HAS_FSQRT to 0 and then in general ppc64 math_private.h we check if its
+already defined before redefining it. This way we can ensure that on e5500 builds it wont
+emit fsqrt intructions
+
+-Khem
+
+Upstream-Status: Pending
+
+Index: git/sysdeps/powerpc/fpu/math_private.h
+===================================================================
+--- git.orig/sysdeps/powerpc/fpu/math_private.h	2014-08-29 10:31:30.224070587 -0700
++++ git/sysdeps/powerpc/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -25,10 +25,12 @@
+ #include <fenv_private.h>
+ #include_next <math_private.h>
+ 
+-# if __WORDSIZE == 64 || defined _ARCH_PWR4
+-#  define __CPU_HAS_FSQRT 1
+-# else
+-#  define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
++# ifndef __CPU_HAS_FSQRT
++#  if __WORDSIZE == 64 || defined _ARCH_PWR4
++#   define __CPU_HAS_FSQRT 1
++#  else
++#   define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
++#  endif
+ # endif
+ 
+ extern double __slow_ieee754_sqrt (double);
+Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e5500/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E5500_MATH_PRIVATE_H_
++#define _E5500_MATH_PRIVATE_H_ 1
++/* E5500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E5500_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e6500/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E6500_MATH_PRIVATE_H_
++#define _E6500_MATH_PRIVATE_H_ 1
++/* E6500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E6500_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/math_private.h	2014-08-29 10:31:30.212070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E500MC_MATH_PRIVATE_H_
++#define _E500MC_MATH_PRIVATE_H_ 1
++/* E500MC core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E500MC_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e5500/fpu/math_private.h	2014-08-29 10:31:30.216070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E5500_MATH_PRIVATE_H_
++#define _E5500_MATH_PRIVATE_H_ 1
++/* E5500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E5500_MATH_PRIVATE_H_ */
+Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/math_private.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e6500/fpu/math_private.h	2014-08-29 10:31:30.216070587 -0700
+@@ -0,0 +1,9 @@
++#ifndef _E6500_MATH_PRIVATE_H_
++#define _E6500_MATH_PRIVATE_H_ 1
++/* E6500 core FPU does not implement
++   fsqrt */
++
++#define __CPU_HAS_FSQRT 0
++#include_next <math_private.h>
++
++#endif /* _E6500_MATH_PRIVATE_H_ */
diff --git a/recipes-core/glibc/glibc/generate-supported.mk b/recipes-core/glibc/glibc/generate-supported.mk
new file mode 100644
index 0000000..d2a28c2
--- /dev/null
+++ b/recipes-core/glibc/glibc/generate-supported.mk
@@ -0,0 +1,11 @@
+#!/usr/bin/make
+
+include $(IN)
+
+all:
+	rm -f $(OUT)
+	touch $(OUT)
+	for locale in $(SUPPORTED-LOCALES); do \
+		[ $$locale = true ] && continue; \
+		echo $$locale | sed 's,/, ,' >> $(OUT); \
+	done
diff --git a/recipes-core/glibc/glibc/glibc.fix_sqrt2.patch b/recipes-core/glibc/glibc/glibc.fix_sqrt2.patch
new file mode 100644
index 0000000..f5ed1bf
--- /dev/null
+++ b/recipes-core/glibc/glibc/glibc.fix_sqrt2.patch
@@ -0,0 +1,1516 @@
+Signed-of-by: Edmar Wienskoski <edmar@freescale.com>
+Upstream-Status: Pending
+
+Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c	2014-08-29 10:34:07.768070587 -0700
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c	2014-08-29 10:34:07.768070587 -0700
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c	2014-08-29 10:34:07.768070587 -0700
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c	2014-08-29 10:34:07.772070587 -0700
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c	2014-08-29 10:34:07.776070587 -0700
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 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 <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l & FE_INVALID) == 0)
++#endif
++	feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies	2014-08-29 10:34:07.776070587 -0700
+@@ -0,0 +1 @@
++powerpc/powerpc32/603e/fpu
+Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e300c3/fpu/Implies	2014-08-29 10:34:07.776070587 -0700
+@@ -0,0 +1,2 @@
++# e300c3 is a variant of 603e so use the same optimizations for sqrt
++powerpc/powerpc32/603e/fpu
+Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e500mc/fpu/Implies	2014-08-29 10:34:07.776070587 -0700
+@@ -0,0 +1 @@
++powerpc/powerpc32/e500mc/fpu
+Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e5500/fpu/Implies	2014-08-29 10:34:07.776070587 -0700
+@@ -0,0 +1 @@
++powerpc/powerpc32/e5500/fpu
+Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/powerpc32/e6500/fpu/Implies	2014-08-29 10:34:07.776070587 -0700
+@@ -0,0 +1 @@
++powerpc/powerpc32/e6500/fpu
+Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies	2014-08-29 10:34:07.780070587 -0700
+@@ -0,0 +1 @@
++powerpc/powerpc64/e5500/fpu
+Index: git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/sysdeps/unix/sysv/linux/powerpc/powerpc64/e6500/fpu/Implies	2014-08-29 10:34:07.780070587 -0700
+@@ -0,0 +1 @@
++powerpc/powerpc64/e6500/fpu
diff --git a/recipes-core/glibc/glibc/grok_gold.patch b/recipes-core/glibc/glibc/grok_gold.patch
new file mode 100644
index 0000000..26875c7
--- /dev/null
+++ b/recipes-core/glibc/glibc/grok_gold.patch
@@ -0,0 +1,34 @@
+Make ld --version output matching grok gold's output
+
+adapted from from upstream branch roland/gold-vs-libc
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Backport
+
+
+Index: git/configure
+===================================================================
+--- git.orig/configure	2014-08-29 10:32:34.464070587 -0700
++++ git/configure	2014-08-29 10:32:34.456070587 -0700
+@@ -4592,7 +4592,7 @@
+   # Found it, now check the version.
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5
+ $as_echo_n "checking version of $LD... " >&6; }
+-  ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
++  ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU [Bbinutilsd][^.]* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'`
+   case $ac_prog_version in
+     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
+     2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*)
+Index: git/configure.ac
+===================================================================
+--- git.orig/configure.ac	2014-08-29 10:32:34.464070587 -0700
++++ git/configure.ac	2014-08-29 10:32:34.460070587 -0700
+@@ -930,7 +930,7 @@
+ 		  [GNU assembler.* \([0-9]*\.[0-9.]*\)],
+ 		  [2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*], AS=: critic_missing="$critic_missing as")
+ AC_CHECK_PROG_VER(LD, $LD, --version,
+-		  [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)],
++		  [GNU [Bbinutilsd][^.]* \([0-9][0-9]*\.[0-9.]*\)],
+ 		  [2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*], LD=: critic_missing="$critic_missing ld")
+ 
+ # These programs are version sensitive.
diff --git a/recipes-core/glibc/glibc/initgroups_keys.patch b/recipes-core/glibc/glibc/initgroups_keys.patch
new file mode 100644
index 0000000..32aa15a
--- /dev/null
+++ b/recipes-core/glibc/glibc/initgroups_keys.patch
@@ -0,0 +1,20 @@
+This is needed since initgroups belongs to NET group
+so when NET is disabled in eglibc build then it reports
+as undefined symbol
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Pending
+
+Index: git/nss/getent.c
+===================================================================
+--- git.orig/nss/getent.c	2014-08-27 05:15:25.996070587 +0000
++++ git/nss/getent.c	2014-08-27 05:16:00.048070587 +0000
+@@ -879,7 +879,7 @@
+ D(group)
+ D(gshadow)
+ D(hosts)
+-D(initgroups)
++DN(initgroups)
+ D(netgroup)
+ D(networks)
+ D(passwd)
diff --git a/recipes-core/glibc/glibc/intl-Merge-with-gettext-version-0.19.3.patch b/recipes-core/glibc/glibc/intl-Merge-with-gettext-version-0.19.3.patch
new file mode 100644
index 0000000..f2eea97
--- /dev/null
+++ b/recipes-core/glibc/glibc/intl-Merge-with-gettext-version-0.19.3.patch
@@ -0,0 +1,4797 @@
+From 7c159401dd735baa3206eb3e3bd28ebe6b239b08 Mon Sep 17 00:00:00 2001
+From: Will Newton <will.newton@linaro.org>
+Date: Wed, 10 Dec 2014 12:03:53 +0000
+Subject: [PATCH] intl: Merge with gettext version 0.19.3
+
+This patch merges the latest release of gettext into the intl
+subdirectory. The initial motivation was to include the plural.y
+changes which enable building with bison 3.0, but the majority
+of the other changes are merely cosmetic so it seemed like merging
+the whole directory was simpler than trying to take it piecemeal.
+
+The merge was done by copying across the latext gettext code and
+adding in a few small glibc changes that have been added over the
+years that seemed beneficial, as well as a couple of small build
+fixes that should be merged back to gettext. I also reverted the
+gettext commit:
+
+commit 279b57fc367251666f00e8e2b599b83703451afb
+Author: Bruno Haible <bruno@clisp.org>
+Date:   Fri Jun 14 12:03:49 2002 +0000
+
+    Make absolute pathnames inside $LANGUAGE work.
+
+As it caused localedata/tst-setlocale3 to fail and it wasn't clear
+that glibc wanted that behaviour.
+
+The merge has dropped many uses of __glibc_likely/unlikely. This is
+intentional given that it eases merging. It seems to me that the cost
+of continually rewriting these lines when merging and the risk of adding
+bugs when doing so outweighs the benefits of using these macros when
+code is shared with another project.
+
+Tested with make check on x86_64.
+
+ChangeLog:
+
+2014-12-11  Will Newton  <will.newton@linaro.org>
+
+	Merge gettext 0.19.3 into intl/.
+
+	This involves a number of cosmetic changes to comments
+	and ANSI function definitions and prototypes throughout
+	all the files. The gettext copyright header is used but
+	with the date ranges taken from the glibc copy.
+
+	* NEWS: Add gettext merge to 2.21.
+	* intl/bindtextdom.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	Use gl_* locking primitives rather than __libc_* ones.
+	Use __builtin_expect rather than __glibc_likely/unlikely.
+	* intl/dcgettext.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	* intl/dcigettext.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	(INTDIV0_RAISES_SIGFPE): New define.
+	Use gl_* locking primitives rather than __libc_* ones.
+	Include eval-plural.h instead of plural-eval.c.
+	Use __builtin_expect rather than __glibc_likely/unlikely.
+	* intl/dcngettext.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	* intl/dgettext.c: Likewise.
+	* intl/dngettext.c: Likewise.
+	* intl/plural-eval.c: Renamed to...
+	* intl/eval-plural.h: ...this.
+	* intl/explodename.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	(_nl_explode_name): Use strchr instead of __rawmemchr.
+	* intl/finddomain.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	Use gl_* locking primitives rather than __libc_* ones.
+	(_nl_find_domain): Use malloc rather than alloca for
+	allocation of temporary locale name.
+	* intl/gettext.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	* intl/gettextP.h: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	Use gl_* locking primitives rather than __libc_* ones.
+	* intl/gmo.h: Switch to gettext copyright.
+	(struct sysdep_string): Move struct segment_pair outside of
+	struct definition.
+	* intl/hash-string.c: Use ANSI definitions and prototypes.
+	* intl/hash-string.h: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	* intl/l10nflist.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	(_nl_normalize_codeset): Avoid integer overflow.
+	* intl/loadinfo.h: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	(LIBINTL_DLL_EXPORTED): New define.
+	(PATH_SEPARATOR): New define.
+	* intl/loadmsgcat.c: Switch to gettext copyright.
+	* intl/localealias.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	(_nl_expand_alias): Use PATH_SEPARATOR.
+	* intl/ngettext.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	* intl/plural-exp.c: Likewise.
+	* intl/plural-exp.h: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	(struct expression): Move definition of enum operator outside
+	of struct definition.
+	* intl/plural.c: Regenerate.
+	* intl/plural.y: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	Port to bison 3.0.
+	* intl/textdomain.c: Switch to gettext copyright.
+	Use ANSI definitions and prototypes.
+	Use gl_* locking primitives rather than __libc_* ones.
+---
+ intl/bindtextdom.c |  92 ++----
+ intl/dcgettext.c   |  25 +-
+ intl/dcigettext.c  | 851 +++++++++++++++++++++++++++++++++--------------------
+ intl/dcngettext.c  |  29 +-
+ intl/dgettext.c    |  27 +-
+ intl/dngettext.c   |  30 +-
+ intl/eval-plural.h | 106 +++++++
+ intl/explodename.c |  44 ++-
+ intl/finddomain.c  |  75 +++--
+ intl/gettext.c     |  23 +-
+ intl/gettextP.h    | 235 +++++++++------
+ intl/gmo.h         |  39 +--
+ intl/hash-string.c |   8 +-
+ intl/hash-string.h |  41 ++-
+ intl/l10nflist.c   | 108 +++----
+ intl/loadinfo.h    | 116 +++++---
+ intl/loadmsgcat.c  |  20 +-
+ intl/localealias.c | 186 +++++++-----
+ intl/ngettext.c    |  25 +-
+ intl/plural-eval.c | 100 -------
+ intl/plural-exp.c  |  30 +-
+ intl/plural-exp.h  | 104 +++----
+ intl/plural.c      | 190 ++++++------
+ intl/plural.y      |  98 +++---
+ intl/textdomain.c  |  55 ++--
+ 25 files changed, 1447 insertions(+), 1210 deletions(-)
+ create mode 100644 intl/eval-plural.h
+ delete mode 100644 intl/plural-eval.c
+
+diff --git a/intl/bindtextdom.c b/intl/bindtextdom.c
+index c362496..29a1b12 100644
+--- a/intl/bindtextdom.c
++++ b/intl/bindtextdom.c
+@@ -1,20 +1,18 @@
+ /* Implementation of the bindtextdomain(3) function
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -24,29 +22,21 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include "gettextP.h"
+ #ifdef _LIBC
+ # include <libintl.h>
+ #else
+ # include "libgnuintl.h"
+ #endif
+-#include "gettextP.h"
+ 
++/* Handle multi-threaded applications.  */
+ #ifdef _LIBC
+-/* We have to handle multi-threaded applications.  */
+ # include <bits/libc-lock.h>
++# define gl_rwlock_define __libc_rwlock_define
++# define gl_rwlock_wrlock __libc_rwlock_wrlock
++# define gl_rwlock_unlock __libc_rwlock_unlock
+ #else
+-/* Provide dummy implementation if this is outside glibc.  */
+-# define __libc_rwlock_define(CLASS, NAME)
+-# define __libc_rwlock_wrlock(NAME)
+-# define __libc_rwlock_unlock(NAME)
+-#endif
+-
+-/* The internal variables in the standalone libintl.a must have different
+-   names than the internal variables in GNU libc, otherwise programs
+-   using libintl.a cannot be linked statically.  */
+-#if !defined _LIBC
+-# define _nl_default_dirname libintl_nl_default_dirname
+-# define _nl_domain_bindings libintl_nl_domain_bindings
++# include "lock.h"
+ #endif
+ 
+ /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>.  */
+@@ -56,17 +46,8 @@
+ 
+ /* @@ end of prolog @@ */
+ 
+-/* Contains the default location of the message catalogs.  */
+-extern const char _nl_default_dirname[];
+-#ifdef _LIBC
+-libc_hidden_proto (_nl_default_dirname)
+-#endif
+-
+-/* List with bindings of specific domains.  */
+-extern struct binding *_nl_domain_bindings;
+-
+ /* Lock variable to protect the global data in the gettext implementation.  */
+-__libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
++gl_rwlock_define (extern, _nl_state_lock attribute_hidden)
+ 
+ 
+ /* Names for the libintl functions are a problem.  They must not clash
+@@ -84,11 +65,6 @@ __libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
+ # define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset
+ #endif
+ 
+-/* Prototypes for local functions.  */
+-static void set_binding_values PARAMS ((const char *domainname,
+-					const char **dirnamep,
+-					const char **codesetp));
+-
+ /* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP
+    to be used for the DOMAINNAME message catalog.
+    If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not
+@@ -96,10 +72,8 @@ static void set_binding_values PARAMS ((const char *domainname,
+    If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither
+    modified nor returned.  */
+ static void
+-set_binding_values (domainname, dirnamep, codesetp)
+-     const char *domainname;
+-     const char **dirnamep;
+-     const char **codesetp;
++set_binding_values (const char *domainname,
++		    const char **dirnamep, const char **codesetp)
+ {
+   struct binding *binding;
+   int modified;
+@@ -114,7 +88,7 @@ set_binding_values (domainname, dirnamep, codesetp)
+       return;
+     }
+ 
+-  __libc_rwlock_wrlock (_nl_state_lock);
++  gl_rwlock_wrlock (_nl_state_lock);
+ 
+   modified = 0;
+ 
+@@ -158,12 +132,12 @@ set_binding_values (domainname, dirnamep, codesetp)
+ #else
+ 		      size_t len = strlen (dirname) + 1;
+ 		      result = (char *) malloc (len);
+-		      if (__glibc_likely (result != NULL))
++		      if (__builtin_expect (result != NULL, 1))
+ 			memcpy (result, dirname, len);
+ #endif
+ 		    }
+ 
+-		  if (__glibc_likely (result != NULL))
++		  if (__builtin_expect (result != NULL, 1))
+ 		    {
+ 		      if (binding->dirname != _nl_default_dirname)
+ 			free (binding->dirname);
+@@ -196,11 +170,11 @@ set_binding_values (domainname, dirnamep, codesetp)
+ #else
+ 		  size_t len = strlen (codeset) + 1;
+ 		  result = (char *) malloc (len);
+-		  if (__glibc_likely (result != NULL))
++		  if (__builtin_expect (result != NULL, 1))
+ 		    memcpy (result, codeset, len);
+ #endif
+ 
+-		  if (__glibc_likely (result != NULL))
++		  if (__builtin_expect (result != NULL, 1))
+ 		    {
+ 		      free (binding->codeset);
+ 
+@@ -228,7 +202,7 @@ set_binding_values (domainname, dirnamep, codesetp)
+       struct binding *new_binding =
+ 	(struct binding *) malloc (offsetof (struct binding, domainname) + len);
+ 
+-      if (__glibc_unlikely (new_binding == NULL))
++      if (__builtin_expect (new_binding == NULL, 0))
+ 	goto failed;
+ 
+       memcpy (new_binding->domainname, domainname, len);
+@@ -249,12 +223,12 @@ set_binding_values (domainname, dirnamep, codesetp)
+ 		  char *result;
+ #if defined _LIBC || defined HAVE_STRDUP
+ 		  result = strdup (dirname);
+-		  if (__glibc_unlikely (result == NULL))
++		  if (__builtin_expect (result == NULL, 0))
+ 		    goto failed_dirname;
+ #else
+ 		  size_t len = strlen (dirname) + 1;
+ 		  result = (char *) malloc (len);
+-		  if (__glibc_unlikely (result == NULL))
++		  if (__builtin_expect (result == NULL, 0))
+ 		    goto failed_dirname;
+ 		  memcpy (result, dirname, len);
+ #endif
+@@ -278,12 +252,12 @@ set_binding_values (domainname, dirnamep, codesetp)
+ 
+ #if defined _LIBC || defined HAVE_STRDUP
+ 	      result = strdup (codeset);
+-	      if (__glibc_unlikely (result == NULL))
++	      if (__builtin_expect (result == NULL, 0))
+ 		goto failed_codeset;
+ #else
+ 	      size_t len = strlen (codeset) + 1;
+ 	      result = (char *) malloc (len);
+-	      if (__glibc_unlikely (result == NULL))
++	      if (__builtin_expect (result == NULL, 0))
+ 		goto failed_codeset;
+ 	      memcpy (result, codeset, len);
+ #endif
+@@ -335,15 +309,13 @@ set_binding_values (domainname, dirnamep, codesetp)
+   if (modified)
+     ++_nl_msg_cat_cntr;
+ 
+-  __libc_rwlock_unlock (_nl_state_lock);
++  gl_rwlock_unlock (_nl_state_lock);
+ }
+ 
+ /* Specify that the DOMAINNAME message catalog will be found
+    in DIRNAME rather than in the system locale data base.  */
+ char *
+-BINDTEXTDOMAIN (domainname, dirname)
+-     const char *domainname;
+-     const char *dirname;
++BINDTEXTDOMAIN (const char *domainname, const char *dirname)
+ {
+   set_binding_values (domainname, &dirname, NULL);
+   return (char *) dirname;
+@@ -352,9 +324,7 @@ BINDTEXTDOMAIN (domainname, dirname)
+ /* Specify the character encoding in which the messages from the
+    DOMAINNAME message catalog will be returned.  */
+ char *
+-BIND_TEXTDOMAIN_CODESET (domainname, codeset)
+-     const char *domainname;
+-     const char *codeset;
++BIND_TEXTDOMAIN_CODESET (const char *domainname, const char *codeset)
+ {
+   set_binding_values (domainname, NULL, &codeset);
+   return (char *) codeset;
+diff --git a/intl/dcgettext.c b/intl/dcgettext.c
+index 4daae55..95dccad 100644
+--- a/intl/dcgettext.c
++++ b/intl/dcgettext.c
+@@ -1,20 +1,18 @@
+ /* Implementation of the dcgettext(3) function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -44,10 +42,7 @@
+ /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+    locale.  */
+ char *
+-DCGETTEXT (domainname, msgid, category)
+-     const char *domainname;
+-     const char *msgid;
+-     int category;
++DCGETTEXT (const char *domainname, const char *msgid, int category)
+ {
+   return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category);
+ }
+diff --git a/intl/dcigettext.c b/intl/dcigettext.c
+index 723dd7e..7af4a76 100644
+--- a/intl/dcigettext.c
++++ b/intl/dcigettext.c
+@@ -1,20 +1,18 @@
+ /* Implementation of the internal dcigettext function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ /* Tell glibc's <string.h> to provide a prototype for mempcpy().
+    This must come before <config.h> because <config.h> may include
+@@ -33,14 +31,19 @@
+ # define alloca __builtin_alloca
+ # define HAVE_ALLOCA 1
+ #else
+-# if defined HAVE_ALLOCA_H || defined _LIBC
+-#  include <alloca.h>
++# ifdef _MSC_VER
++#  include <malloc.h>
++#  define alloca _alloca
+ # else
+-#  ifdef _AIX
+- #pragma alloca
++#  if defined HAVE_ALLOCA_H || defined _LIBC
++#   include <alloca.h>
+ #  else
+-#   ifndef alloca
++#   ifdef _AIX
++ #pragma alloca
++#   else
++#    ifndef alloca
+ char *alloca ();
++#    endif
+ #   endif
+ #  endif
+ # endif
+@@ -64,30 +67,49 @@ extern int errno;
+ 
+ #include <locale.h>
+ 
++#ifdef _LIBC
++  /* Guess whether integer division by zero raises signal SIGFPE.
++     Set to 1 only if you know for sure.  In case of doubt, set to 0.  */
++# if defined __alpha__ || defined __arm__ || defined __i386__ \
++     || defined __m68k__ || defined __s390__
++#  define INTDIV0_RAISES_SIGFPE 1
++# else
++#  define INTDIV0_RAISES_SIGFPE 0
++# endif
++#endif
++#if !INTDIV0_RAISES_SIGFPE
++# include <signal.h>
++#endif
++
+ #if defined HAVE_SYS_PARAM_H || defined _LIBC
+ # include <sys/param.h>
+ #endif
+ 
++#if !defined _LIBC
++# include "localcharset.h"
++#endif
++
+ #include "gettextP.h"
+ #include "plural-exp.h"
+ #ifdef _LIBC
+ # include <libintl.h>
+ #else
++# ifdef IN_LIBGLOCALE
++#  include <libintl.h>
++# endif
+ # include "libgnuintl.h"
+ #endif
+ #include "hash-string.h"
+ 
+-/* Thread safetyness.  */
++/* Handle multi-threaded applications.  */
+ #ifdef _LIBC
+ # include <bits/libc-lock.h>
++# define gl_rwlock_define_initialized __libc_rwlock_define_initialized
++# define gl_rwlock_rdlock __libc_rwlock_rdlock
++# define gl_rwlock_wrlock __libc_rwlock_wrlock
++# define gl_rwlock_unlock __libc_rwlock_unlock
+ #else
+-/* Provide dummy implementation if this is outside glibc.  */
+-# define __libc_lock_define_initialized(CLASS, NAME)
+-# define __libc_lock_lock(NAME)
+-# define __libc_lock_unlock(NAME)
+-# define __libc_rwlock_define_initialized(CLASS, NAME)
+-# define __libc_rwlock_rdlock(NAME)
+-# define __libc_rwlock_unlock(NAME)
++# include "lock.h"
+ #endif
+ 
+ /* Alignment of types.  */
+@@ -98,16 +120,6 @@ extern int errno;
+     ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2)
+ #endif
+ 
+-/* The internal variables in the standalone libintl.a must have different
+-   names than the internal variables in GNU libc, otherwise programs
+-   using libintl.a cannot be linked statically.  */
+-#if !defined _LIBC
+-# define _nl_default_default_domain libintl_nl_default_default_domain
+-# define _nl_current_default_domain libintl_nl_current_default_domain
+-# define _nl_default_dirname libintl_nl_default_dirname
+-# define _nl_domain_bindings libintl_nl_domain_bindings
+-#endif
+-
+ /* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>.  */
+ #ifndef offsetof
+ # define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
+@@ -129,16 +141,36 @@ extern int errno;
+ char *getwd ();
+ #  define getcwd(buf, max) getwd (buf)
+ # else
++#  if VMS
++#   define getcwd(buf, max) (getcwd) (buf, max, 0)
++#  else
+ char *getcwd ();
++#  endif
+ # endif
+ # ifndef HAVE_STPCPY
+-static char *stpcpy PARAMS ((char *dest, const char *src));
++static char *stpcpy (char *dest, const char *src);
+ # endif
+ # ifndef HAVE_MEMPCPY
+-static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
++static void *mempcpy (void *dest, const void *src, size_t n);
+ # endif
+ #endif
+ 
++/* Use a replacement if the system does not provide the `tsearch' function
++   family.  */
++#if defined HAVE_TSEARCH || defined _LIBC
++# include <search.h>
++#else
++# define tsearch libintl_tsearch
++# define tfind libintl_tfind
++# define tdelete libintl_tdelete
++# define twalk libintl_twalk
++# include "tsearch.h"
++#endif
++
++#ifdef _LIBC
++# define tsearch __tsearch
++#endif
++
+ /* Amount to increase buffer size by in each try.  */
+ #define PATH_INCR 32
+ 
+@@ -171,8 +203,30 @@ static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
+ # define PATH_MAX _POSIX_PATH_MAX
+ #endif
+ 
++/* Pathname support.
++   ISSLASH(C)           tests whether C is a directory separator character.
++   IS_ABSOLUTE_PATH(P)  tests whether P is an absolute path.  If it is not,
++                        it may be concatenated to a directory pathname.
++   IS_PATH_WITH_DIR(P)  tests whether P contains a directory specification.
++ */
++#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
++  /* Win32, Cygwin, OS/2, DOS */
++# define ISSLASH(C) ((C) == '/' || (C) == '\\')
++# define HAS_DEVICE(P) \
++    ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
++     && (P)[1] == ':')
++# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
++# define IS_PATH_WITH_DIR(P) \
++    (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
++#else
++  /* Unix */
++# define ISSLASH(C) ((C) == '/')
++# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
++# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
++#endif
++
+ /* Whether to support different locales in different threads.  */
+-#if defined _LIBC || HAVE_NL_LOCALE_NAME
++#if defined _LIBC || HAVE_USELOCALE || defined IN_LIBGLOCALE
+ # define HAVE_PER_THREAD_LOCALE
+ #endif
+ 
+@@ -191,6 +245,11 @@ struct known_translation_t
+   const char *localename;
+ #endif
+ 
++#ifdef IN_LIBGLOCALE
++  /* The character encoding.  */
++  const char *encoding;
++#endif
++
+   /* State of the catalog counter at the point the string was found.  */
+   int counter;
+ 
+@@ -210,23 +269,14 @@ struct known_translation_t
+   msgid;
+ };
+ 
+-/* Root of the search tree with known translations.  We can use this
+-   only if the system provides the `tsearch' function family.  */
+-#if defined HAVE_TSEARCH || defined _LIBC
+-# include <search.h>
++gl_rwlock_define_initialized (static, tree_lock)
+ 
++/* Root of the search tree with known translations.  */
+ static void *root;
+ 
+-# ifdef _LIBC
+-#  define tsearch __tsearch
+-# endif
+-
+ /* Function to compare two entries in the table of known translations.  */
+-static int transcmp PARAMS ((const void *p1, const void *p2));
+ static int
+-transcmp (p1, p2)
+-     const void *p1;
+-     const void *p2;
++transcmp (const void *p1, const void *p2)
+ {
+   const struct known_translation_t *s1;
+   const struct known_translation_t *s2;
+@@ -246,59 +296,83 @@ transcmp (p1, p2)
+ 	  result = strcmp (s1->localename, s2->localename);
+ 	  if (result == 0)
+ #endif
+-	    /* We compare the category last (though this is the cheapest
+-	       operation) since it is hopefully always the same (namely
+-	       LC_MESSAGES).  */
+-	    result = s1->category - s2->category;
++	    {
++#ifdef IN_LIBGLOCALE
++	      result = strcmp (s1->encoding, s2->encoding);
++	      if (result == 0)
++#endif
++		/* We compare the category last (though this is the cheapest
++		   operation) since it is hopefully always the same (namely
++		   LC_MESSAGES).  */
++		result = s1->category - s2->category;
++	    }
+ 	}
+     }
+ 
+   return result;
+ }
+-#endif
+ 
+ /* Name of the default domain used for gettext(3) prior any call to
+    textdomain(3).  The default value for this is "messages".  */
+ const char _nl_default_default_domain[] attribute_hidden = "messages";
+ 
++#ifndef IN_LIBGLOCALE
+ /* Value used as the default domain for gettext(3).  */
+ const char *_nl_current_default_domain attribute_hidden
+      = _nl_default_default_domain;
++#endif
+ 
+ /* Contains the default location of the message catalogs.  */
+-
+-#ifdef _LIBC
++#if defined __EMX__
++extern const char _nl_default_dirname[];
++#else
++# ifdef _LIBC
+ extern const char _nl_default_dirname[];
+ libc_hidden_proto (_nl_default_dirname)
+-#endif
++# endif
+ const char _nl_default_dirname[] = LOCALEDIR;
+-#ifdef _LIBC
++# ifdef _LIBC
+ libc_hidden_data_def (_nl_default_dirname)
++# endif
+ #endif
+ 
++#ifndef IN_LIBGLOCALE
+ /* List with bindings of specific domains created by bindtextdomain()
+    calls.  */
+ struct binding *_nl_domain_bindings;
++#endif
+ 
+ /* Prototypes for local functions.  */
+-static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain,
+-				    unsigned long int n,
+-				    const char *translation,
+-				    size_t translation_len))
++static char *plural_lookup (struct loaded_l10nfile *domain,
++			    unsigned long int n,
++			    const char *translation, size_t translation_len)
++     internal_function;
++
++#ifdef IN_LIBGLOCALE
++static const char *guess_category_value (int category,
++					 const char *categoryname,
++					 const char *localename)
+      internal_function;
+-static const char *guess_category_value PARAMS ((int category,
+-						 const char *categoryname))
++#else
++static const char *guess_category_value (int category,
++					 const char *categoryname)
+      internal_function;
++#endif
++
+ #ifdef _LIBC
+ # include "../locale/localeinfo.h"
+ # define category_to_name(category) \
+   _nl_category_names.str + _nl_category_name_idxs[category]
+ #else
+-static const char *category_to_name PARAMS ((int category)) internal_function;
++static const char *category_to_name (int category) internal_function;
++#endif
++#if (defined _LIBC || HAVE_ICONV) && !defined IN_LIBGLOCALE
++static const char *get_output_charset (struct binding *domainbinding)
++     internal_function;
+ #endif
+ 
+ 
+-/* For those loosing systems which don't have `alloca' we have to add
++/* For those losing systems which don't have `alloca' we have to add
+    some additional code emulating it.  */
+ #ifdef HAVE_ALLOCA
+ /* Nothing has to be done.  */
+@@ -348,10 +422,6 @@ static struct transmem_list *transmem_list;
+ #else
+ typedef unsigned char transmem_block_t;
+ #endif
+-#if defined _LIBC || HAVE_ICONV
+-static const char *get_output_charset PARAMS ((struct binding *domainbinding))
+-     internal_function;
+-#endif
+ 
+ 
+ /* Names for the libintl functions are a problem.  They must not clash
+@@ -365,9 +435,7 @@ static const char *get_output_charset PARAMS ((struct binding *domainbinding))
+ #endif
+ 
+ /* Lock variable to protect the global data in the gettext implementation.  */
+-#ifdef _LIBC
+-__libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden)
+-#endif
++gl_rwlock_define_initialized (, _nl_state_lock attribute_hidden)
+ 
+ /* Checking whether the binaries runs SUID must be done and glibc provides
+    easier methods therefore we make a difference here.  */
+@@ -400,19 +468,23 @@ static int enable_secure;
+ #endif
+ 
+ /* Get the function to evaluate the plural expression.  */
+-#include "plural-eval.c"
++#include "eval-plural.h"
+ 
+ /* Look up MSGID in the DOMAINNAME message catalog for the current
+    CATEGORY locale and, if PLURAL is nonzero, search over string
+    depending on the plural form determined by N.  */
++#ifdef IN_LIBGLOCALE
+ char *
+-DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+-     const char *domainname;
+-     const char *msgid1;
+-     const char *msgid2;
+-     int plural;
+-     unsigned long int n;
+-     int category;
++gl_dcigettext (const char *domainname,
++	       const char *msgid1, const char *msgid2,
++	       int plural, unsigned long int n,
++	       int category,
++	       const char *localename, const char *encoding)
++#else
++char *
++DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
++	    int plural, unsigned long int n, int category)
++#endif
+ {
+ #ifndef HAVE_ALLOCA
+   struct block_list *block_list = NULL;
+@@ -421,17 +493,16 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+   struct binding *binding;
+   const char *categoryname;
+   const char *categoryvalue;
+-  char *dirname, *xdomainname;
++  const char *dirname;
++  char *xdomainname;
+   char *single_locale;
+   char *retval;
+   size_t retlen;
+   int saved_errno;
+-#if defined HAVE_TSEARCH || defined _LIBC
+   struct known_translation_t search;
+   struct known_translation_t **foundp = NULL;
+-# ifdef HAVE_PER_THREAD_LOCALE
++#if defined HAVE_PER_THREAD_LOCALE && !defined IN_LIBGLOCALE
+   const char *localename;
+-# endif
+ #endif
+   size_t domainname_len;
+ 
+@@ -448,12 +519,15 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 	    : n == 1 ? (char *) msgid1 : (char *) msgid2);
+ #endif
+ 
++  /* Preserve the `errno' value.  */
++  saved_errno = errno;
++
+ #ifdef _LIBC
+   __libc_rwlock_define (extern, __libc_setlocale_lock attribute_hidden)
+   __libc_rwlock_rdlock (__libc_setlocale_lock);
+ #endif
+ 
+-  __libc_rwlock_rdlock (_nl_state_lock);
++  gl_rwlock_rdlock (_nl_state_lock);
+ 
+   /* If DOMAINNAME is NULL, we are interested in the default domain.  If
+      CATEGORY is not LC_MESSAGES this might not make much sense but the
+@@ -461,28 +535,42 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+   if (domainname == NULL)
+     domainname = _nl_current_default_domain;
+ 
+-#if defined HAVE_TSEARCH || defined _LIBC
++  /* OS/2 specific: backward compatibility with older libintl versions  */
++#ifdef LC_MESSAGES_COMPAT
++  if (category == LC_MESSAGES_COMPAT)
++    category = LC_MESSAGES;
++#endif
++
+   /* Try to find the translation among those which we found at
+      some time.  */
+   search.domain = NULL;
+   search.msgid.ptr = msgid1;
+   search.domainname = domainname;
+   search.category = category;
+-# ifdef HAVE_PER_THREAD_LOCALE
++#ifdef HAVE_PER_THREAD_LOCALE
++# ifndef IN_LIBGLOCALE
+ #  ifdef _LIBC
+   localename = strdupa (__current_locale_name (category));
++#  else
++  categoryname = category_to_name (category);
++#   define CATEGORYNAME_INITIALIZED
++  localename = _nl_locale_name_thread_unsafe (category, categoryname);
++  if (localename == NULL)
++    localename = "";
+ #  endif
++# endif
+   search.localename = localename;
++# ifdef IN_LIBGLOCALE
++  search.encoding = encoding;
+ # endif
+ 
+   /* Since tfind/tsearch manage a balanced tree, concurrent tfind and
+      tsearch calls can be fatal.  */
+-  __libc_rwlock_define_initialized (static, tree_lock);
+-  __libc_rwlock_rdlock (tree_lock);
++  gl_rwlock_rdlock (tree_lock);
+ 
+   foundp = (struct known_translation_t **) tfind (&search, &root, transcmp);
+ 
+-  __libc_rwlock_unlock (tree_lock);
++  gl_rwlock_unlock (tree_lock);
+ 
+   if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
+     {
+@@ -493,21 +581,25 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+       else
+ 	retval = (char *) (*foundp)->translation;
+ 
++      gl_rwlock_unlock (_nl_state_lock);
+ # ifdef _LIBC
+       __libc_rwlock_unlock (__libc_setlocale_lock);
+ # endif
+-      __libc_rwlock_unlock (_nl_state_lock);
++      __set_errno (saved_errno);
+       return retval;
+     }
+ #endif
+ 
+-  /* Preserve the `errno' value.  */
+-  saved_errno = errno;
+-
+   /* See whether this is a SUID binary or not.  */
+   DETERMINE_SECURE;
+ 
+   /* First find matching binding.  */
++#ifdef IN_LIBGLOCALE
++  /* We can use a trivial binding, since _nl_find_msg will ignore it anyway,
++     and _nl_load_domain and _nl_find_domain just pass it through.  */
++  binding = NULL;
++  dirname = bindtextdomain (domainname, NULL);
++#else
+   for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
+     {
+       int compare = strcmp (domainname, binding->domainname);
+@@ -523,50 +615,65 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+     }
+ 
+   if (binding == NULL)
+-    dirname = (char *) _nl_default_dirname;
+-  else if (binding->dirname[0] == '/')
+-    dirname = binding->dirname;
++    dirname = _nl_default_dirname;
+   else
+     {
+-      /* We have a relative path.  Make it absolute now.  */
+-      size_t dirname_len = strlen (binding->dirname) + 1;
+-      size_t path_max;
+-      char *ret;
++      dirname = binding->dirname;
++#endif
++      if (!IS_ABSOLUTE_PATH (dirname))
++	{
++	  /* We have a relative path.  Make it absolute now.  */
++	  size_t dirname_len = strlen (dirname) + 1;
++	  size_t path_max;
++	  char *resolved_dirname;
++	  char *ret;
+ 
+-      path_max = (unsigned int) PATH_MAX;
+-      path_max += 2;		/* The getcwd docs say to do this.  */
++	  path_max = (unsigned int) PATH_MAX;
++	  path_max += 2;		/* The getcwd docs say to do this.  */
+ 
+-      for (;;)
+-	{
+-	  dirname = (char *) alloca (path_max + dirname_len);
+-	  ADD_BLOCK (block_list, dirname);
++	  for (;;)
++	    {
++	      resolved_dirname = (char *) alloca (path_max + dirname_len);
++	      ADD_BLOCK (block_list, tmp_dirname);
+ 
+-	  __set_errno (0);
+-	  ret = getcwd (dirname, path_max);
+-	  if (ret != NULL || errno != ERANGE)
+-	    break;
++	      __set_errno (0);
++	      ret = getcwd (resolved_dirname, path_max);
++	      if (ret != NULL || errno != ERANGE)
++		break;
+ 
+-	  path_max += path_max / 2;
+-	  path_max += PATH_INCR;
+-	}
++	      path_max += path_max / 2;
++	      path_max += PATH_INCR;
++	    }
+ 
+-      if (ret == NULL)
+-	goto no_translation;
++	  if (ret == NULL)
++	    /* We cannot get the current working directory.  Don't signal an
++	       error but simply return the default string.  */
++	    goto return_untranslated;
+ 
+-      stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
++	  stpcpy (stpcpy (strchr (resolved_dirname, '\0'), "/"), dirname);
++	  dirname = resolved_dirname;
++	}
++#ifndef IN_LIBGLOCALE
+     }
++#endif
+ 
+   /* Now determine the symbolic name of CATEGORY and its value.  */
++#ifndef CATEGORYNAME_INITIALIZED
+   categoryname = category_to_name (category);
++#endif
++#ifdef IN_LIBGLOCALE
++  categoryvalue = guess_category_value (category, categoryname, localename);
++#else
+   categoryvalue = guess_category_value (category, categoryname);
++#endif
+ 
+   domainname_len = strlen (domainname);
+   xdomainname = (char *) alloca (strlen (categoryname)
+ 				 + domainname_len + 5);
+   ADD_BLOCK (block_list, xdomainname);
+ 
+-  stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
+-		  domainname, domainname_len),
++  stpcpy ((char *) mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
++			    domainname, domainname_len),
+ 	  ".mo");
+ 
+   /* Creating working area.  */
+@@ -599,7 +706,7 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 
+ 	  /* When this is a SUID binary we must not allow accessing files
+ 	     outside the dedicated directories.  */
+-	  if (ENABLE_SECURE && strchr (single_locale, '/') != NULL)
++	  if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale))
+ 	    /* Ingore this entry.  */
+ 	    continue;
+ 	}
+@@ -608,18 +715,7 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 	 domain.  Return the MSGID.  */
+       if (strcmp (single_locale, "C") == 0
+ 	  || strcmp (single_locale, "POSIX") == 0)
+-	{
+-	no_translation:
+-	  FREE_BLOCKS (block_list);
+-	  __libc_rwlock_unlock (__libc_setlocale_lock);
+-	  __libc_rwlock_unlock (_nl_state_lock);
+-	  __set_errno (saved_errno);
+-	  return (plural == 0
+-		  ? (char *) msgid1
+-		  /* Use the Germanic plural rule.  */
+-		  : n == 1 ? (char *) msgid1 : (char *) msgid2);
+-	}
+-
++	break;
+ 
+       /* Find structure describing the message catalog matching the
+ 	 DOMAINNAME and CATEGORY.  */
+@@ -627,7 +723,11 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 
+       if (domain != NULL)
+ 	{
++#if defined IN_LIBGLOCALE
++	  retval = _nl_find_msg (domain, binding, encoding, msgid1, &retlen);
++#else
+ 	  retval = _nl_find_msg (domain, binding, msgid1, 1, &retlen);
++#endif
+ 
+ 	  if (retval == NULL)
+ 	    {
+@@ -635,13 +735,18 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 
+ 	      for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
+ 		{
++#if defined IN_LIBGLOCALE
++		  retval = _nl_find_msg (domain->successor[cnt], binding,
++					 encoding, msgid1, &retlen);
++#else
+ 		  retval = _nl_find_msg (domain->successor[cnt], binding,
+ 					 msgid1, 1, &retlen);
++#endif
+ 
+ 		  /* Resource problems are not fatal, instead we return no
+ 		     translation.  */
+-		  if (__glibc_unlikely (retval == (char *) -1))
+-		    goto no_translation;
++		  if (__builtin_expect (retval == (char *) -1, 0))
++		    goto return_untranslated;
+ 
+ 		  if (retval != NULL)
+ 		    {
+@@ -654,15 +759,14 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 	  /* Returning -1 means that some resource problem exists
+ 	     (likely memory) and that the strings could not be
+ 	     converted.  Return the original strings.  */
+-	  if (__glibc_unlikely (retval == (char *) -1))
+-	    goto no_translation;
++	  if (__builtin_expect (retval == (char *) -1, 0))
++	    break;
+ 
+ 	  if (retval != NULL)
+ 	    {
+ 	      /* Found the translation of MSGID1 in domain DOMAIN:
+ 		 starting at RETVAL, RETLEN bytes.  */
+ 	      FREE_BLOCKS (block_list);
+-#if defined HAVE_TSEARCH || defined _LIBC
+ 	      if (foundp == NULL)
+ 		{
+ 		  /* Create a new entry and add it to the search tree.  */
+@@ -673,41 +777,45 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 		  msgid_len = strlen (msgid1) + 1;
+ 		  size = offsetof (struct known_translation_t, msgid)
+ 			 + msgid_len + domainname_len + 1;
+-# ifdef HAVE_PER_THREAD_LOCALE
++#ifdef HAVE_PER_THREAD_LOCALE
+ 		  size += strlen (localename) + 1;
+-# endif
++#endif
+ 		  newp = (struct known_translation_t *) malloc (size);
+ 		  if (newp != NULL)
+ 		    {
+ 		      char *new_domainname;
+-# ifdef HAVE_PER_THREAD_LOCALE
++#ifdef HAVE_PER_THREAD_LOCALE
+ 		      char *new_localename;
+-# endif
++#endif
+ 
+ 		      new_domainname =
+-			mempcpy (newp->msgid.appended, msgid1, msgid_len);
++			(char *) mempcpy (newp->msgid.appended, msgid1,
++					  msgid_len);
+ 		      memcpy (new_domainname, domainname, domainname_len + 1);
+-# ifdef HAVE_PER_THREAD_LOCALE
++#ifdef HAVE_PER_THREAD_LOCALE
+ 		      new_localename = new_domainname + domainname_len + 1;
+ 		      strcpy (new_localename, localename);
+-# endif
++#endif
+ 		      newp->domainname = new_domainname;
+ 		      newp->category = category;
+-# ifdef HAVE_PER_THREAD_LOCALE
++#ifdef HAVE_PER_THREAD_LOCALE
+ 		      newp->localename = new_localename;
+-# endif
++#endif
++#ifdef IN_LIBGLOCALE
++		      newp->encoding = encoding;
++#endif
+ 		      newp->counter = _nl_msg_cat_cntr;
+ 		      newp->domain = domain;
+ 		      newp->translation = retval;
+ 		      newp->translation_length = retlen;
+ 
+-		      __libc_rwlock_wrlock (tree_lock);
++		      gl_rwlock_wrlock (tree_lock);
+ 
+ 		      /* Insert the entry in the search tree.  */
+ 		      foundp = (struct known_translation_t **)
+ 			tsearch (newp, &root, transcmp);
+ 
+-		      __libc_rwlock_unlock (tree_lock);
++		      gl_rwlock_unlock (tree_lock);
+ 
+ 		      if (foundp == NULL
+ 			  || __builtin_expect (*foundp != newp, 0))
+@@ -723,31 +831,68 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ 		  (*foundp)->translation = retval;
+ 		  (*foundp)->translation_length = retlen;
+ 		}
+-#endif
++
+ 	      __set_errno (saved_errno);
+ 
+ 	      /* Now deal with plural.  */
+ 	      if (plural)
+ 		retval = plural_lookup (domain, n, retval, retlen);
+ 
++	      gl_rwlock_unlock (_nl_state_lock);
++#ifdef _LIBC
+ 	      __libc_rwlock_unlock (__libc_setlocale_lock);
+-	      __libc_rwlock_unlock (_nl_state_lock);
++#endif
+ 	      return retval;
+ 	    }
+ 	}
+     }
+-  /* NOTREACHED */
++
++ return_untranslated:
++  /* Return the untranslated MSGID.  */
++  FREE_BLOCKS (block_list);
++  gl_rwlock_unlock (_nl_state_lock);
++#ifdef _LIBC
++  __libc_rwlock_unlock (__libc_setlocale_lock);
++#endif
++#ifndef _LIBC
++  if (!ENABLE_SECURE)
++    {
++      extern void _nl_log_untranslated (const char *logfilename,
++					const char *domainname,
++					const char *msgid1, const char *msgid2,
++					int plural);
++      const char *logfilename = getenv ("GETTEXT_LOG_UNTRANSLATED");
++
++      if (logfilename != NULL && logfilename[0] != '\0')
++	_nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural);
++    }
++#endif
++  __set_errno (saved_errno);
++  return (plural == 0
++	  ? (char *) msgid1
++	  /* Use the Germanic plural rule.  */
++	  : n == 1 ? (char *) msgid1 : (char *) msgid2);
+ }
+ 
+ 
++/* Look up the translation of msgid within DOMAIN_FILE and DOMAINBINDING.
++   Return it if found.  Return NULL if not found or in case of a conversion
++   failure (problem in the particular message catalog).  Return (char *) -1
++   in case of a memory allocation failure during conversion (only if
++   ENCODING != NULL resp. CONVERT == true).  */
+ char *
+ internal_function
+-_nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+-     struct loaded_l10nfile *domain_file;
+-     struct binding *domainbinding;
+-     const char *msgid;
+-     int convert;
+-     size_t *lengthp;
++#ifdef IN_LIBGLOCALE
++_nl_find_msg (struct loaded_l10nfile *domain_file,
++	      struct binding *domainbinding, const char *encoding,
++	      const char *msgid,
++	      size_t *lengthp)
++#else
++_nl_find_msg (struct loaded_l10nfile *domain_file,
++	      struct binding *domainbinding,
++	      const char *msgid, int convert,
++	      size_t *lengthp)
++#endif
+ {
+   struct loaded_domain *domain;
+   nls_uint32 nstrings;
+@@ -853,19 +998,27 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+     }
+ 
+ #if defined _LIBC || HAVE_ICONV
++# ifdef IN_LIBGLOCALE
++  if (encoding != NULL)
++# else
+   if (convert)
++# endif
+     {
+       /* We are supposed to do a conversion.  */
++# ifndef IN_LIBGLOCALE
+       const char *encoding = get_output_charset (domainbinding);
++# endif
++      size_t nconversions;
++      struct converted_domain *convd;
++      size_t i;
+ 
+       /* Protect against reallocation of the table.  */
+-      __libc_rwlock_rdlock (domain->conversions_lock);
++      gl_rwlock_rdlock (domain->conversions_lock);
+ 
+       /* Search whether a table with converted translations for this
+ 	 encoding has already been allocated.  */
+-      size_t nconversions = domain->nconversions;
+-      struct converted_domain *convd = NULL;
+-      size_t i;
++      nconversions = domain->nconversions;
++      convd = NULL;
+ 
+       for (i = nconversions; i > 0; )
+ 	{
+@@ -877,12 +1030,12 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ 	    }
+ 	}
+ 
+-      __libc_rwlock_unlock (domain->conversions_lock);
++      gl_rwlock_unlock (domain->conversions_lock);
+ 
+       if (convd == NULL)
+ 	{
+ 	  /* We have to allocate a new conversions table.  */
+-	  __libc_rwlock_wrlock (domain->conversions_lock);
++	  gl_rwlock_wrlock (domain->conversions_lock);
+ 	  nconversions = domain->nconversions;
+ 
+ 	  /* Maybe in the meantime somebody added the translation.
+@@ -897,140 +1050,151 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ 		}
+ 	    }
+ 
+-	  /* Allocate a table for the converted translations for this
+-	     encoding.  */
+-	  struct converted_domain *new_conversions =
+-	    (struct converted_domain *)
+-	    realloc (domain->conversions,
+-		     (nconversions + 1) * sizeof (struct converted_domain));
++	  {
++	    /* Allocate a table for the converted translations for this
++	       encoding.  */
++	    struct converted_domain *new_conversions =
++	      (struct converted_domain *)
++	      (domain->conversions != NULL
++	       ? realloc (domain->conversions,
++			  (nconversions + 1) * sizeof (struct converted_domain))
++	       : malloc ((nconversions + 1) * sizeof (struct converted_domain)));
++
++	    if (__builtin_expect (new_conversions == NULL, 0))
++	      {
++		/* Nothing we can do, no more memory.  We cannot use the
++		   translation because it might be encoded incorrectly.  */
++	      unlock_fail:
++		gl_rwlock_unlock (domain->conversions_lock);
++		return (char *) -1;
++	      }
+ 
+-	  if (__glibc_unlikely (new_conversions == NULL))
+-	    {
++	    domain->conversions = new_conversions;
++
++	    /* Copy the 'encoding' string to permanent storage.  */
++	    encoding = strdup (encoding);
++	    if (__builtin_expect (encoding == NULL, 0))
+ 	      /* Nothing we can do, no more memory.  We cannot use the
+ 		 translation because it might be encoded incorrectly.  */
+-	    unlock_fail:
+-	      __libc_rwlock_unlock (domain->conversions_lock);
+-	      return (char *) -1;
+-	    }
+-
+-	  domain->conversions = new_conversions;
+-
+-	  /* Copy the 'encoding' string to permanent storage.  */
+-	  encoding = strdup (encoding);
+-	  if (__glibc_unlikely (encoding == NULL))
+-	    /* Nothing we can do, no more memory.  We cannot use the
+-	       translation because it might be encoded incorrectly.  */
+-	    goto unlock_fail;
++	      goto unlock_fail;
+ 
+-	  convd = &new_conversions[nconversions];
+-	  convd->encoding = encoding;
++	    convd = &new_conversions[nconversions];
++	    convd->encoding = encoding;
+ 
+-	  /* Find out about the character set the file is encoded with.
+-	     This can be found (in textual form) in the entry "".  If this
+-	     entry does not exist or if this does not contain the 'charset='
+-	     information, we will assume the charset matches the one the
+-	     current locale and we don't have to perform any conversion.  */
++	    /* Find out about the character set the file is encoded with.
++	       This can be found (in textual form) in the entry "".  If this
++	       entry does not exist or if this does not contain the 'charset='
++	       information, we will assume the charset matches the one the
++	       current locale and we don't have to perform any conversion.  */
+ # ifdef _LIBC
+-	  convd->conv = (__gconv_t) -1;
++	    convd->conv = (__gconv_t) -1;
+ # else
+ #  if HAVE_ICONV
+-	  convd->conv = (iconv_t) -1;
++	    convd->conv = (iconv_t) -1;
+ #  endif
+ # endif
+-	  {
+-	    char *nullentry;
+-	    size_t nullentrylen;
+-
+-	    /* Get the header entry.  This is a recursion, but it doesn't
+-	       reallocate domain->conversions because we pass convert = 0.  */
+-	    nullentry =
+-	      _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
++	    {
++	      char *nullentry;
++	      size_t nullentrylen;
++
++	      /* Get the header entry.  This is a recursion, but it doesn't
++		 reallocate domain->conversions because we pass
++		 encoding = NULL or convert = 0, respectively.  */
++	      nullentry =
++# ifdef IN_LIBGLOCALE
++		_nl_find_msg (domain_file, domainbinding, NULL, "",
++			      &nullentrylen);
++# else
++		_nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
++# endif
+ 
+-	    /* Resource problems are fatal.  If we continue onwards we will
+-	       only attempt to calloc a new conv_tab and fail later.  */
+-	    if (__glibc_unlikely (nullentry == (char *) -1))
+-	      return (char *) -1;
++	      /* Resource problems are fatal.  If we continue onwards we will
++	         only attempt to calloc a new conv_tab and fail later.  */
++	      if (__builtin_expect (nullentry == (char *) -1, 0))
++	        return (char *) -1;
+ 
+-	    if (nullentry != NULL)
+-	      {
+-		const char *charsetstr;
++	      if (nullentry != NULL)
++		{
++		  const char *charsetstr;
+ 
+-		charsetstr = strstr (nullentry, "charset=");
+-		if (charsetstr != NULL)
+-		  {
+-		    size_t len;
+-		    char *charset;
+-		    const char *outcharset;
++		  charsetstr = strstr (nullentry, "charset=");
++		  if (charsetstr != NULL)
++		    {
++		      size_t len;
++		      char *charset;
++		      const char *outcharset;
+ 
+-		    charsetstr += strlen ("charset=");
+-		    len = strcspn (charsetstr, " \t\n");
++		      charsetstr += strlen ("charset=");
++		      len = strcspn (charsetstr, " \t\n");
+ 
+-		    charset = (char *) alloca (len + 1);
++		      charset = (char *) alloca (len + 1);
+ # if defined _LIBC || HAVE_MEMPCPY
+-		    *((char *) mempcpy (charset, charsetstr, len)) = '\0';
++		      *((char *) mempcpy (charset, charsetstr, len)) = '\0';
+ # else
+-		    memcpy (charset, charsetstr, len);
+-		    charset[len] = '\0';
++		      memcpy (charset, charsetstr, len);
++		      charset[len] = '\0';
+ # endif
+ 
+-		    outcharset = encoding;
++		      outcharset = encoding;
+ 
+ # ifdef _LIBC
+-		    /* We always want to use transliteration.  */
+-		    outcharset = norm_add_slashes (outcharset, "TRANSLIT");
+-		    charset = norm_add_slashes (charset, "");
+-		    int r = __gconv_open (outcharset, charset, &convd->conv,
+-					  GCONV_AVOID_NOCONV);
+-		    if (__glibc_unlikely (r != __GCONV_OK))
+-		      {
+-			/* If the output encoding is the same there is
+-			   nothing to do.  Otherwise do not use the
+-			   translation at all.  */
+-			if (__glibc_likely (r != __GCONV_NULCONV))
+-			  {
+-			    __libc_rwlock_unlock (domain->conversions_lock);
+-			    free ((char *) encoding);
+-			    return NULL;
+-			  }
+-
+-			convd->conv = (__gconv_t) -1;
+-		      }
++		      /* We always want to use transliteration.  */
++		      outcharset = norm_add_slashes (outcharset, "TRANSLIT");
++		      charset = norm_add_slashes (charset, "");
++		      int r = __gconv_open (outcharset, charset, &convd->conv,
++					    GCONV_AVOID_NOCONV);
++		      if (__builtin_expect (r != __GCONV_OK, 0))
++			{
++			  /* If the output encoding is the same there is
++			     nothing to do.  Otherwise do not use the
++			     translation at all.  */
++			  if (__builtin_expect (r != __GCONV_NULCONV, 1))
++			    {
++			      gl_rwlock_unlock (domain->conversions_lock);
++			      free ((char *) encoding);
++			      return NULL;
++			    }
++
++			  convd->conv = (__gconv_t) -1;
++			}
+ # else
+ #  if HAVE_ICONV
+-		    /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
+-		       we want to use transliteration.  */
+-#   if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \
++		      /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
++			 we want to use transliteration.  */
++#   if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \
++	&& !defined __UCLIBC__) \
+        || _LIBICONV_VERSION >= 0x0105
+-		    if (strchr (outcharset, '/') == NULL)
+-		      {
+-			char *tmp;
++		      if (strchr (outcharset, '/') == NULL)
++			{
++			  char *tmp;
+ 
+-			len = strlen (outcharset);
+-			tmp = (char *) alloca (len + 10 + 1);
+-			memcpy (tmp, outcharset, len);
+-			memcpy (tmp + len, "//TRANSLIT", 10 + 1);
+-			outcharset = tmp;
++			  len = strlen (outcharset);
++			  tmp = (char *) alloca (len + 10 + 1);
++			  memcpy (tmp, outcharset, len);
++			  memcpy (tmp + len, "//TRANSLIT", 10 + 1);
++			  outcharset = tmp;
+ 
+-			convd->conv = iconv_open (outcharset, charset);
++			  convd->conv = iconv_open (outcharset, charset);
+ 
+-			freea (outcharset);
+-		      }
+-		    else
++			  freea (outcharset);
++			}
++		      else
+ #   endif
+-		      convd->conv = iconv_open (outcharset, charset);
++			convd->conv = iconv_open (outcharset, charset);
+ #  endif
+ # endif
+ 
+-		    freea (charset);
+-		  }
+-	      }
++		      freea (charset);
++		    }
++		}
++	    }
++	    convd->conv_tab = NULL;
++	    /* Here domain->conversions is still == new_conversions.  */
++	    domain->nconversions++;
+ 	  }
+-	  convd->conv_tab = NULL;
+-	  /* Here domain->conversions is still == new_conversions.  */
+-	  domain->nconversions++;
+ 
+ 	found_convd:
+-	  __libc_rwlock_unlock (domain->conversions_lock);
++	  gl_rwlock_unlock (domain->conversions_lock);
+ 	}
+ 
+       if (
+@@ -1043,7 +1207,6 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ # endif
+ 	  )
+ 	{
+-	  __libc_lock_define_initialized (static, lock)
+ 	  /* We are supposed to do a conversion.  First allocate an
+ 	     appropriate table with the same structure as the table
+ 	     of translations in the file, where we can put the pointers
+@@ -1053,14 +1216,22 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ 	     handle this case by converting RESULTLEN bytes, including
+ 	     NULs.  */
+ 
+-	  if (__glibc_unlikely (convd->conv_tab == NULL))
++	  /* This lock primarily protects the memory management variables
++	     freemem, freemem_size.  It also protects write accesses to
++	     convd->conv_tab.  It's not worth using a separate lock (such
++	     as domain->conversions_lock) for this purpose, because when
++	     modifying convd->conv_tab, we also need to lock freemem,
++	     freemem_size for most of the time.  */
++	  __libc_lock_define_initialized (static, lock)
++
++	  if (__builtin_expect (convd->conv_tab == NULL, 0))
+ 	    {
+ 	      __libc_lock_lock (lock);
+ 	      if (convd->conv_tab == NULL)
+ 		{
+-		  convd->conv_tab
+-		    = calloc (nstrings + domain->n_sysdep_strings,
+-			      sizeof (char *));
++		  convd->conv_tab =
++		    (char **) calloc (nstrings + domain->n_sysdep_strings,
++				      sizeof (char *));
+ 		  if (convd->conv_tab != NULL)
+ 		    goto not_translated_yet;
+ 		  /* Mark that we didn't succeed allocating a table.  */
+@@ -1069,16 +1240,13 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ 	      __libc_lock_unlock (lock);
+ 	    }
+ 
+-	  if (__glibc_unlikely (convd->conv_tab == (char **) -1))
++	  if (__builtin_expect (convd->conv_tab == (char **) -1, 0))
+ 	    /* Nothing we can do, no more memory.  We cannot use the
+ 	       translation because it might be encoded incorrectly.  */
+ 	    return (char *) -1;
+ 
+ 	  if (convd->conv_tab[act] == NULL)
+ 	    {
+-	      __libc_lock_lock (lock);
+-	    not_translated_yet:;
+-
+ 	      /* We haven't used this string so far, so it is not
+ 		 translated yet.  Do this now.  */
+ 	      /* We use a bit more efficient memory handling.
+@@ -1092,11 +1260,17 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ 	      unsigned char *outbuf;
+ 	      int malloc_count;
+ # ifndef _LIBC
+-	      transmem_block_t *transmem_list = NULL;
++	      transmem_block_t *transmem_list;
+ # endif
+ 
++	      __libc_lock_lock (lock);
++	    not_translated_yet:
++
+ 	      inbuf = (const unsigned char *) result;
+ 	      outbuf = freemem + sizeof (size_t);
++# ifndef _LIBC
++	      transmem_list = NULL;
++# endif
+ 
+ 	      malloc_count = 0;
+ 	      while (1)
+@@ -1190,7 +1364,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ 		      /* Fall through and return -1.  */
+ # endif
+ 		    }
+-		  if (__glibc_unlikely (newmem == NULL))
++		  if (__builtin_expect (newmem == NULL, 0))
+ 		    {
+ 		      freemem = NULL;
+ 		      freemem_size = 0;
+@@ -1241,11 +1415,8 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
+ /* Look up a plural variant.  */
+ static char *
+ internal_function
+-plural_lookup (domain, n, translation, translation_len)
+-     struct loaded_l10nfile *domain;
+-     unsigned long int n;
+-     const char *translation;
+-     size_t translation_len;
++plural_lookup (struct loaded_l10nfile *domain, unsigned long int n,
++	       const char *translation, size_t translation_len)
+ {
+   struct loaded_domain *domaindata = (struct loaded_domain *) domain->data;
+   unsigned long int index;
+@@ -1282,8 +1453,7 @@ plural_lookup (domain, n, translation, translation_len)
+ /* Return string representation of locale CATEGORY.  */
+ static const char *
+ internal_function
+-category_to_name (category)
+-     int category;
++category_to_name (int category)
+ {
+   const char *retval;
+ 
+@@ -1340,41 +1510,102 @@ category_to_name (category)
+ }
+ #endif
+ 
+-/* Guess value of current locale from value of the environment variables.  */
++/* Guess value of current locale from value of the environment variables
++   or system-dependent defaults.  */
+ static const char *
+ internal_function
+-guess_category_value (category, categoryname)
+-     int category;
+-     const char *categoryname;
++#ifdef IN_LIBGLOCALE
++guess_category_value (int category, const char *categoryname,
++		      const char *locale)
++
++#else
++guess_category_value (int category, const char *categoryname)
++#endif
+ {
+   const char *language;
+-  const char *retval;
+-
+-  /* The highest priority value is the `LANGUAGE' environment
+-     variable.  But we don't use the value if the currently selected
+-     locale is the C locale.  This is a GNU extension.  */
+-  language = getenv ("LANGUAGE");
+-  if (language != NULL && language[0] == '\0')
+-    language = NULL;
++#ifndef IN_LIBGLOCALE
++  const char *locale;
++# ifndef _LIBC
++  const char *language_default;
++  int locale_defaulted;
++# endif
++#endif
+ 
+-  /* We have to proceed with the POSIX methods of looking to `LC_ALL',
++  /* We use the settings in the following order:
++     1. The value of the environment variable 'LANGUAGE'.  This is a GNU
++        extension.  Its value can be a colon-separated list of locale names.
++     2. The value of the environment variable 'LC_ALL', 'LC_xxx', or 'LANG'.
++        More precisely, the first among these that is set to a non-empty value.
++        This is how POSIX specifies it.  The value is a single locale name.
++     3. A system-dependent preference list of languages.  Its value can be a
++        colon-separated list of locale names.
++     4. A system-dependent default locale name.
++     This way:
++       - System-dependent settings can be overridden by environment variables.
++       - If the system provides both a list of languages and a default locale,
++         the former is used.  */
++
++#ifndef IN_LIBGLOCALE
++  /* Fetch the locale name, through the POSIX method of looking to `LC_ALL',
+      `LC_xxx', and `LANG'.  On some systems this can be done by the
+      `setlocale' function itself.  */
+-#ifdef _LIBC
+-  retval = __current_locale_name (category);
+-#else
+-  retval = _nl_locale_name (category, categoryname);
++# ifdef _LIBC
++  locale = __current_locale_name (category);
++# else
++  locale_defaulted = 0;
++#  if HAVE_USELOCALE
++  locale = _nl_locale_name_thread_unsafe (category, categoryname);
++  if (locale == NULL)
++#  endif
++    {
++      locale = _nl_locale_name_posix (category, categoryname);
++      if (locale == NULL)
++	{
++	  locale = _nl_locale_name_default ();
++	  locale_defaulted = 1;
++	}
++    }
++# endif
+ #endif
+ 
+-  return language != NULL && strcmp (retval, "C") != 0 ? language : retval;
++  /* Ignore LANGUAGE and its system-dependent analogon if the locale is set
++     to "C" because
++     1. "C" locale usually uses the ASCII encoding, and most international
++	messages use non-ASCII characters. These characters get displayed
++	as question marks (if using glibc's iconv()) or as invalid 8-bit
++	characters (because other iconv()s refuse to convert most non-ASCII
++	characters to ASCII). In any case, the output is ugly.
++     2. The precise output of some programs in the "C" locale is specified
++	by POSIX and should not depend on environment variables like
++	"LANGUAGE" or system-dependent information.  We allow such programs
++        to use gettext().  */
++  if (strcmp (locale, "C") == 0)
++    return locale;
++
++  /* The highest priority value is the value of the 'LANGUAGE' environment
++     variable.  */
++  language = getenv ("LANGUAGE");
++  if (language != NULL && language[0] != '\0')
++    return language;
++#if !defined IN_LIBGLOCALE && !defined _LIBC
++  /* The next priority value is the locale name, if not defaulted.  */
++  if (locale_defaulted)
++    {
++      /* The next priority value is the default language preferences list. */
++      language_default = _nl_language_preferences_default ();
++      if (language_default != NULL)
++        return language_default;
++    }
++  /* The least priority value is the locale name, if defaulted.  */
++#endif
++  return locale;
+ }
+ 
+-#if defined _LIBC || HAVE_ICONV
++#if (defined _LIBC || HAVE_ICONV) && !defined IN_LIBGLOCALE
+ /* Returns the output charset.  */
+ static const char *
+ internal_function
+-get_output_charset (domainbinding)
+-     struct binding *domainbinding;
++get_output_charset (struct binding *domainbinding)
+ {
+   /* The output charset should normally be determined by the locale.  But
+      sometimes the locale is not used or not correctly set up, so we provide
+@@ -1415,7 +1646,6 @@ get_output_charset (domainbinding)
+ 	  return _NL_CURRENT (LC_CTYPE, CODESET);
+ # else
+ #  if HAVE_ICONV
+-	  extern const char *locale_charset PARAMS ((void));
+ 	  return locale_charset ();
+ #  endif
+ # endif
+@@ -1432,9 +1662,7 @@ get_output_charset (domainbinding)
+    to be defined.  */
+ #if !_LIBC && !HAVE_STPCPY
+ static char *
+-stpcpy (dest, src)
+-     char *dest;
+-     const char *src;
++stpcpy (char *dest, const char *src)
+ {
+   while ((*dest++ = *src++) != '\0')
+     /* Do nothing. */ ;
+@@ -1444,15 +1672,16 @@ stpcpy (dest, src)
+ 
+ #if !_LIBC && !HAVE_MEMPCPY
+ static void *
+-mempcpy (dest, src, n)
+-     void *dest;
+-     const void *src;
+-     size_t n;
++mempcpy (void *dest, const void *src, size_t n)
+ {
+   return (void *) ((char *) memcpy (dest, src, n) + n);
+ }
+ #endif
+ 
++#if !_LIBC && !HAVE_TSEARCH
++# include "tsearch.c"
++#endif
++
+ 
+ #ifdef _LIBC
+ /* If we want to free all resources we have to do some work at
+diff --git a/intl/dcngettext.c b/intl/dcngettext.c
+index f3404f3..67dcbcf 100644
+--- a/intl/dcngettext.c
++++ b/intl/dcngettext.c
+@@ -1,20 +1,18 @@
+ /* Implementation of the dcngettext(3) function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -44,12 +42,9 @@
+ /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+    locale.  */
+ char *
+-DCNGETTEXT (domainname, msgid1, msgid2, n, category)
+-     const char *domainname;
+-     const char *msgid1;
+-     const char *msgid2;
+-     unsigned long int n;
+-     int category;
++DCNGETTEXT (const char *domainname,
++	    const char *msgid1, const char *msgid2, unsigned long int n,
++	    int category)
+ {
+   return DCIGETTEXT (domainname, msgid1, msgid2, 1, n, category);
+ }
+diff --git a/intl/dgettext.c b/intl/dgettext.c
+index d7c2331..c0e6cd0 100644
+--- a/intl/dgettext.c
++++ b/intl/dgettext.c
+@@ -1,28 +1,27 @@
+ /* Implementation of the dgettext(3) function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+ 
++#include "gettextP.h"
++
+ #include <locale.h>
+ 
+-#include "gettextP.h"
+ #ifdef _LIBC
+ # include <libintl.h>
+ #else
+@@ -46,9 +45,7 @@
+ /* Look up MSGID in the DOMAINNAME message catalog of the current
+    LC_MESSAGES locale.  */
+ char *
+-DGETTEXT (domainname, msgid)
+-     const char *domainname;
+-     const char *msgid;
++DGETTEXT (const char *domainname, const char *msgid)
+ {
+   return DCGETTEXT (domainname, msgid, LC_MESSAGES);
+ }
+diff --git a/intl/dngettext.c b/intl/dngettext.c
+index 38cfdac..4d900e7 100644
+--- a/intl/dngettext.c
++++ b/intl/dngettext.c
+@@ -1,28 +1,27 @@
+ /* Implementation of the dngettext(3) function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+ 
++#include "gettextP.h"
++
+ #include <locale.h>
+ 
+-#include "gettextP.h"
+ #ifdef _LIBC
+ # include <libintl.h>
+ #else
+@@ -46,11 +45,8 @@
+ /* Look up MSGID in the DOMAINNAME message catalog of the current
+    LC_MESSAGES locale and skip message according to the plural form.  */
+ char *
+-DNGETTEXT (domainname, msgid1, msgid2, n)
+-     const char *domainname;
+-     const char *msgid1;
+-     const char *msgid2;
+-     unsigned long int n;
++DNGETTEXT (const char *domainname,
++	   const char *msgid1, const char *msgid2, unsigned long int n)
+ {
+   return DCNGETTEXT (domainname, msgid1, msgid2, n, LC_MESSAGES);
+ }
+diff --git a/intl/eval-plural.h b/intl/eval-plural.h
+new file mode 100644
+index 0000000..924c8c3
+--- /dev/null
++++ b/intl/eval-plural.h
+@@ -0,0 +1,106 @@
++/* Plural expression evaluation.
++   Copyright (C) 2000-2003, 2007 Free Software Foundation, Inc.
++
++   This program 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.
++
++   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 Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#ifndef STATIC
++#define STATIC static
++#endif
++
++/* Evaluate the plural expression and return an index value.  */
++STATIC
++unsigned long int
++internal_function
++plural_eval (const struct expression *pexp, unsigned long int n)
++{
++  switch (pexp->nargs)
++    {
++    case 0:
++      switch (pexp->operation)
++	{
++	case var:
++	  return n;
++	case num:
++	  return pexp->val.num;
++	default:
++	  break;
++	}
++      /* NOTREACHED */
++      break;
++    case 1:
++      {
++	/* pexp->operation must be lnot.  */
++	unsigned long int arg = plural_eval (pexp->val.args[0], n);
++	return ! arg;
++      }
++    case 2:
++      {
++	unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
++	if (pexp->operation == lor)
++	  return leftarg || plural_eval (pexp->val.args[1], n);
++	else if (pexp->operation == land)
++	  return leftarg && plural_eval (pexp->val.args[1], n);
++	else
++	  {
++	    unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
++
++	    switch (pexp->operation)
++	      {
++	      case mult:
++		return leftarg * rightarg;
++	      case divide:
++#if !INTDIV0_RAISES_SIGFPE
++		if (rightarg == 0)
++		  raise (SIGFPE);
++#endif
++		return leftarg / rightarg;
++	      case module:
++#if !INTDIV0_RAISES_SIGFPE
++		if (rightarg == 0)
++		  raise (SIGFPE);
++#endif
++		return leftarg % rightarg;
++	      case plus:
++		return leftarg + rightarg;
++	      case minus:
++		return leftarg - rightarg;
++	      case less_than:
++		return leftarg < rightarg;
++	      case greater_than:
++		return leftarg > rightarg;
++	      case less_or_equal:
++		return leftarg <= rightarg;
++	      case greater_or_equal:
++		return leftarg >= rightarg;
++	      case equal:
++		return leftarg == rightarg;
++	      case not_equal:
++		return leftarg != rightarg;
++	      default:
++		break;
++	      }
++	  }
++	/* NOTREACHED */
++	break;
++      }
++    case 3:
++      {
++	/* pexp->operation must be qmop.  */
++	unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
++	return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
++      }
++    }
++  /* NOTREACHED */
++  return 0;
++}
+diff --git a/intl/explodename.c b/intl/explodename.c
+index 31fcf3d..9e049c7 100644
+--- a/intl/explodename.c
++++ b/intl/explodename.c
+@@ -1,20 +1,18 @@
+ /* Copyright (C) 1995-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ 
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -37,11 +35,13 @@
+ 
+ /* @@ end of prolog @@ */
+ 
+-static char *_nl_find_language PARAMS ((const char *name));
++/* Split a locale name NAME into a leading language part and all the
++   rest.  Return a pointer to the first character after the language,
++   i.e. to the first byte of the rest.  */
++static char *_nl_find_language (const char *name);
+ 
+ static char *
+-_nl_find_language (name)
+-     const char *name;
++_nl_find_language (const char *name)
+ {
+   while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.')
+     ++name;
+@@ -51,14 +51,10 @@ _nl_find_language (name)
+ 
+ 
+ int
+-_nl_explode_name (name, language, modifier, territory, codeset,
+-		  normalized_codeset)
+-     char *name;
+-     const char **language;
+-     const char **modifier;
+-     const char **territory;
+-     const char **codeset;
+-     const char **normalized_codeset;
++_nl_explode_name (char *name,
++		  const char **language, const char **modifier,
++		  const char **territory, const char **codeset,
++		  const char **normalized_codeset)
+ {
+   char *cp;
+   int mask;
+@@ -77,8 +73,8 @@ _nl_explode_name (name, language, modifier, territory, codeset,
+   if (*language == cp)
+     /* This does not make sense: language has to be specified.  Use
+        this entry as it is without exploding.  Perhaps it is an alias.  */
+-    cp = __rawmemchr (*language, '\0');
+-  else if (cp[0] != '@')
++    cp = strchr (*language, '\0');
++  else
+     {
+       if (cp[0] == '_')
+ 	{
+diff --git a/intl/finddomain.c b/intl/finddomain.c
+index 8a588bc..b5a48a5 100644
+--- a/intl/finddomain.c
++++ b/intl/finddomain.c
+@@ -1,21 +1,19 @@
+ /* Handle list of needed message catalogs
+    Copyright (C) 1995-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+    Written by Ulrich Drepper <drepper@gnu.org>, 1995.
+ 
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -33,11 +31,21 @@
+ #include "gettextP.h"
+ #ifdef _LIBC
+ # include <libintl.h>
+-# include <bits/libc-lock.h>
+ #else
+ # include "libgnuintl.h"
+ #endif
+ 
++/* Handle multi-threaded applications.  */
++#ifdef _LIBC
++# include <bits/libc-lock.h>
++# define gl_rwlock_define_initialized __libc_rwlock_define_initialized
++# define gl_rwlock_rdlock __libc_rwlock_rdlock
++# define gl_rwlock_wrlock __libc_rwlock_wrlock
++# define gl_rwlock_unlock __libc_rwlock_unlock
++#else
++# include "lock.h"
++#endif
++
+ /* @@ end of prolog @@ */
+ /* List of already loaded domains.  */
+ static struct loaded_l10nfile *_nl_loaded_domains;
+@@ -48,11 +56,8 @@ static struct loaded_l10nfile *_nl_loaded_domains;
+    established bindings.  */
+ struct loaded_l10nfile *
+ internal_function
+-_nl_find_domain (dirname, locale, domainname, domainbinding)
+-     const char *dirname;
+-     char *locale;
+-     const char *domainname;
+-     struct binding *domainbinding;
++_nl_find_domain (const char *dirname, char *locale,
++		 const char *domainname, struct binding *domainbinding)
+ {
+   struct loaded_l10nfile *retval;
+   const char *language;
+@@ -65,7 +70,7 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
+ 
+   /* LOCALE can consist of up to four recognized parts for the XPG syntax:
+ 
+-		language[_territory[.codeset]][@modifier]
++		language[_territory][.codeset][@modifier]
+ 
+      Beside the first part all of them are allowed to be missing.  If
+      the full specified locale is not found, the less specific one are
+@@ -78,15 +83,16 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
+    */
+ 
+   /* We need to protect modifying the _NL_LOADED_DOMAINS data.  */
+-  __libc_rwlock_define_initialized (static, lock);
+-  __libc_rwlock_rdlock (lock);
++  gl_rwlock_define_initialized (static, lock);
++  gl_rwlock_rdlock (lock);
+ 
+   /* If we have already tested for this locale entry there has to
+      be one data set in the list of loaded domains.  */
+   retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+ 			       strlen (dirname) + 1, 0, locale, NULL, NULL,
+ 			       NULL, NULL, domainname, 0);
+-  __libc_rwlock_unlock (lock);
++
++  gl_rwlock_unlock (lock);
+ 
+   if (retval != NULL)
+     {
+@@ -117,11 +123,23 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
+      done.  */
+   alias_value = _nl_expand_alias (locale);
+   if (alias_value != NULL)
+-    locale = strdupa (alias_value);
++    {
++#if defined _LIBC || defined HAVE_STRDUP
++      locale = strdup (alias_value);
++      if (locale == NULL)
++	return NULL;
++#else
++      size_t len = strlen (alias_value) + 1;
++      locale = (char *) malloc (len);
++      if (locale == NULL)
++	return NULL;
++
++      memcpy (locale, alias_value, len);
++#endif
++    }
+ 
+   /* Now we determine the single parts of the locale name.  First
+-     look for the language.  Termination symbols are `_' and `@' if
+-     we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
++     look for the language.  Termination symbols are `_', '.', and `@'.  */
+   mask = _nl_explode_name (locale, &language, &modifier, &territory,
+ 			   &codeset, &normalized_codeset);
+   if (mask == -1)
+@@ -129,7 +147,7 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
+     return NULL;
+ 
+   /* We need to protect modifying the _NL_LOADED_DOMAINS data.  */
+-  __libc_rwlock_wrlock (lock);
++  gl_rwlock_wrlock (lock);
+ 
+   /* Create all possible locale entries which might be interested in
+      generalization.  */
+@@ -137,7 +155,8 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
+ 			       strlen (dirname) + 1, mask, language, territory,
+ 			       codeset, normalized_codeset, modifier,
+ 			       domainname, 1);
+-  __libc_rwlock_unlock (lock);
++
++  gl_rwlock_unlock (lock);
+ 
+   if (retval == NULL)
+     /* This means we are out of core.  */
+@@ -157,6 +176,10 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
+ 	}
+     }
+ 
++  /* The room for an alias was dynamically allocated.  Free it now.  */
++  if (alias_value != NULL)
++    free (locale);
++
+ out:
+   /* The space for normalized_codeset is dynamically allocated.  Free it.  */
+   if (mask & XPG_NORM_CODESET)
+diff --git a/intl/gettext.c b/intl/gettext.c
+index 3864a03..4a1af7e 100644
+--- a/intl/gettext.c
++++ b/intl/gettext.c
+@@ -1,20 +1,18 @@
+ /* Implementation of gettext(3) function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -52,8 +50,7 @@
+    LC_MESSAGES locale.  If not found, returns MSGID itself (the default
+    text).  */
+ char *
+-GETTEXT (msgid)
+-     const char *msgid;
++GETTEXT (const char *msgid)
+ {
+   return DCGETTEXT (NULL, msgid, LC_MESSAGES);
+ }
+diff --git a/intl/gettextP.h b/intl/gettextP.h
+index 3da2322..6f4c684 100644
+--- a/intl/gettextP.h
++++ b/intl/gettextP.h
+@@ -1,21 +1,19 @@
+ /* Header describing internals of libintl library.
+    Copyright (C) 1995-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+    Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
+ 
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef _GETTEXTP_H
+ #define _GETTEXTP_H
+@@ -30,20 +28,67 @@
+ # endif
+ #endif
+ 
++/* Handle multi-threaded applications.  */
++#ifdef _LIBC
++# include <bits/libc-lock.h>
++# define gl_rwlock_define __libc_rwlock_define
++#else
++# include "lock.h"
++#endif
++
++#ifdef _LIBC
++struct loaded_domain;
++extern char *__gettext (const char *__msgid);
++extern char *__dgettext (const char *__domainname, const char *__msgid);
++extern char *__dcgettext (const char *__domainname, const char *__msgid,
++			  int __category);
++extern char *__ngettext (const char *__msgid1, const char *__msgid2,
++			 unsigned long int __n);
++extern char *__dngettext (const char *__domainname,
++			  const char *__msgid1, const char *__msgid2,
++			  unsigned long int n);
++extern char *__dcngettext (const char *__domainname,
++			   const char *__msgid1, const char *__msgid2,
++			   unsigned long int __n, int __category);
++extern char *__dcigettext (const char *__domainname,
++			   const char *__msgid1, const char *__msgid2,
++			   int __plural, unsigned long int __n,
++			   int __category);
++extern char *__textdomain (const char *__domainname);
++extern char *__bindtextdomain (const char *__domainname,
++			       const char *__dirname);
++extern char *__bind_textdomain_codeset (const char *__domainname,
++					const char *__codeset);
++extern void _nl_finddomain_subfreeres (void) attribute_hidden;
++extern void _nl_unload_domain (struct loaded_domain *__domain)
++     internal_function attribute_hidden;
++#else
++/* Declare the exported libintl_* functions, in a way that allows us to
++   call them under their real name.  */
++# undef _INTL_REDIRECT_INLINE
++# undef _INTL_REDIRECT_MACROS
++# define _INTL_REDIRECT_MACROS
++# include "libgnuintl.h"
++# ifdef IN_LIBGLOCALE
++extern char *gl_dcigettext (const char *__domainname,
++			    const char *__msgid1, const char *__msgid2,
++			    int __plural, unsigned long int __n,
++			    int __category,
++			    const char *__localename, const char *__encoding);
++# else
++extern char *libintl_dcigettext (const char *__domainname,
++				 const char *__msgid1, const char *__msgid2,
++				 int __plural, unsigned long int __n,
++				 int __category);
++# endif
++#endif
++
+ #include "loadinfo.h"
+ 
+ #include "gmo.h"		/* Get nls_uint32.  */
+ 
+ /* @@ end of prolog @@ */
+ 
+-#ifndef PARAMS
+-# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
+-#  define PARAMS(args) args
+-# else
+-#  define PARAMS(args) ()
+-# endif
+-#endif
+-
+ #ifndef internal_function
+ # define internal_function
+ #endif
+@@ -52,6 +97,12 @@
+ # define attribute_hidden
+ #endif
+ 
++/* Tell the compiler when a conditional or integer expression is
++   almost always true or almost always false.  */
++#ifndef HAVE_BUILTIN_EXPECT
++# define __builtin_expect(expr, val) (expr)
++#endif
++
+ #ifndef W
+ # define W(flag, data) ((flag) ? SWAP (data) : (data))
+ #endif
+@@ -61,11 +112,13 @@
+ # include <byteswap.h>
+ # define SWAP(i) bswap_32 (i)
+ #else
+-static nls_uint32 SWAP PARAMS ((nls_uint32 i));
+-
+ static inline nls_uint32
++# ifdef __cplusplus
++SWAP (nls_uint32 i)
++# else
+ SWAP (i)
+      nls_uint32 i;
++# endif
+ {
+   return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
+ }
+@@ -139,7 +192,7 @@ struct loaded_domain
+   /* Cache of charset conversions of the translated strings.  */
+   struct converted_domain *conversions;
+   size_t nconversions;
+-  __libc_rwlock_define (, conversions_lock);
++  gl_rwlock_define (, conversions_lock)
+ 
+   const struct expression *plural;
+   unsigned long int nplurals;
+@@ -166,82 +219,92 @@ struct binding
+ /* A counter which is incremented each time some previous translations
+    become invalid.
+    This variable is part of the external ABI of the GNU libintl.  */
+-extern int _nl_msg_cat_cntr;
++#ifdef IN_LIBGLOCALE
++# include <glocale/config.h>
++extern LIBGLOCALE_DLL_EXPORTED int _nl_msg_cat_cntr;
++#else
++extern LIBINTL_DLL_EXPORTED int _nl_msg_cat_cntr;
++#endif
+ 
+ #ifndef _LIBC
+-const char *_nl_locale_name PARAMS ((int category, const char *categoryname));
++extern const char *_nl_language_preferences_default (void);
++# define gl_locale_name_canonicalize _nl_locale_name_canonicalize
++extern void _nl_locale_name_canonicalize (char *name);
++# define gl_locale_name_from_win32_LANGID _nl_locale_name_from_win32_LANGID
++/* extern const char *_nl_locale_name_from_win32_LANGID (LANGID langid); */
++# define gl_locale_name_from_win32_LCID _nl_locale_name_from_win32_LCID
++/* extern const char *_nl_locale_name_from_win32_LCID (LCID lcid); */
++# define gl_locale_name_thread_unsafe _nl_locale_name_thread_unsafe
++extern const char *_nl_locale_name_thread_unsafe (int category,
++						  const char *categoryname);
++# define gl_locale_name_thread _nl_locale_name_thread
++/* extern const char *_nl_locale_name_thread (int category,
++					      const char *categoryname); */
++# define gl_locale_name_posix _nl_locale_name_posix
++extern const char *_nl_locale_name_posix (int category,
++					  const char *categoryname);
++# define gl_locale_name_environ _nl_locale_name_environ
++extern const char *_nl_locale_name_environ (int category,
++					    const char *categoryname);
++# define gl_locale_name_default _nl_locale_name_default
++extern const char *_nl_locale_name_default (void);
++# define gl_locale_name _nl_locale_name
++/* extern const char *_nl_locale_name (int category,
++				       const char *categoryname); */
+ #endif
+ 
+-struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
+-						 char *__locale,
+-						 const char *__domainname,
+-					      struct binding *__domainbinding))
++struct loaded_l10nfile *_nl_find_domain (const char *__dirname, char *__locale,
++					 const char *__domainname,
++					 struct binding *__domainbinding)
+      internal_function;
+-void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain,
+-			      struct binding *__domainbinding))
++void _nl_load_domain (struct loaded_l10nfile *__domain,
++		      struct binding *__domainbinding)
+      internal_function;
+ 
+-char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file,
+-			    struct binding *domainbinding, const char *msgid,
+-			    int convert, size_t *lengthp))
++#ifdef IN_LIBGLOCALE
++char *_nl_find_msg (struct loaded_l10nfile *domain_file,
++		    struct binding *domainbinding, const char *encoding,
++		    const char *msgid,
++		    size_t *lengthp)
+      internal_function;
++#else
++char *_nl_find_msg (struct loaded_l10nfile *domain_file,
++		    struct binding *domainbinding, const char *msgid,
++		    int convert, size_t *lengthp)
++     internal_function;
++#endif
+ 
++/* The internal variables in the standalone libintl.a must have different
++   names than the internal variables in GNU libc, otherwise programs
++   using libintl.a cannot be linked statically.  */
++#if !defined _LIBC
++# define _nl_default_dirname libintl_nl_default_dirname
++# define _nl_domain_bindings libintl_nl_domain_bindings
++#endif
++
++/* Contains the default location of the message catalogs.  */
++extern const char _nl_default_dirname[];
+ #ifdef _LIBC
+-extern char *__gettext PARAMS ((const char *__msgid));
+-extern char *__dgettext PARAMS ((const char *__domainname,
+-				 const char *__msgid));
+-extern char *__dcgettext PARAMS ((const char *__domainname,
+-				  const char *__msgid, int __category));
+-extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2,
+-				 unsigned long int __n));
+-extern char *__dngettext PARAMS ((const char *__domainname,
+-				  const char *__msgid1, const char *__msgid2,
+-				  unsigned long int n));
+-extern char *__dcngettext PARAMS ((const char *__domainname,
+-				   const char *__msgid1, const char *__msgid2,
+-				   unsigned long int __n, int __category));
+-extern char *__dcigettext PARAMS ((const char *__domainname,
+-				   const char *__msgid1, const char *__msgid2,
+-				   int __plural, unsigned long int __n,
+-				   int __category));
+-extern char *__textdomain PARAMS ((const char *__domainname));
+-extern char *__bindtextdomain PARAMS ((const char *__domainname,
+-				       const char *__dirname));
+-extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname,
+-						const char *__codeset));
+-extern void _nl_finddomain_subfreeres PARAMS ((void)) attribute_hidden;
+-extern void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
+-     internal_function attribute_hidden;
+-#else
+-extern char *libintl_gettext PARAMS ((const char *__msgid));
+-extern char *libintl_dgettext PARAMS ((const char *__domainname,
+-				       const char *__msgid));
+-extern char *libintl_dcgettext PARAMS ((const char *__domainname,
+-					const char *__msgid, int __category));
+-extern char *libintl_ngettext PARAMS ((const char *__msgid1,
+-				       const char *__msgid2,
+-				       unsigned long int __n));
+-extern char *libintl_dngettext PARAMS ((const char *__domainname,
+-					const char *__msgid1,
+-					const char *__msgid2,
+-					unsigned long int __n));
+-extern char *libintl_dcngettext PARAMS ((const char *__domainname,
+-					 const char *__msgid1,
+-					 const char *__msgid2,
+-					 unsigned long int __n,
+-					 int __category));
+-extern char *libintl_dcigettext PARAMS ((const char *__domainname,
+-					 const char *__msgid1,
+-					 const char *__msgid2,
+-					 int __plural, unsigned long int __n,
+-					 int __category));
+-extern char *libintl_textdomain PARAMS ((const char *__domainname));
+-extern char *libintl_bindtextdomain PARAMS ((const char *__domainname,
+-					     const char *__dirname));
+-extern char *libintl_bind_textdomain_codeset PARAMS ((const char *__domainname,
+-						      const char *__codeset));
++libc_hidden_proto (_nl_default_dirname)
++#endif
++
++/* List with bindings of specific domains.  */
++extern struct binding *_nl_domain_bindings;
++
++/* The internal variables in the standalone libintl.a must have different
++   names than the internal variables in GNU libc, otherwise programs
++   using libintl.a cannot be linked statically.  */
++#if !defined _LIBC
++# define _nl_default_default_domain libintl_nl_default_default_domain
++# define _nl_current_default_domain libintl_nl_current_default_domain
+ #endif
+ 
++/* Name of the default text domain.  */
++extern const char _nl_default_default_domain[] attribute_hidden;
++
++/* Default text domain in which entries for gettext(3) are to be found.  */
++extern const char *_nl_current_default_domain attribute_hidden;
++
+ /* @@ begin of epilog @@ */
+ 
+ #endif /* gettextP.h  */
+diff --git a/intl/gmo.h b/intl/gmo.h
+index c9330db..4d18e9a 100644
+--- a/intl/gmo.h
++++ b/intl/gmo.h
+@@ -1,20 +1,18 @@
+-/* Internal header for GNU gettext internationalization functions.
++/* Description of GNU message catalog format: general file layout.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef _GETTEXT_H
+ #define _GETTEXT_H 1
+@@ -124,6 +122,15 @@ struct sysdep_segment
+   nls_uint32 offset;
+ };
+ 
++/* Pair of a static and a system dependent segment, in struct sysdep_string.  */
++struct segment_pair
++{
++  /* Size of static segment.  */
++  nls_uint32 segsize;
++  /* Reference to system dependent string segment, or ~0 at the end.  */
++  nls_uint32 sysdepref;
++};
++
+ /* Descriptor for system dependent string.  */
+ struct sysdep_string
+ {
+@@ -131,13 +138,7 @@ struct sysdep_string
+   nls_uint32 offset;
+   /* Alternating sequence of static and system dependent segments.
+      The last segment is a static segment, including the trailing NUL.  */
+-  struct segment_pair
+-  {
+-    /* Size of static segment.  */
+-    nls_uint32 segsize;
+-    /* Reference to system dependent string segment, or ~0 at the end.  */
+-    nls_uint32 sysdepref;
+-  } segments[1];
++  struct segment_pair segments[1];
+ };
+ 
+ /* Marker for the end of the segments[] array.  This has the value 0xFFFFFFFF,
+diff --git a/intl/hash-string.c b/intl/hash-string.c
+index 3e53e2a..f44ebc0 100644
+--- a/intl/hash-string.c
++++ b/intl/hash-string.c
+@@ -16,6 +16,11 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++/* Specification.  */
+ #include "hash-string.h"
+ 
+ 
+@@ -23,8 +28,7 @@
+    [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+    1986, 1987 Bell Telephone Laboratories, Inc.]  */
+ unsigned long int
+-__hash_string (str_param)
+-     const char *str_param;
++__hash_string (const char *str_param)
+ {
+   unsigned long int hval, g;
+   const char *str = str_param;
+diff --git a/intl/hash-string.h b/intl/hash-string.h
+index 646631f..339a4f8 100644
+--- a/intl/hash-string.h
++++ b/intl/hash-string.h
+@@ -1,37 +1,34 @@
+-/* Implements a string hashing function.
++/* Description of GNU message catalog format: string hashing function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ /* @@ end of prolog @@ */
+ 
+-#ifndef PARAMS
+-# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
+-#  define PARAMS(Args) Args
+-# else
+-#  define PARAMS(Args) ()
+-# endif
+-#endif
+-
+ /* We assume to have `unsigned long int' value with at least 32 bits.  */
+ #define HASHWORDBITS 32
+ 
+ 
++#ifndef _LIBC
++# ifdef IN_LIBINTL
++#  define __hash_string libintl_hash_string
++# else
++#  define __hash_string hash_string
++# endif
++#endif
++
+ /* Defines the so called `hashpjw' function by P.J. Weinberger
+    [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+    1986, 1987 Bell Telephone Laboratories, Inc.]  */
+-extern unsigned long int __hash_string PARAMS ((const char *__str_param))
+-     attribute_hidden;
++extern unsigned long int __hash_string (const char *str_param);
+diff --git a/intl/l10nflist.c b/intl/l10nflist.c
+index 428a3f1..5b7c2bd 100644
+--- a/intl/l10nflist.c
++++ b/intl/l10nflist.c
+@@ -1,20 +1,18 @@
+ /* Copyright (C) 1995-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ 
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ /* Tell glibc's <string.h> to provide a prototype for stpcpy().
+    This must come before <config.h> because <config.h> may include
+@@ -58,20 +56,19 @@
+ # endif
+ #else
+ # ifndef HAVE_STPCPY
+-static char *stpcpy PARAMS ((char *dest, const char *src));
++static char *stpcpy (char *dest, const char *src);
+ # endif
+ #endif
+ 
+ /* Define function which are usually not available.  */
+ 
+-#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
++#if defined HAVE_ARGZ_COUNT
++# undef __argz_count
++# define __argz_count argz_count
++#else
+ /* Returns the number of strings in ARGZ.  */
+-static size_t argz_count__ PARAMS ((const char *argz, size_t len));
+-
+ static size_t
+-argz_count__ (argz, len)
+-     const char *argz;
+-     size_t len;
++argz_count__ (const char *argz, size_t len)
+ {
+   size_t count = 0;
+   while (len > 0)
+@@ -85,18 +82,16 @@ argz_count__ (argz, len)
+ }
+ # undef __argz_count
+ # define __argz_count(argz, len) argz_count__ (argz, len)
+-#endif	/* !_LIBC && !HAVE___ARGZ_COUNT */
++#endif	/* !_LIBC && !HAVE_ARGZ_COUNT */
+ 
+-#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
++#if defined HAVE_ARGZ_STRINGIFY
++# undef __argz_stringify
++# define __argz_stringify argz_stringify
++#else
+ /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
+    except the last into the character SEP.  */
+-static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
+-
+ static void
+-argz_stringify__ (argz, len, sep)
+-     char *argz;
+-     size_t len;
+-     int sep;
++argz_stringify__ (char *argz, size_t len, int sep)
+ {
+   while (len > 0)
+     {
+@@ -109,22 +104,20 @@ argz_stringify__ (argz, len, sep)
+ }
+ # undef __argz_stringify
+ # define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
+-#endif	/* !_LIBC && !HAVE___ARGZ_STRINGIFY */
+-
+-#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
+-static char *argz_next__ PARAMS ((char *argz, size_t argz_len,
+-				  const char *entry));
++#endif	/* !_LIBC && !HAVE_ARGZ_STRINGIFY */
+ 
++#ifdef _LIBC
++#elif defined HAVE_ARGZ_NEXT
++# undef __argz_next
++# define __argz_next argz_next
++#else
+ static char *
+-argz_next__ (argz, argz_len, entry)
+-     char *argz;
+-     size_t argz_len;
+-     const char *entry;
++argz_next__ (char *argz, size_t argz_len, const char *entry)
+ {
+   if (entry)
+     {
+       if (entry < argz + argz_len)
+-	entry = strchr (entry, '\0') + 1;
++        entry = strchr (entry, '\0') + 1;
+ 
+       return entry >= argz + argz_len ? NULL : (char *) entry;
+     }
+@@ -136,16 +129,12 @@ argz_next__ (argz, argz_len, entry)
+ }
+ # undef __argz_next
+ # define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
+-#endif	/* !_LIBC && !HAVE___ARGZ_NEXT */
+-
++#endif	/* !_LIBC && !HAVE_ARGZ_NEXT */
+ 
+ /* Return number of bits set in X.  */
+ #ifndef ARCH_POP
+-static int pop PARAMS ((int x));
+-
+ static inline int
+-pop (x)
+-     int x;
++pop (int x)
+ {
+   /* We assume that no more than 16 bits are used.  */
+   x = ((x & ~0x5555) >> 1) + (x & 0x5555);
+@@ -159,20 +148,12 @@ pop (x)
+ 
+ \f
+ struct loaded_l10nfile *
+-_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
+-		    territory, codeset, normalized_codeset, modifier,
+-		    filename, do_allocate)
+-     struct loaded_l10nfile **l10nfile_list;
+-     const char *dirlist;
+-     size_t dirlist_len;
+-     int mask;
+-     const char *language;
+-     const char *territory;
+-     const char *codeset;
+-     const char *normalized_codeset;
+-     const char *modifier;
+-     const char *filename;
+-     int do_allocate;
++_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list,
++		    const char *dirlist, size_t dirlist_len,
++		    int mask, const char *language, const char *territory,
++		    const char *codeset, const char *normalized_codeset,
++		    const char *modifier,
++		    const char *filename, int do_allocate)
+ {
+   char *abs_filename;
+   struct loaded_l10nfile *last = NULL;
+@@ -315,11 +296,9 @@ _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
+    names.  The return value is dynamically allocated and has to be
+    freed by the caller.  */
+ const char *
+-_nl_normalize_codeset (codeset, name_len)
+-     const char *codeset;
+-     size_t name_len;
++_nl_normalize_codeset (const char *codeset, size_t name_len)
+ {
+-  int len = 0;
++  size_t len = 0;
+   int only_digit = 1;
+   char *retval;
+   char *wp;
+@@ -343,9 +322,10 @@ _nl_normalize_codeset (codeset, name_len)
+ 
+   if (retval != NULL)
+     {
+-      wp = retval;
+       if (only_digit)
+-	wp = stpcpy (wp, "iso");
++	wp = stpcpy (retval, "iso");
++      else
++	wp = retval;
+ 
+       for (cnt = 0; cnt < name_len; ++cnt)
+ 	if (__isalpha_l ((unsigned char) codeset[cnt], locale))
+@@ -368,9 +348,7 @@ _nl_normalize_codeset (codeset, name_len)
+    to be defined.  */
+ #if !_LIBC && !HAVE_STPCPY
+ static char *
+-stpcpy (dest, src)
+-     char *dest;
+-     const char *src;
++stpcpy (char *dest, const char *src)
+ {
+   while ((*dest++ = *src++) != '\0')
+     /* Do nothing. */ ;
+diff --git a/intl/loadinfo.h b/intl/loadinfo.h
+index e11b2e8..adf5bc9 100644
+--- a/intl/loadinfo.h
++++ b/intl/loadinfo.h
+@@ -2,19 +2,18 @@
+    This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+ 
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef _LOADINFO_H
+ #define _LOADINFO_H	1
+@@ -31,18 +30,29 @@
+    in gettextP.h.
+  */
+ 
+-#ifndef PARAMS
+-# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
+-#  define PARAMS(args) args
+-# else
+-#  define PARAMS(args) ()
+-# endif
+-#endif
+-
+ #ifndef internal_function
+ # define internal_function
+ #endif
+ 
++#ifndef LIBINTL_DLL_EXPORTED
++# define LIBINTL_DLL_EXPORTED
++#endif
++
++/* Tell the compiler when a conditional or integer expression is
++   almost always true or almost always false.  */
++#ifndef HAVE_BUILTIN_EXPECT
++# define __builtin_expect(expr, val) (expr)
++#endif
++
++/* Separator in PATH like lists of pathnames.  */
++#if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__
++  /* Win32, OS/2, DOS */
++# define PATH_SEPARATOR ';'
++#else
++  /* Unix */
++# define PATH_SEPARATOR ':'
++#endif
++
+ /* Encoding of locale name parts.  */
+ #define XPG_NORM_CODESET	1
+ #define XPG_CODESET		2
+@@ -66,27 +76,55 @@ struct loaded_l10nfile
+    names.  Normalization allows the user to use any of the common
+    names.  The return value is dynamically allocated and has to be
+    freed by the caller.  */
+-extern const char *_nl_normalize_codeset PARAMS ((const char *codeset,
+-						  size_t name_len));
+-
++extern const char *_nl_normalize_codeset (const char *codeset,
++					  size_t name_len);
++
++/* Lookup a locale dependent file.
++   *L10NFILE_LIST denotes a pool of lookup results of locale dependent
++   files of the same kind, sorted in decreasing order of ->filename.
++   DIRLIST and DIRLIST_LEN are an argz list of directories in which to
++   look, containing at least one directory (i.e. DIRLIST_LEN > 0).
++   MASK, LANGUAGE, TERRITORY, CODESET, NORMALIZED_CODESET, MODIFIER
++   are the pieces of the locale name, as produced by _nl_explode_name().
++   FILENAME is the filename suffix.
++   The return value is the lookup result, either found in *L10NFILE_LIST,
++   or - if DO_ALLOCATE is nonzero - freshly allocated, or possibly NULL.
++   If the return value is non-NULL, it is added to *L10NFILE_LIST, and
++   its ->next field denotes the chaining inside *L10NFILE_LIST, and
++   furthermore its ->successor[] field contains a list of other lookup
++   results from which this lookup result inherits.  */
+ extern struct loaded_l10nfile *
+-_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list,
+-			    const char *dirlist, size_t dirlist_len, int mask,
+-			    const char *language, const char *territory,
+-			    const char *codeset,
+-			    const char *normalized_codeset,
+-			    const char *modifier, const char *filename,
+-			    int do_allocate));
+-
+-
+-extern const char *_nl_expand_alias PARAMS ((const char *name));
+-
+-/* normalized_codeset is dynamically allocated and has to be freed by
+-   the caller.  */
+-extern int _nl_explode_name PARAMS ((char *name, const char **language,
+-				     const char **modifier,
+-				     const char **territory,
+-				     const char **codeset,
+-				     const char **normalized_codeset));
++_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list,
++		    const char *dirlist, size_t dirlist_len, int mask,
++		    const char *language, const char *territory,
++		    const char *codeset, const char *normalized_codeset,
++		    const char *modifier,
++		    const char *filename, int do_allocate);
++
++/* Lookup the real locale name for a locale alias NAME, or NULL if
++   NAME is not a locale alias (but possibly a real locale name).
++   The return value is statically allocated and must not be freed.  */
++/* Part of the libintl ABI only for the sake of the gettext.m4 macro.  */
++extern LIBINTL_DLL_EXPORTED const char *_nl_expand_alias (const char *name);
++
++/* Split a locale name NAME into its pieces: language, modifier,
++   territory, codeset.
++   NAME gets destructively modified: NUL bytes are inserted here and
++   there.  *LANGUAGE gets assigned NAME.  Each of *MODIFIER, *TERRITORY,
++   *CODESET gets assigned either a pointer into the old NAME string, or
++   NULL.  *NORMALIZED_CODESET gets assigned the expanded *CODESET, if it
++   is different from *CODESET; this one is dynamically allocated and has
++   to be freed by the caller.
++   The return value is a bitmask, where each bit corresponds to one
++   filled-in value:
++     XPG_MODIFIER                for *MODIFIER,
++     XPG_TERRITORY               for *TERRITORY,
++     XPG_CODESET                 for *CODESET,
++     XPG_NORM_CODESET            for *NORMALIZED_CODESET.
++ */
++extern int _nl_explode_name (char *name, const char **language,
++			     const char **modifier, const char **territory,
++			     const char **codeset,
++			     const char **normalized_codeset);
+ 
+ #endif	/* loadinfo.h */
+diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
+index 2ea0f10..4074c4c 100644
+--- a/intl/loadmsgcat.c
++++ b/intl/loadmsgcat.c
+@@ -1,20 +1,18 @@
+ /* Load needed message catalogs.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ /* Tell glibc's <string.h> to provide a prototype for mempcpy().
+    This must come before <config.h> because <config.h> may include
+diff --git a/intl/localealias.c b/intl/localealias.c
+index 9ab4328..e65b31b 100644
+--- a/intl/localealias.c
++++ b/intl/localealias.c
+@@ -1,20 +1,18 @@
+ /* Handle aliases for locale names.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ /* Tell glibc's <string.h> to provide a prototype for mempcpy().
+    This must come before <config.h> because <config.h> may include
+@@ -39,14 +37,19 @@
+ # define alloca __builtin_alloca
+ # define HAVE_ALLOCA 1
+ #else
+-# if defined HAVE_ALLOCA_H || defined _LIBC
+-#  include <alloca.h>
++# ifdef _MSC_VER
++#  include <malloc.h>
++#  define alloca _alloca
+ # else
+-#  ifdef _AIX
+- #pragma alloca
++#  if defined HAVE_ALLOCA_H || defined _LIBC
++#   include <alloca.h>
+ #  else
+-#   ifndef alloca
++#   ifdef _AIX
++ #pragma alloca
++#   else
++#    ifndef alloca
+ char *alloca ();
++#    endif
+ #   endif
+ #  endif
+ # endif
+@@ -57,6 +60,12 @@ char *alloca ();
+ 
+ #include "gettextP.h"
+ 
++#ifdef ENABLE_RELOCATABLE
++# include "relocatable.h"
++#else
++# define relocate(pathname) (pathname)
++#endif
++
+ /* @@ end of prolog @@ */
+ 
+ #ifdef _LIBC
+@@ -70,11 +79,13 @@ char *alloca ();
+ # endif
+ # define HAVE_MEMPCPY	1
+ # define HAVE___FSETLOCKING	1
++#endif
+ 
+-/* We need locking here since we can be called from different places.  */
++/* Handle multi-threaded applications.  */
++#ifdef _LIBC
+ # include <bits/libc-lock.h>
+-
+-__libc_lock_define_initialized (static, lock);
++#else
++# include "lock.h"
+ #endif
+ 
+ #ifndef internal_function
+@@ -99,16 +110,19 @@ __libc_lock_define_initialized (static, lock);
+ # define freea(p) free (p)
+ #endif
+ 
+-#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
++#if defined _LIBC_REENTRANT || defined HAVE_DECL_FGETS_UNLOCKED
+ # undef fgets
+ # define fgets(buf, len, s) fgets_unlocked (buf, len, s)
+ #endif
+-#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED
++#if defined _LIBC_REENTRANT || defined HAVE_DECL_FEOF_UNLOCKED
+ # undef feof
+ # define feof(s) feof_unlocked (s)
+ #endif
+ 
+ 
++__libc_lock_define_initialized (static, lock)
++
++
+ struct alias_map
+ {
+   const char *alias;
+@@ -129,25 +143,25 @@ static size_t maxmap;
+ 
+ 
+ /* Prototypes for local functions.  */
+-static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
++static size_t read_alias_file (const char *fname, int fname_len)
+      internal_function;
+-static int extend_alias_table PARAMS ((void));
+-static int alias_compare PARAMS ((const struct alias_map *map1,
+-				  const struct alias_map *map2));
++static int extend_alias_table (void);
++static int alias_compare (const struct alias_map *map1,
++			  const struct alias_map *map2);
+ 
+ 
+ const char *
+-_nl_expand_alias (name)
+-    const char *name;
++_nl_expand_alias (const char *name)
+ {
+-  static const char *locale_alias_path = LOCALE_ALIAS_PATH;
++  static const char *locale_alias_path;
+   struct alias_map *retval;
+   const char *result = NULL;
+   size_t added;
+ 
+-#ifdef _LIBC
+   __libc_lock_lock (lock);
+-#endif
++
++  if (locale_alias_path == NULL)
++    locale_alias_path = LOCALE_ALIAS_PATH;
+ 
+   do
+     {
+@@ -158,8 +172,8 @@ _nl_expand_alias (name)
+       if (nmap > 0)
+ 	retval = (struct alias_map *) bsearch (&item, map, nmap,
+ 					       sizeof (struct alias_map),
+-					       (int (*) PARAMS ((const void *,
+-								 const void *))
++					       (int (*) (const void *,
++							 const void *)
+ 						) alias_compare);
+       else
+ 	retval = NULL;
+@@ -177,11 +191,12 @@ _nl_expand_alias (name)
+ 	{
+ 	  const char *start;
+ 
+-	  while (locale_alias_path[0] == ':')
++	  while (locale_alias_path[0] == PATH_SEPARATOR)
+ 	    ++locale_alias_path;
+ 	  start = locale_alias_path;
+ 
+-	  while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
++	  while (locale_alias_path[0] != '\0'
++		 && locale_alias_path[0] != PATH_SEPARATOR)
+ 	    ++locale_alias_path;
+ 
+ 	  if (start < locale_alias_path)
+@@ -190,9 +205,7 @@ _nl_expand_alias (name)
+     }
+   while (added != 0);
+ 
+-#ifdef _LIBC
+   __libc_lock_unlock (lock);
+-#endif
+ 
+   return result;
+ }
+@@ -200,9 +213,7 @@ _nl_expand_alias (name)
+ 
+ static size_t
+ internal_function
+-read_alias_file (fname, fname_len)
+-     const char *fname;
+-     int fname_len;
++read_alias_file (const char *fname, int fname_len)
+ {
+   FILE *fp;
+   char *full_fname;
+@@ -218,9 +229,13 @@ read_alias_file (fname, fname_len)
+   memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
+ #endif
+ 
++#ifdef _LIBC
+   /* Note the file is opened with cancellation in the I/O functions
+      disabled.  */
+-  fp = fopen (full_fname, "rce");
++  fp = fopen (relocate (full_fname), "rce");
++#else
++  fp = fopen (relocate (full_fname), "r");
++#endif
+   freea (full_fname);
+   if (fp == NULL)
+     return 0;
+@@ -274,9 +289,6 @@ read_alias_file (fname, fname_len)
+ 
+ 	  if (cp[0] != '\0')
+ 	    {
+-	      size_t alias_len;
+-	      size_t value_len;
+-
+ 	      value = cp++;
+ 	      while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
+ 		++cp;
+@@ -292,48 +304,62 @@ read_alias_file (fname, fname_len)
+ 	      else if (cp[0] != '\0')
+ 		*cp++ = '\0';
+ 
+-	      if (nmap >= maxmap)
+-		if (__glibc_unlikely (extend_alias_table ()))
+-		  goto out;
++#ifdef IN_LIBGLOCALE
++	      /* glibc's locale.alias contains entries for ja_JP and ko_KR
++		 that make it impossible to use a Japanese or Korean UTF-8
++		 locale under the name "ja_JP" or "ko_KR".  Ignore these
++		 entries.  */
++	      if (strchr (alias, '_') == NULL)
++#endif
++		{
++		  size_t alias_len;
++		  size_t value_len;
+ 
+-	      alias_len = strlen (alias) + 1;
+-	      value_len = strlen (value) + 1;
++		  if (nmap >= maxmap)
++		    if (__builtin_expect (extend_alias_table (), 0))
++		      goto out;
+ 
+-	      if (string_space_act + alias_len + value_len > string_space_max)
+-		{
+-		  /* Increase size of memory pool.  */
+-		  size_t new_size = (string_space_max
+-				     + (alias_len + value_len > 1024
+-					? alias_len + value_len : 1024));
+-		  char *new_pool = (char *) realloc (string_space, new_size);
+-		  if (new_pool == NULL)
+-		    goto out;
+-
+-		  if (__glibc_unlikely (string_space != new_pool))
+-		    {
+-		      size_t i;
++		  alias_len = strlen (alias) + 1;
++		  value_len = strlen (value) + 1;
+ 
+-		      for (i = 0; i < nmap; i++)
++		  if (string_space_act + alias_len + value_len > string_space_max)
++		    {
++		      /* Increase size of memory pool.  */
++		      size_t new_size = (string_space_max
++					 + (alias_len + value_len > 1024
++					    ? alias_len + value_len : 1024));
++		      char *new_pool = (char *) realloc (string_space, new_size);
++		      if (new_pool == NULL)
++			goto out;
++
++		      if (__builtin_expect (string_space != new_pool, 0))
+ 			{
+-			  map[i].alias += new_pool - string_space;
+-			  map[i].value += new_pool - string_space;
++			  size_t i;
++
++			  for (i = 0; i < nmap; i++)
++			    {
++			      map[i].alias += new_pool - string_space;
++			      map[i].value += new_pool - string_space;
++			    }
+ 			}
+-		    }
+ 
+-		  string_space = new_pool;
+-		  string_space_max = new_size;
+-		}
++		      string_space = new_pool;
++		      string_space_max = new_size;
++		    }
+ 
+-	      map[nmap].alias = memcpy (&string_space[string_space_act],
+-					alias, alias_len);
+-	      string_space_act += alias_len;
++		  map[nmap].alias =
++		    (const char *) memcpy (&string_space[string_space_act],
++					   alias, alias_len);
++		  string_space_act += alias_len;
+ 
+-	      map[nmap].value = memcpy (&string_space[string_space_act],
+-					value, value_len);
+-	      string_space_act += value_len;
++		  map[nmap].value =
++		    (const char *) memcpy (&string_space[string_space_act],
++					   value, value_len);
++		  string_space_act += value_len;
+ 
+-	      ++nmap;
+-	      ++added;
++		  ++nmap;
++		  ++added;
++		}
+ 	    }
+ 	}
+ 
+@@ -348,14 +374,14 @@ read_alias_file (fname, fname_len)
+ 	while (strchr (buf, '\n') == NULL);
+     }
+ 
+-out:
++ out:
+   /* Should we test for ferror()?  I think we have to silently ignore
+      errors.  --drepper  */
+   fclose (fp);
+ 
+   if (added > 0)
+     qsort (map, nmap, sizeof (struct alias_map),
+-	   (int (*) PARAMS ((const void *, const void *))) alias_compare);
++	   (int (*) (const void *, const void *)) alias_compare);
+ 
+   return added;
+ }
+@@ -381,9 +407,7 @@ extend_alias_table (void)
+ 
+ 
+ static int
+-alias_compare (map1, map2)
+-     const struct alias_map *map1;
+-     const struct alias_map *map2;
++alias_compare (const struct alias_map *map1, const struct alias_map *map2)
+ {
+ #if defined _LIBC || defined HAVE_STRCASECMP
+   return strcasecmp (map1->alias, map2->alias);
+diff --git a/intl/ngettext.c b/intl/ngettext.c
+index 7bf8e21..7fe7e7f 100644
+--- a/intl/ngettext.c
++++ b/intl/ngettext.c
+@@ -1,20 +1,18 @@
+ /* Implementation of ngettext(3) function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -54,10 +52,7 @@
+    LC_MESSAGES locale.  If not found, returns MSGID itself (the default
+    text).  */
+ char *
+-NGETTEXT (msgid1, msgid2, n)
+-     const char *msgid1;
+-     const char *msgid2;
+-     unsigned long int n;
++NGETTEXT (const char *msgid1, const char *msgid2, unsigned long int n)
+ {
+   return DCNGETTEXT (NULL, msgid1, msgid2, n, LC_MESSAGES);
+ }
+diff --git a/intl/plural-eval.c b/intl/plural-eval.c
+deleted file mode 100644
+index 6fc2460..0000000
+--- a/intl/plural-eval.c
++++ /dev/null
+@@ -1,100 +0,0 @@
+-/* Plural expression evaluation.
+-   Copyright (C) 2000-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-static unsigned long int plural_eval (const struct expression *pexp,
+-				      unsigned long int n)
+-     internal_function;
+-
+-static unsigned long int
+-internal_function
+-plural_eval (pexp, n)
+-     const struct expression *pexp;
+-     unsigned long int n;
+-{
+-  switch (pexp->nargs)
+-    {
+-    case 0:
+-      switch (pexp->operation)
+-	{
+-	case var:
+-	  return n;
+-	case num:
+-	  return pexp->val.num;
+-	default:
+-	  break;
+-	}
+-      /* NOTREACHED */
+-      break;
+-    case 1:
+-      {
+-	/* pexp->operation must be lnot.  */
+-	unsigned long int arg = plural_eval (pexp->val.args[0], n);
+-	return ! arg;
+-      }
+-    case 2:
+-      {
+-	unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
+-	if (pexp->operation == lor)
+-	  return leftarg || plural_eval (pexp->val.args[1], n);
+-	else if (pexp->operation == land)
+-	  return leftarg && plural_eval (pexp->val.args[1], n);
+-	else
+-	  {
+-	    unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
+-
+-	    switch (pexp->operation)
+-	      {
+-	      case mult:
+-		return leftarg * rightarg;
+-	      case divide:
+-		return leftarg / rightarg;
+-	      case module:
+-		return leftarg % rightarg;
+-	      case plus:
+-		return leftarg + rightarg;
+-	      case minus:
+-		return leftarg - rightarg;
+-	      case less_than:
+-		return leftarg < rightarg;
+-	      case greater_than:
+-		return leftarg > rightarg;
+-	      case less_or_equal:
+-		return leftarg <= rightarg;
+-	      case greater_or_equal:
+-		return leftarg >= rightarg;
+-	      case equal:
+-		return leftarg == rightarg;
+-	      case not_equal:
+-		return leftarg != rightarg;
+-	      default:
+-		break;
+-	      }
+-	  }
+-	/* NOTREACHED */
+-	break;
+-      }
+-    case 3:
+-      {
+-	/* pexp->operation must be qmop.  */
+-	unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
+-	return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
+-      }
+-    }
+-  /* NOTREACHED */
+-  return 0;
+-}
+diff --git a/intl/plural-exp.c b/intl/plural-exp.c
+index 9a536c7..97cd93a 100644
+--- a/intl/plural-exp.c
++++ b/intl/plural-exp.c
+@@ -1,21 +1,19 @@
+ /* Expression parsing for plural form selection.
+    Copyright (C) 2000-2014 Free Software Foundation, Inc.
+    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -27,7 +25,8 @@
+ 
+ #include "plural-exp.h"
+ 
+-#if (defined __GNUC__ && !defined __APPLE_CC__) \
++#if (defined __GNUC__ && !(defined __APPLE_CC_ && __APPLE_CC__ > 1) && \
++     !defined __cplusplus)					       \
+     || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+ 
+ /* These structs are the constant expression for the germanic plural
+@@ -96,10 +95,9 @@ init_germanic_plural (void)
+ 
+ void
+ internal_function
+-EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp)
+-     const char *nullentry;
+-     const struct expression **pluralp;
+-     unsigned long int *npluralsp;
++EXTRACT_PLURAL_EXPRESSION (const char *nullentry,
++			   const struct expression **pluralp,
++			   unsigned long int *npluralsp)
+ {
+   if (nullentry != NULL)
+     {
+diff --git a/intl/plural-exp.h b/intl/plural-exp.h
+index 9ec8901..beaa326 100644
+--- a/intl/plural-exp.h
++++ b/intl/plural-exp.h
+@@ -1,33 +1,23 @@
+ /* Expression parsing and evaluation for plural form selection.
+    Copyright (C) 2000-2014 Free Software Foundation, Inc.
+    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef _PLURAL_EXP_H
+ #define _PLURAL_EXP_H
+ 
+-#ifndef PARAMS
+-# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES
+-#  define PARAMS(args) args
+-# else
+-#  define PARAMS(args) ()
+-# endif
+-#endif
+-
+ #ifndef internal_function
+ # define internal_function
+ #endif
+@@ -36,36 +26,42 @@
+ # define attribute_hidden
+ #endif
+ 
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++enum expression_operator
++{
++  /* Without arguments:  */
++  var,				/* The variable "n".  */
++  num,				/* Decimal number.  */
++  /* Unary operators:  */
++  lnot,				/* Logical NOT.  */
++  /* Binary operators:  */
++  mult,				/* Multiplication.  */
++  divide,			/* Division.  */
++  module,			/* Modulo operation.  */
++  plus,				/* Addition.  */
++  minus,			/* Subtraction.  */
++  less_than,			/* Comparison.  */
++  greater_than,			/* Comparison.  */
++  less_or_equal,		/* Comparison.  */
++  greater_or_equal,		/* Comparison.  */
++  equal,			/* Comparison for equality.  */
++  not_equal,			/* Comparison for inequality.  */
++  land,				/* Logical AND.  */
++  lor,				/* Logical OR.  */
++  /* Ternary operators:  */
++  qmop				/* Question mark operator.  */
++};
+ 
+ /* This is the representation of the expressions to determine the
+    plural form.  */
+ struct expression
+ {
+   int nargs;			/* Number of arguments.  */
+-  enum operator
+-  {
+-    /* Without arguments:  */
+-    var,			/* The variable "n".  */
+-    num,			/* Decimal number.  */
+-    /* Unary operators:  */
+-    lnot,			/* Logical NOT.  */
+-    /* Binary operators:  */
+-    mult,			/* Multiplication.  */
+-    divide,			/* Division.  */
+-    module,			/* Modulo operation.  */
+-    plus,			/* Addition.  */
+-    minus,			/* Subtraction.  */
+-    less_than,			/* Comparison.  */
+-    greater_than,		/* Comparison.  */
+-    less_or_equal,		/* Comparison.  */
+-    greater_or_equal,		/* Comparison.  */
+-    equal,			/* Comparison for equality.  */
+-    not_equal,			/* Comparison for inequality.  */
+-    land,			/* Logical AND.  */
+-    lor,			/* Logical OR.  */
+-    /* Ternary operators:  */
+-    qmop			/* Question mark operator.  */
+-  } operation;
++  enum expression_operator operation;
+   union
+   {
+     unsigned long int num;	/* Number value for `num'.  */
+@@ -109,17 +105,23 @@ struct parse_args
+ # define EXTRACT_PLURAL_EXPRESSION extract_plural_expression
+ #endif
+ 
+-extern void FREE_EXPRESSION PARAMS ((struct expression *exp))
++extern void FREE_EXPRESSION (struct expression *exp)
+      internal_function;
+-extern int PLURAL_PARSE PARAMS ((void *arg));
++extern int PLURAL_PARSE (struct parse_args *arg);
+ extern const struct expression GERMANIC_PLURAL attribute_hidden;
+-extern void EXTRACT_PLURAL_EXPRESSION PARAMS
+-  ((const char *nullentry, const struct expression **pluralp,
+-    unsigned long int *npluralsp)) internal_function;
++extern void EXTRACT_PLURAL_EXPRESSION (const char *nullentry,
++				       const struct expression **pluralp,
++				       unsigned long int *npluralsp)
++     internal_function;
++
++#if !defined (_LIBC) && !defined (IN_LIBINTL) && !defined (IN_LIBGLOCALE)
++extern unsigned long int plural_eval (const struct expression *pexp,
++				      unsigned long int n);
++#endif
++
+ 
+-#if !defined (_LIBC) && !defined (IN_LIBINTL)
+-extern unsigned long int plural_eval PARAMS ((const struct expression *pexp,
+-					      unsigned long int n));
++#ifdef __cplusplus
++}
+ #endif
+ 
+ #endif /* _PLURAL_EXP_H */
+diff --git a/intl/plural.c b/intl/plural.c
+index 1bac3c0..31b0570 100644
+--- a/intl/plural.c
++++ b/intl/plural.c
+@@ -50,7 +50,7 @@
+ #define YYSKELETON_NAME "yacc.c"
+ 
+ /* Pure parsers.  */
+-#define YYPURE 1
++#define YYPURE 2
+ 
+ /* Push parsers.  */
+ #define YYPUSH 0
+@@ -74,30 +74,30 @@
+ 
+ /* Expression parsing for plural form selection.
+    Copyright (C) 2000-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
+ 
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+-/* The bison generated parser uses alloca.  AIX 3 forces us to put this
+-   declaration at the beginning of the file.  The declaration in bison's
+-   skeleton file comes too late.  This must come before <config.h>
+-   because <config.h> may include arbitrary system headers.  */
++/* For bison < 2.0, the bison generated parser uses alloca.  AIX 3 forces us
++   to put this declaration at the beginning of the file.  The declaration in
++   bison's skeleton file comes too late.  This must come before <config.h>
++   because <config.h> may include arbitrary system headers.
++   This can go away once the AM_INTL_SUBDIR macro requires bison >= 2.0.  */
+ #if defined _AIX && !defined __GNUC__
+  #pragma alloca
+ #endif
++
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+@@ -113,11 +113,9 @@
+ # define __gettextparse PLURAL_PARSE
+ #endif
+ 
+-#define YYLEX_PARAM	&((struct parse_args *) arg)->cp
+-#define YYPARSE_PARAM	arg
+ 
+ /* Line 371 of yacc.c  */
+-#line 121 "plural.c"
++#line 119 "plural.c"
+ 
+ # ifndef YY_NULL
+ #  if defined __cplusplus && 201103L <= __cplusplus
+@@ -173,12 +171,12 @@ typedef union YYSTYPE
+ #line 49 "plural.y"
+ 
+   unsigned long int num;
+-  enum operator op;
++  enum expression_operator op;
+   struct expression *exp;
+ 
+ 
+ /* Line 387 of yacc.c  */
+-#line 182 "plural.c"
++#line 180 "plural.c"
+ } YYSTYPE;
+ # define YYSTYPE_IS_TRIVIAL 1
+ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
+@@ -194,7 +192,7 @@ int __gettextparse ();
+ #endif
+ #else /* ! YYPARSE_PARAM */
+ #if defined __STDC__ || defined __cplusplus
+-int __gettextparse (void);
++int __gettextparse (struct parse_args *arg);
+ #else
+ int __gettextparse ();
+ #endif
+@@ -207,28 +205,14 @@ int __gettextparse ();
+ #line 55 "plural.y"
+ 
+ /* Prototypes for local functions.  */
+-static struct expression *new_exp PARAMS ((int nargs, enum operator op,
+-					   struct expression * const *args));
+-static inline struct expression *new_exp_0 PARAMS ((enum operator op));
+-static inline struct expression *new_exp_1 PARAMS ((enum operator op,
+-						   struct expression *right));
+-static struct expression *new_exp_2 PARAMS ((enum operator op,
+-					     struct expression *left,
+-					     struct expression *right));
+-static inline struct expression *new_exp_3 PARAMS ((enum operator op,
+-						   struct expression *bexp,
+-						   struct expression *tbranch,
+-						   struct expression *fbranch));
+-static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
+-static void yyerror PARAMS ((const char *str));
++static int yylex (YYSTYPE *lval, struct parse_args *arg);
++static void yyerror (struct parse_args *arg, const char *str);
+ 
+ /* Allocation of expressions.  */
+ 
+ static struct expression *
+-new_exp (nargs, op, args)
+-     int nargs;
+-     enum operator op;
+-     struct expression * const *args;
++new_exp (int nargs, enum expression_operator op,
++	 struct expression * const *args)
+ {
+   int i;
+   struct expression *newp;
+@@ -257,16 +241,13 @@ new_exp (nargs, op, args)
+ }
+ 
+ static inline struct expression *
+-new_exp_0 (op)
+-     enum operator op;
++new_exp_0 (enum expression_operator op)
+ {
+   return new_exp (0, op, NULL);
+ }
+ 
+ static inline struct expression *
+-new_exp_1 (op, right)
+-     enum operator op;
+-     struct expression *right;
++new_exp_1 (enum expression_operator op, struct expression *right)
+ {
+   struct expression *args[1];
+ 
+@@ -275,10 +256,8 @@ new_exp_1 (op, right)
+ }
+ 
+ static struct expression *
+-new_exp_2 (op, left, right)
+-     enum operator op;
+-     struct expression *left;
+-     struct expression *right;
++new_exp_2 (enum expression_operator op, struct expression *left,
++	   struct expression *right)
+ {
+   struct expression *args[2];
+ 
+@@ -288,11 +267,8 @@ new_exp_2 (op, left, right)
+ }
+ 
+ static inline struct expression *
+-new_exp_3 (op, bexp, tbranch, fbranch)
+-     enum operator op;
+-     struct expression *bexp;
+-     struct expression *tbranch;
+-     struct expression *fbranch;
++new_exp_3 (enum expression_operator op, struct expression *bexp,
++	   struct expression *tbranch, struct expression *fbranch)
+ {
+   struct expression *args[3];
+ 
+@@ -304,7 +280,7 @@ new_exp_3 (op, bexp, tbranch, fbranch)
+ 
+ 
+ /* Line 390 of yacc.c  */
+-#line 308 "plural.c"
++#line 284 "plural.c"
+ 
+ #ifdef short
+ # undef short
+@@ -596,8 +572,8 @@ static const yytype_int8 yyrhs[] =
+ /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+ static const yytype_uint8 yyrline[] =
+ {
+-       0,   174,   174,   182,   186,   190,   194,   198,   202,   206,
+-     210,   214,   218,   223
++       0,   152,   152,   160,   164,   168,   172,   176,   180,   184,
++     188,   192,   196,   201
+ };
+ #endif
+ 
+@@ -746,7 +722,7 @@ do                                                              \
+     }                                                           \
+   else                                                          \
+     {                                                           \
+-      yyerror (YY_("syntax error: cannot back up")); \
++      yyerror (arg, YY_("syntax error: cannot back up")); \
+       YYERROR;							\
+     }								\
+ while (YYID (0))
+@@ -766,7 +742,7 @@ while (YYID (0))
+ #ifdef YYLEX_PARAM
+ # define YYLEX yylex (&yylval, YYLEX_PARAM)
+ #else
+-# define YYLEX yylex (&yylval)
++# define YYLEX yylex (&yylval, arg)
+ #endif
+ 
+ /* Enable debugging if requested.  */
+@@ -789,7 +765,7 @@ do {									  \
+     {									  \
+       YYFPRINTF (stderr, "%s ", Title);					  \
+       yy_symbol_print (stderr,						  \
+-		  Type, Value); \
++		  Type, Value, arg); \
+       YYFPRINTF (stderr, "\n");						  \
+     }									  \
+ } while (YYID (0))
+@@ -803,19 +779,21 @@ do {									  \
+ #if (defined __STDC__ || defined __C99__FUNC__ \
+      || defined __cplusplus || defined _MSC_VER)
+ static void
+-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
++yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parse_args *arg)
+ #else
+ static void
+-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
++yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg)
+     FILE *yyoutput;
+     int yytype;
+     YYSTYPE const * const yyvaluep;
++    struct parse_args *arg;
+ #endif
+ {
+   FILE *yyo = yyoutput;
+   YYUSE (yyo);
+   if (!yyvaluep)
+     return;
++  YYUSE (arg);
+ # ifdef YYPRINT
+   if (yytype < YYNTOKENS)
+     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+@@ -837,13 +815,14 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ #if (defined __STDC__ || defined __C99__FUNC__ \
+      || defined __cplusplus || defined _MSC_VER)
+ static void
+-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
++yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parse_args *arg)
+ #else
+ static void
+-yy_symbol_print (yyoutput, yytype, yyvaluep)
++yy_symbol_print (yyoutput, yytype, yyvaluep, arg)
+     FILE *yyoutput;
+     int yytype;
+     YYSTYPE const * const yyvaluep;
++    struct parse_args *arg;
+ #endif
+ {
+   if (yytype < YYNTOKENS)
+@@ -851,7 +830,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
+   else
+     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+ 
+-  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
++  yy_symbol_value_print (yyoutput, yytype, yyvaluep, arg);
+   YYFPRINTF (yyoutput, ")");
+ }
+ 
+@@ -894,12 +873,13 @@ do {								\
+ #if (defined __STDC__ || defined __C99__FUNC__ \
+      || defined __cplusplus || defined _MSC_VER)
+ static void
+-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
++yy_reduce_print (YYSTYPE *yyvsp, int yyrule, struct parse_args *arg)
+ #else
+ static void
+-yy_reduce_print (yyvsp, yyrule)
++yy_reduce_print (yyvsp, yyrule, arg)
+     YYSTYPE *yyvsp;
+     int yyrule;
++    struct parse_args *arg;
+ #endif
+ {
+   int yynrhs = yyr2[yyrule];
+@@ -913,7 +893,7 @@ yy_reduce_print (yyvsp, yyrule)
+       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ 		       &(yyvsp[(yyi + 1) - (yynrhs)])
+-				       );
++		       , arg);
+       YYFPRINTF (stderr, "\n");
+     }
+ }
+@@ -921,7 +901,7 @@ yy_reduce_print (yyvsp, yyrule)
+ # define YY_REDUCE_PRINT(Rule)		\
+ do {					\
+   if (yydebug)				\
+-    yy_reduce_print (yyvsp, Rule); \
++    yy_reduce_print (yyvsp, Rule, arg); \
+ } while (YYID (0))
+ 
+ /* Nonzero means print parse trace.  It is left uninitialized so that
+@@ -1201,16 +1181,18 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ #if (defined __STDC__ || defined __C99__FUNC__ \
+      || defined __cplusplus || defined _MSC_VER)
+ static void
+-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
++yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct parse_args *arg)
+ #else
+ static void
+-yydestruct (yymsg, yytype, yyvaluep)
++yydestruct (yymsg, yytype, yyvaluep, arg)
+     const char *yymsg;
+     int yytype;
+     YYSTYPE *yyvaluep;
++    struct parse_args *arg;
+ #endif
+ {
+   YYUSE (yyvaluep);
++  YYUSE (arg);
+ 
+   if (!yymsg)
+     yymsg = "Deleting";
+@@ -1245,11 +1227,11 @@ yyparse (YYPARSE_PARAM)
+ #if (defined __STDC__ || defined __C99__FUNC__ \
+      || defined __cplusplus || defined _MSC_VER)
+ int
+-yyparse (void)
++yyparse (struct parse_args *arg)
+ #else
+ int
+-yyparse ()
+-
++yyparse (arg)
++    struct parse_args *arg;
+ #endif
+ #endif
+ {
+@@ -1519,17 +1501,17 @@ yyreduce:
+     {
+         case 2:
+ /* Line 1792 of yacc.c  */
+-#line 175 "plural.y"
++#line 153 "plural.y"
+     {
+ 	    if ((yyvsp[(1) - (1)].exp) == NULL)
+ 	      YYABORT;
+-	    ((struct parse_args *) arg)->res = (yyvsp[(1) - (1)].exp);
++	    arg->res = (yyvsp[(1) - (1)].exp);
+ 	  }
+     break;
+ 
+   case 3:
+ /* Line 1792 of yacc.c  */
+-#line 183 "plural.y"
++#line 161 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_3 (qmop, (yyvsp[(1) - (5)].exp), (yyvsp[(3) - (5)].exp), (yyvsp[(5) - (5)].exp));
+ 	  }
+@@ -1537,7 +1519,7 @@ yyreduce:
+ 
+   case 4:
+ /* Line 1792 of yacc.c  */
+-#line 187 "plural.y"
++#line 165 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_2 (lor, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));
+ 	  }
+@@ -1545,7 +1527,7 @@ yyreduce:
+ 
+   case 5:
+ /* Line 1792 of yacc.c  */
+-#line 191 "plural.y"
++#line 169 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_2 (land, (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));
+ 	  }
+@@ -1553,7 +1535,7 @@ yyreduce:
+ 
+   case 6:
+ /* Line 1792 of yacc.c  */
+-#line 195 "plural.y"
++#line 173 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));
+ 	  }
+@@ -1561,7 +1543,7 @@ yyreduce:
+ 
+   case 7:
+ /* Line 1792 of yacc.c  */
+-#line 199 "plural.y"
++#line 177 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));
+ 	  }
+@@ -1569,7 +1551,7 @@ yyreduce:
+ 
+   case 8:
+ /* Line 1792 of yacc.c  */
+-#line 203 "plural.y"
++#line 181 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));
+ 	  }
+@@ -1577,7 +1559,7 @@ yyreduce:
+ 
+   case 9:
+ /* Line 1792 of yacc.c  */
+-#line 207 "plural.y"
++#line 185 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_2 ((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].exp), (yyvsp[(3) - (3)].exp));
+ 	  }
+@@ -1585,7 +1567,7 @@ yyreduce:
+ 
+   case 10:
+ /* Line 1792 of yacc.c  */
+-#line 211 "plural.y"
++#line 189 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_1 (lnot, (yyvsp[(2) - (2)].exp));
+ 	  }
+@@ -1593,7 +1575,7 @@ yyreduce:
+ 
+   case 11:
+ /* Line 1792 of yacc.c  */
+-#line 215 "plural.y"
++#line 193 "plural.y"
+     {
+ 	    (yyval.exp) = new_exp_0 (var);
+ 	  }
+@@ -1601,7 +1583,7 @@ yyreduce:
+ 
+   case 12:
+ /* Line 1792 of yacc.c  */
+-#line 219 "plural.y"
++#line 197 "plural.y"
+     {
+ 	    if (((yyval.exp) = new_exp_0 (num)) != NULL)
+ 	      (yyval.exp)->val.num = (yyvsp[(1) - (1)].num);
+@@ -1610,7 +1592,7 @@ yyreduce:
+ 
+   case 13:
+ /* Line 1792 of yacc.c  */
+-#line 224 "plural.y"
++#line 202 "plural.y"
+     {
+ 	    (yyval.exp) = (yyvsp[(2) - (3)].exp);
+ 	  }
+@@ -1618,7 +1600,7 @@ yyreduce:
+ 
+ 
+ /* Line 1792 of yacc.c  */
+-#line 1622 "plural.c"
++#line 1604 "plural.c"
+       default: break;
+     }
+   /* User semantic actions sometimes alter yychar, and that requires
+@@ -1668,7 +1650,7 @@ yyerrlab:
+     {
+       ++yynerrs;
+ #if ! YYERROR_VERBOSE
+-      yyerror (YY_("syntax error"));
++      yyerror (arg, YY_("syntax error"));
+ #else
+ # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                         yyssp, yytoken)
+@@ -1695,7 +1677,7 @@ yyerrlab:
+                 yymsgp = yymsg;
+               }
+           }
+-        yyerror (yymsgp);
++        yyerror (arg, yymsgp);
+         if (yysyntax_error_status == 2)
+           goto yyexhaustedlab;
+       }
+@@ -1719,7 +1701,7 @@ yyerrlab:
+       else
+ 	{
+ 	  yydestruct ("Error: discarding",
+-		      yytoken, &yylval);
++		      yytoken, &yylval, arg);
+ 	  yychar = YYEMPTY;
+ 	}
+     }
+@@ -1775,7 +1757,7 @@ yyerrlab1:
+ 
+ 
+       yydestruct ("Error: popping",
+-		  yystos[yystate], yyvsp);
++		  yystos[yystate], yyvsp, arg);
+       YYPOPSTACK (1);
+       yystate = *yyssp;
+       YY_STACK_PRINT (yyss, yyssp);
+@@ -1812,7 +1794,7 @@ yyabortlab:
+ | yyexhaustedlab -- memory exhaustion comes here.  |
+ `-------------------------------------------------*/
+ yyexhaustedlab:
+-  yyerror (YY_("memory exhausted"));
++  yyerror (arg, YY_("memory exhausted"));
+   yyresult = 2;
+   /* Fall through.  */
+ #endif
+@@ -1824,7 +1806,7 @@ yyreturn:
+          user semantic actions for why this is necessary.  */
+       yytoken = YYTRANSLATE (yychar);
+       yydestruct ("Cleanup: discarding lookahead",
+-                  yytoken, &yylval);
++                  yytoken, &yylval, arg);
+     }
+   /* Do not reclaim the symbols of the rule which action triggered
+      this YYABORT or YYACCEPT.  */
+@@ -1833,7 +1815,7 @@ yyreturn:
+   while (yyssp != yyss)
+     {
+       yydestruct ("Cleanup: popping",
+-		  yystos[*yyssp], yyvsp);
++		  yystos[*yyssp], yyvsp, arg);
+       YYPOPSTACK (1);
+     }
+ #ifndef yyoverflow
+@@ -1850,13 +1832,12 @@ yyreturn:
+ 
+ 
+ /* Line 2055 of yacc.c  */
+-#line 229 "plural.y"
++#line 207 "plural.y"
+ 
+ 
+ void
+ internal_function
+-FREE_EXPRESSION (exp)
+-     struct expression *exp;
++FREE_EXPRESSION (struct expression *exp)
+ {
+   if (exp == NULL)
+     return;
+@@ -1882,18 +1863,16 @@ FREE_EXPRESSION (exp)
+ 
+ 
+ static int
+-yylex (lval, pexp)
+-     YYSTYPE *lval;
+-     const char **pexp;
++yylex (YYSTYPE *lval, struct parse_args *arg)
+ {
+-  const char *exp = *pexp;
++  const char *exp = arg->cp;
+   int result;
+ 
+   while (1)
+     {
+       if (exp[0] == '\0')
+ 	{
+-	  *pexp = exp;
++	  arg->cp = exp;
+ 	  return YYEOF;
+ 	}
+ 
+@@ -2020,15 +1999,14 @@ yylex (lval, pexp)
+       break;
+     }
+ 
+-  *pexp = exp;
++  arg->cp = exp;
+ 
+   return result;
+ }
+ 
+ 
+ static void
+-yyerror (str)
+-     const char *str;
++yyerror (struct parse_args *arg, const char *str)
+ {
+   /* Do nothing.  We don't print error messages here.  */
+ }
+diff --git a/intl/plural.y b/intl/plural.y
+index 105fe0d..d74de07 100644
+--- a/intl/plural.y
++++ b/intl/plural.y
+@@ -1,30 +1,30 @@
+ %{
+ /* Expression parsing for plural form selection.
+    Copyright (C) 2000-2014 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
+ 
+-   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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+-/* The bison generated parser uses alloca.  AIX 3 forces us to put this
+-   declaration at the beginning of the file.  The declaration in bison's
+-   skeleton file comes too late.  This must come before <config.h>
+-   because <config.h> may include arbitrary system headers.  */
++/* For bison < 2.0, the bison generated parser uses alloca.  AIX 3 forces us
++   to put this declaration at the beginning of the file.  The declaration in
++   bison's skeleton file comes too late.  This must come before <config.h>
++   because <config.h> may include arbitrary system headers.
++   This can go away once the AM_INTL_SUBDIR macro requires bison >= 2.0.  */
+ #if defined _AIX && !defined __GNUC__
+  #pragma alloca
+ #endif
++
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+@@ -40,42 +40,28 @@
+ # define __gettextparse PLURAL_PARSE
+ #endif
+ 
+-#define YYLEX_PARAM	&((struct parse_args *) arg)->cp
+-#define YYPARSE_PARAM	arg
+ %}
+-%pure_parser
++%parse-param {struct parse_args *arg}
++%lex-param {struct parse_args *arg}
++%define api.pure full
+ %expect 7
+ 
+ %union {
+   unsigned long int num;
+-  enum operator op;
++  enum expression_operator op;
+   struct expression *exp;
+ }
+ 
+ %{
+ /* Prototypes for local functions.  */
+-static struct expression *new_exp PARAMS ((int nargs, enum operator op,
+-					   struct expression * const *args));
+-static inline struct expression *new_exp_0 PARAMS ((enum operator op));
+-static inline struct expression *new_exp_1 PARAMS ((enum operator op,
+-						   struct expression *right));
+-static struct expression *new_exp_2 PARAMS ((enum operator op,
+-					     struct expression *left,
+-					     struct expression *right));
+-static inline struct expression *new_exp_3 PARAMS ((enum operator op,
+-						   struct expression *bexp,
+-						   struct expression *tbranch,
+-						   struct expression *fbranch));
+-static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
+-static void yyerror PARAMS ((const char *str));
++static int yylex (YYSTYPE *lval, struct parse_args *arg);
++static void yyerror (struct parse_args *arg, const char *str);
+ 
+ /* Allocation of expressions.  */
+ 
+ static struct expression *
+-new_exp (nargs, op, args)
+-     int nargs;
+-     enum operator op;
+-     struct expression * const *args;
++new_exp (int nargs, enum expression_operator op,
++	 struct expression * const *args)
+ {
+   int i;
+   struct expression *newp;
+@@ -104,16 +90,13 @@ new_exp (nargs, op, args)
+ }
+ 
+ static inline struct expression *
+-new_exp_0 (op)
+-     enum operator op;
++new_exp_0 (enum expression_operator op)
+ {
+   return new_exp (0, op, NULL);
+ }
+ 
+ static inline struct expression *
+-new_exp_1 (op, right)
+-     enum operator op;
+-     struct expression *right;
++new_exp_1 (enum expression_operator op, struct expression *right)
+ {
+   struct expression *args[1];
+ 
+@@ -122,10 +105,8 @@ new_exp_1 (op, right)
+ }
+ 
+ static struct expression *
+-new_exp_2 (op, left, right)
+-     enum operator op;
+-     struct expression *left;
+-     struct expression *right;
++new_exp_2 (enum expression_operator op, struct expression *left,
++	   struct expression *right)
+ {
+   struct expression *args[2];
+ 
+@@ -135,11 +116,8 @@ new_exp_2 (op, left, right)
+ }
+ 
+ static inline struct expression *
+-new_exp_3 (op, bexp, tbranch, fbranch)
+-     enum operator op;
+-     struct expression *bexp;
+-     struct expression *tbranch;
+-     struct expression *fbranch;
++new_exp_3 (enum expression_operator op, struct expression *bexp,
++	   struct expression *tbranch, struct expression *fbranch)
+ {
+   struct expression *args[3];
+ 
+@@ -175,7 +153,7 @@ start:	  exp
+ 	  {
+ 	    if ($1 == NULL)
+ 	      YYABORT;
+-	    ((struct parse_args *) arg)->res = $1;
++	    arg->res = $1;
+ 	  }
+ 	;
+ 
+@@ -230,8 +208,7 @@ exp:	  exp '?' exp ':' exp
+ 
+ void
+ internal_function
+-FREE_EXPRESSION (exp)
+-     struct expression *exp;
++FREE_EXPRESSION (struct expression *exp)
+ {
+   if (exp == NULL)
+     return;
+@@ -257,18 +234,16 @@ FREE_EXPRESSION (exp)
+ 
+ 
+ static int
+-yylex (lval, pexp)
+-     YYSTYPE *lval;
+-     const char **pexp;
++yylex (YYSTYPE *lval, struct parse_args *arg)
+ {
+-  const char *exp = *pexp;
++  const char *exp = arg->cp;
+   int result;
+ 
+   while (1)
+     {
+       if (exp[0] == '\0')
+ 	{
+-	  *pexp = exp;
++	  arg->cp = exp;
+ 	  return YYEOF;
+ 	}
+ 
+@@ -395,15 +370,14 @@ yylex (lval, pexp)
+       break;
+     }
+ 
+-  *pexp = exp;
++  arg->cp = exp;
+ 
+   return result;
+ }
+ 
+ 
+ static void
+-yyerror (str)
+-     const char *str;
++yyerror (struct parse_args *arg, const char *str)
+ {
+   /* Do nothing.  We don't print error messages here.  */
+ }
+diff --git a/intl/textdomain.c b/intl/textdomain.c
+index 3b5a6c1..d1ab52a 100644
+--- a/intl/textdomain.c
++++ b/intl/textdomain.c
+@@ -1,20 +1,18 @@
+ /* Implementation of the textdomain(3) function.
+    Copyright (C) 1995-2014 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.
++   This program 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,
++   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
+-   Lesser General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+@@ -23,39 +21,25 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#include "gettextP.h"
+ #ifdef _LIBC
+ # include <libintl.h>
+ #else
+ # include "libgnuintl.h"
+ #endif
+-#include "gettextP.h"
+ 
++/* Handle multi-threaded applications.  */
+ #ifdef _LIBC
+-/* We have to handle multi-threaded applications.  */
+ # include <bits/libc-lock.h>
++# define gl_rwlock_define __libc_rwlock_define
++# define gl_rwlock_wrlock __libc_rwlock_wrlock
++# define gl_rwlock_unlock __libc_rwlock_unlock
+ #else
+-/* Provide dummy implementation if this is outside glibc.  */
+-# define __libc_rwlock_define(CLASS, NAME)
+-# define __libc_rwlock_wrlock(NAME)
+-# define __libc_rwlock_unlock(NAME)
+-#endif
+-
+-/* The internal variables in the standalone libintl.a must have different
+-   names than the internal variables in GNU libc, otherwise programs
+-   using libintl.a cannot be linked statically.  */
+-#if !defined _LIBC
+-# define _nl_default_default_domain libintl_nl_default_default_domain
+-# define _nl_current_default_domain libintl_nl_current_default_domain
++# include "lock.h"
+ #endif
+ 
+ /* @@ end of prolog @@ */
+ 
+-/* Name of the default text domain.  */
+-extern const char _nl_default_default_domain[] attribute_hidden;
+-
+-/* Default text domain in which entries for gettext(3) are to be found.  */
+-extern const char *_nl_current_default_domain attribute_hidden;
+-
+ 
+ /* Names for the libintl functions are a problem.  They must not clash
+    with existing names and they should follow ANSI C.  But this source
+@@ -71,14 +55,13 @@ extern const char *_nl_current_default_domain attribute_hidden;
+ #endif
+ 
+ /* Lock variable to protect the global data in the gettext implementation.  */
+-__libc_rwlock_define (extern, _nl_state_lock attribute_hidden)
++gl_rwlock_define (extern, _nl_state_lock attribute_hidden)
+ 
+ /* Set the current default message catalog to DOMAINNAME.
+    If DOMAINNAME is null, return the current default.
+    If DOMAINNAME is "", reset to the default of "messages".  */
+ char *
+-TEXTDOMAIN (domainname)
+-     const char *domainname;
++TEXTDOMAIN (const char *domainname)
+ {
+   char *new_domain;
+   char *old_domain;
+@@ -87,7 +70,7 @@ TEXTDOMAIN (domainname)
+   if (domainname == NULL)
+     return (char *) _nl_current_default_domain;
+ 
+-  __libc_rwlock_wrlock (_nl_state_lock);
++  gl_rwlock_wrlock (_nl_state_lock);
+ 
+   old_domain = (char *) _nl_current_default_domain;
+ 
+@@ -131,7 +114,7 @@ TEXTDOMAIN (domainname)
+ 	free (old_domain);
+     }
+ 
+-  __libc_rwlock_unlock (_nl_state_lock);
++  gl_rwlock_unlock (_nl_state_lock);
+ 
+   return new_domain;
+ }
+-- 
+1.9.2
+
diff --git a/recipes-core/glibc/glibc/ld-search-order.patch b/recipes-core/glibc/glibc/ld-search-order.patch
new file mode 100644
index 0000000..f518bc7
--- /dev/null
+++ b/recipes-core/glibc/glibc/ld-search-order.patch
@@ -0,0 +1,56 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+The default lib search path order is:
+
+  1) LD_LIBRARY_PATH
+  2) RPATH from the binary
+  3) ld.so.cache
+  4) default search paths embedded in the linker
+
+For nativesdk binaries which are being used alongside binaries on a host system, we 
+need the search paths to firstly search the shipped nativesdk libs but then also
+cover the host system. For example we want the host system's libGL and this may be
+in a non-standard location like /usr/lib/mesa. The only place the location is know 
+about is in the ld.so.cache of the host system.
+
+Since nativesdk has a simple structure and doesn't need to use a cache itself, we 
+repurpose the cache for use as a last resort in finding host system binaries. This 
+means we need to switch the order of 3 and 4 above to make this work effectively.
+
+RP 14/10/2010
+
+Index: git/elf/dl-load.c
+===================================================================
+--- git.orig/elf/dl-load.c	2014-08-28 17:32:46.292070587 -0700
++++ git/elf/dl-load.c	2014-08-28 17:33:56.048070587 -0700
+@@ -2050,7 +2050,14 @@
+ 	fd = open_path (name, namelen, mode,
+ 			&loader->l_runpath_dirs, &realname, &fb, loader,
+ 			LA_SER_RUNPATH, &found_other_class);
+-
++      /* try the default path.  */
++      if (fd == -1
++	  && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
++	   || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
++	 && rtld_search_dirs.dirs != (void *) -1)
++	fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs,
++			&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
++      /* Finally try ld.so.cache */
+ #ifdef USE_LDCONFIG
+       if (fd == -1
+ 	  && (__glibc_likely ((mode & __RTLD_SECURE) == 0)
+@@ -2113,14 +2120,6 @@
+ 	}
+ #endif
+ 
+-      /* Finally, try the default path.  */
+-      if (fd == -1
+-	  && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
+-	      || __glibc_likely (!(l->l_flags_1 & DF_1_NODEFLIB)))
+-	  && rtld_search_dirs.dirs != (void *) -1)
+-	fd = open_path (name, namelen, mode, &rtld_search_dirs,
+-			&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
+-
+       /* Add another newline when we are tracing the library loading.  */
+       if (__glibc_unlikely (GLRO_dl_debug_mask & DL_DEBUG_LIBS))
+ 	_dl_debug_printf ("\n");
diff --git a/recipes-core/glibc/glibc/mips-rld-map-check.patch b/recipes-core/glibc/glibc/mips-rld-map-check.patch
new file mode 100644
index 0000000..9f593d6
--- /dev/null
+++ b/recipes-core/glibc/glibc/mips-rld-map-check.patch
@@ -0,0 +1,27 @@
+
+On mips target, binutils currently sets DT_MIPS_RLD_MAP to 0 in dynamic
+section if a --version-script sets _RLD_MAP to local. This is apparently
+a binutils bug, but libc shouldn't segfault in this case.
+
+see also: http://sourceware.org/bugilla/show_bug.cgi?id=11615
+
+Upstream-Status: Pending
+
+9/19/2010 - added by Qing He <qing.he@intel.com>
+
+
+---
+Index: git/sysdeps/mips/dl-machine.h
+===================================================================
+--- git.orig/sysdeps/mips/dl-machine.h	2014-08-27 04:58:11.840070587 +0000
++++ git/sysdeps/mips/dl-machine.h	2014-08-27 04:58:11.832070587 +0000
+@@ -70,7 +70,8 @@
+ /* If there is a DT_MIPS_RLD_MAP entry in the dynamic section, fill it in
+    with the run-time address of the r_debug structure  */
+ #define ELF_MACHINE_DEBUG_SETUP(l,r) \
+-do { if ((l)->l_info[DT_MIPS (RLD_MAP)]) \
++do { if ((l)->l_info[DT_MIPS (RLD_MAP)] && \
++         (l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) \
+        *(ElfW(Addr) *)((l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) = \
+        (ElfW(Addr)) (r); \
+    } while (0)
diff --git a/recipes-core/glibc/glibc/multilib_readlib.patch b/recipes-core/glibc/glibc/multilib_readlib.patch
new file mode 100644
index 0000000..13ffc46
--- /dev/null
+++ b/recipes-core/glibc/glibc/multilib_readlib.patch
@@ -0,0 +1,19 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+Replace the OECORE_KNOWN_INTERPRETER_NAMES with the value of 
+variable EGLIBC_KNOWN_INTERPRETER_NAMES.
+
+Lianhao Lu, 08/01/2011
+
+Index: git/elf/readlib.c
+===================================================================
+--- git.orig/elf/readlib.c	2014-08-29 10:34:16.824070587 -0700
++++ git/elf/readlib.c	2014-08-29 10:34:16.816070587 -0700
+@@ -51,6 +51,7 @@
+ #ifdef SYSDEP_KNOWN_INTERPRETER_NAMES
+   SYSDEP_KNOWN_INTERPRETER_NAMES
+ #endif
++  OECORE_KNOWN_INTERPRETER_NAMES
+ };
+ 
+ static struct known_names known_libs[] =
diff --git a/recipes-core/glibc/glibc/option-groups.patch b/recipes-core/glibc/glibc/option-groups.patch
new file mode 100644
index 0000000..198be73
--- /dev/null
+++ b/recipes-core/glibc/glibc/option-groups.patch
@@ -0,0 +1,1397 @@
+Eglibc option group infrastructure
+
+Upstream-Status: Pending
+
+Index: git/option-groups.def
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/option-groups.def	2014-08-27 07:26:51.652070587 +0000
+@@ -0,0 +1,868 @@
++# This file documents the option groups EGLIBC currently supports, in
++# a format akin to the Linux Kconfig system's.  The syntax may change
++# over time.
++#
++# An entry of the form:
++#
++#   config GROUP_NAME
++#       bool "one-line explanation of what this option group controls"
++#       help
++#           Multi-line help explaining the option group's meaning in
++#           some detail, terminated by indentation level.
++#
++# defines an option group whose variable is GROUP_NAME, with
++# meaningful values 'y' (enabled) and 'n' (disabled).  The
++# documentation is formatted to be consumed by some sort of
++# interactive configuration interface, but EGLIBC doesn't have such an
++# interface yet.
++#
++# An option may have a 'depends on' line, indicating which other options
++# must also be enabled if this option is.  At present, EGLIBC doesn't
++# check that these dependencies are satisfied.
++#
++# Option group variables get their default values from the file
++# 'option-groups.defaults', in the top directory of the EGLIBC source
++# tree.  By default, all EGLIBC option groups are enabled --- their
++# variables are set to 'y'.
++#
++# After including 'option-groups.defaults', the EGLIBC make machinery
++# includes the file 'option-groups.config' from the top of the build
++# tree, if it is present.  Developers can place assignments to option
++# group variables in that file to override the defaults.  For example,
++# to disable an option group, place a line of the form:
++#
++#    OPTION_GROUP_NAME = n
++#
++# in 'option-groups.config' at the top of your build tree.  To
++# explicitly enable an option group, you may also write:
++#
++#    OPTION_GROUP_NAME = y
++#
++# although this simply reestablishes the value already set by
++# 'option-groups.defaults'.
++
++config EGLIBC_ADVANCED_INET6
++   bool "IPv6 Advanced Sockets API support (RFC3542)"
++   depends on EGLIBC_INET
++   help
++       This option group includes the functions specified by RFC 3542,
++       "Advanced Sockets Application Program Interface (API) for
++       IPv6".
++
++       This option group includes the following functions:
++
++         inet6_opt_append
++         inet6_opt_find
++         inet6_opt_finish
++         inet6_opt_get_val
++         inet6_opt_init
++         inet6_option_alloc
++         inet6_option_append
++         inet6_option_find
++         inet6_option_init
++         inet6_option_next
++         inet6_option_space
++         inet6_opt_next
++         inet6_opt_set_val
++         inet6_rth_add
++         inet6_rth_getaddr
++         inet6_rth_init
++         inet6_rth_reverse
++         inet6_rth_segments
++         inet6_rth_space
++
++config EGLIBC_BACKTRACE
++   bool "Functions for producing backtraces"
++   help
++       This option group includes functions for producing a list of
++       the function calls that are currently active in a thread, from
++       within the thread itself.  These functions are often used
++       within signal handlers, to produce diagnostic output.
++
++       This option group includes the following functions:
++
++         backtrace
++         backtrace_symbols
++         backtrace_symbols_fd
++
++config EGLIBC_BIG_MACROS
++   bool "Use extensive inline code"
++   help
++       This option group specifies whether certain pieces of code
++       should be inlined to achieve maximum speed.  If this option
++       group is not selected, function calls will be used instead,
++       hence reducing the library footprint.
++
++config EGLIBC_BSD
++   bool "BSD-specific functions, and their compatibility stubs"
++   help
++       This option group includes functions specific to BSD kernels.
++       A number of these functions have stub versions that are also
++       included in libraries built for non-BSD systems for
++       compatibility.
++
++       This option group includes the following functions:
++
++         chflags
++         fchflags
++         lchmod
++         revoke
++         setlogin
++
++config EGLIBC_CXX_TESTS
++   bool "Tests that link against the standard C++ library."
++   depends on POSIX_WIDE_CHAR_DEVICE_IO && EGLIBC_LIBM
++   help
++       This option group does not include any C library functions;
++       instead, it controls which EGLIBC tests an ordinary 'make
++       tests' runs.  With this group disabled, tests that would
++       normally link against the standard C++ library are not
++       run.
++
++       The standard C++ library depends on the math library 'libm' and
++       the wide character I/O functions included in EGLIBC.  So those
++       option groups must be enabled if this test is enabled.
++
++config EGLIBC_CATGETS
++   bool "Functions for accessing message catalogs"
++   depends on EGLIBC_LOCALE_CODE
++   help
++       This option group includes functions for accessing message
++       catalogs: catopen, catclose, and catgets.
++
++       This option group depends on the EGLIBC_LOCALE_CODE
++       option group.
++
++config EGLIBC_CHARSETS
++   bool "iconv/gconv character set conversion libraries"
++   help
++       This option group includes support for character sets other
++       than ASCII (ANSI_X3.4-1968) and Unicode and ISO-10646 in their
++       various encodings.  This affects both the character sets
++       supported by the wide and multibyte character functions, and
++       those supported by the 'iconv' functions.
++
++       With this option group disabled, EGLIBC supports only the
++       following character sets:
++
++          ANSI_X3.4         - ASCII
++          ANSI_X3.4-1968
++          ANSI_X3.4-1986
++          ASCII
++          CP367
++          CSASCII
++          IBM367
++          ISO-IR-6
++          ISO646-US
++          ISO_646.IRV:1991
++          OSF00010020
++          US
++          US-ASCII
++
++          10646-1:1993      - ISO 10646, in big-endian UCS4 form
++          10646-1:1993/UCS4
++          CSUCS4
++          ISO-10646
++          ISO-10646/UCS4
++          OSF00010104
++          OSF00010105
++          OSF00010106
++          UCS-4
++          UCS-4BE
++          UCS4
++
++          UCS-4LE           - ISO 10646, in little-endian UCS4 form
++
++          ISO-10646/UTF-8   - ISO 10646, in UTF-8 form
++          ISO-10646/UTF8
++          ISO-IR-193
++          OSF05010001
++          UTF-8
++          UTF8
++
++          ISO-10646/UCS2    - ISO 10646, in target-endian UCS2 form
++          OSF00010100
++          OSF00010101
++          OSF00010102
++          UCS-2
++          UCS2
++
++          UCS-2BE           - ISO 10646, in big-endian UCS2 form
++          UNICODEBIG
++
++          UCS-2LE           - ISO 10646, in little-endian UCS2 form
++          UNICODELITTLE
++
++          WCHAR_T           - EGLIBC's internal form (target-endian,
++                              32-bit ISO 10646)
++
++config EGLIBC_CRYPT
++   bool "Encryption library"
++   help
++       This option group includes the `libcrypt' library which
++       provides functions for one-way encryption.  Supported
++       encryption algorithms include MD5, SHA-256, SHA-512 and DES.
++
++config EGLIBC_CRYPT_UFC
++   bool "Ultra fast `crypt' implementation"
++   depends on EGLIBC_CRYPT
++   help
++       This option group provides ultra fast DES-based implementation of
++       the `crypt' function.  When this option group is disabled,
++       (a) the library will not provide the setkey[_r] and encrypt[_r]
++       functions and (b) the crypt[_r] function will return NULL and set the
++       errno to ENOSYS if /salt/ passed does not correspond to either MD5,
++       SHA-256 or SHA-512 algorithm.
++
++config EGLIBC_DB_ALIASES
++   bool "Functions for accessing the mail aliases database"
++   help
++       This option group includues functions for looking up mail
++       aliases in '/etc/aliases' or using nsswitch.  It includes the
++       following functions:
++
++         endaliasent
++         getaliasbyname
++         getaliasbyname_r
++         getaliasent
++         getaliasent_r
++         setaliasent
++
++       When this option group is disabled, the NSS service libraries
++       also lack support for querying their mail alias tables.
++
++config EGLIBC_ENVZ
++   bool "Functions for handling envz-style environment vectors."
++   help
++       This option group contains functions for creating and operating
++       on envz vectors.  An "envz vector" is a vector of strings in a
++       contiguous block of memory, where each element is a name-value
++       pair, and elements are separated from their neighbors by null
++       characters.
++
++       This option group includes the following functions:
++
++        envz_add        envz_merge
++        envz_entry      envz_remove
++        envz_get        envz_strip
++
++config EGLIBC_FCVT
++   bool "Functions for converting floating-point numbers to strings"
++   help
++       This option group includes functions for converting
++       floating-point numbers to strings.
++
++       This option group includes the following functions:
++
++         ecvt           qecvt
++	 ecvt_r		qecvt_r
++         fcvt		qfcvt
++	 fcvt_r		qfcvt_r
++         gcvt		qgcvt
++
++config EGLIBC_FMTMSG
++   bool "Functions for formatting messages"
++   help
++       This option group includes the following functions:
++
++         addseverity    fmtmsg
++
++config EGLIBC_FSTAB
++   bool "Access functions for 'fstab'"
++   help
++       This option group includes functions for reading the mount
++       point specification table, '/etc/fstab'.  These functions are
++       not included in the POSIX standard, which provides the
++       'getmntent' family of functions instead.
++
++       This option group includes the following functions:
++
++         endfsent       getfsspec
++         getfsent       setfsent
++         getfsfile
++
++config EGLIBC_FTRAVERSE
++   bool "Functions for traversing file hierarchies"
++   help
++       This option group includes functions for traversing file
++       UNIX file hierachies.
++
++       This option group includes the following functions:
++
++         fts_open       ftw
++	 fts_read	nftw
++         fts_children	ftw64
++	 fts_set	nftw64
++         fts_close
++
++config EGLIBC_GETLOGIN
++   bool "The getlogin function"
++   depends on EGLIBC_UTMP
++   help
++       This function group includes the 'getlogin' and 'getlogin_r'
++       functions, which return the user name associated by the login
++       activity with the current process's controlling terminal.
++
++       With this option group disabled, the 'glob' function will not
++       fall back on 'getlogin' to find the user's login name for tilde
++       expansion when the 'HOME' environment variable is not set.
++
++config EGLIBC_IDN
++   bool "International domain names support"
++   help
++       This option group includes the `libcidn' library which
++       provides support for international domain names.
++
++config EGLIBC_INET
++   bool "Networking support"
++   help
++       This option group includes networking-specific functions and
++       data.  With EGLIBC_INET disabled, the EGLIBC
++       installation and API changes as follows:
++
++       - The following libraries are not installed:
++
++         libnsl
++         libnss_compat
++         libnss_dns
++         libnss_hesiod
++         libnss_nis
++         libnss_nisplus
++         libresolv
++
++       - The following functions and variables are omitted from libc:
++
++         authdes_create           hstrerror              svc_fdset
++         authdes_getucred         htonl                  svc_getreq
++         authdes_pk_create        htons                  svc_getreq_common
++         authnone_create          if_freenameindex       svc_getreq_poll
++         authunix_create          if_indextoname         svc_getreqset
++         authunix_create_default  if_nameindex           svc_max_pollfd
++         bindresvport             if_nametoindex         svc_pollfd
++         callrpc                  in6addr_any            svcraw_create
++         cbc_crypt                in6addr_loopback       svc_register
++         clnt_broadcast           inet6_opt_append       svc_run
++         clnt_create              inet6_opt_find         svc_sendreply
++         clnt_pcreateerror        inet6_opt_finish       svctcp_create
++         clnt_perrno              inet6_opt_get_val      svcudp_bufcreate
++         clnt_perror              inet6_opt_init         svcudp_create
++         clntraw_create           inet6_option_alloc     svcudp_enablecache
++         clnt_spcreateerror       inet6_option_append    svcunix_create
++         clnt_sperrno             inet6_option_find      svcunixfd_create
++         clnt_sperror             inet6_option_init      svc_unregister
++         clnttcp_create           inet6_option_next      user2netname
++         clntudp_bufcreate        inet6_option_space     xdecrypt
++         clntudp_create           inet6_opt_next         xdr_accepted_reply
++         clntunix_create          inet6_opt_set_val      xdr_array
++         des_setparity            inet6_rth_add          xdr_authdes_cred
++         ecb_crypt                inet6_rth_getaddr      xdr_authdes_verf
++         endaliasent              inet6_rth_init         xdr_authunix_parms
++         endhostent               inet6_rth_reverse      xdr_bool
++         endnetent                inet6_rth_segments     xdr_bytes
++         endnetgrent              inet6_rth_space        xdr_callhdr
++         endprotoent              inet_addr              xdr_callmsg
++         endrpcent                inet_aton              xdr_char
++         endservent               inet_lnaof             xdr_cryptkeyarg
++         ether_aton               inet_makeaddr          xdr_cryptkeyarg2
++         ether_aton_r             inet_netof             xdr_cryptkeyres
++         ether_hostton            inet_network           xdr_des_block
++         ether_line               inet_nsap_addr         xdr_double
++         ether_ntoa               inet_nsap_ntoa         xdr_enum
++         ether_ntoa_r             inet_ntoa              xdr_float
++         ether_ntohost            inet_ntop              xdr_free
++         freeaddrinfo             inet_pton              xdr_getcredres
++         freeifaddrs              innetgr                xdr_hyper
++         gai_strerror             iruserok               xdr_int
++         getaddrinfo              iruserok_af            xdr_int16_t
++         getaliasbyname           key_decryptsession     xdr_int32_t
++         getaliasbyname_r         key_decryptsession_pk  xdr_int64_t
++         getaliasent              key_encryptsession     xdr_int8_t
++         getaliasent_r            key_encryptsession_pk  xdr_keybuf
++         gethostbyaddr            key_gendes             xdr_key_netstarg
++         gethostbyaddr_r          key_get_conv           xdr_key_netstres
++         gethostbyname            key_secretkey_is_set   xdr_keystatus
++         gethostbyname2           key_setnet             xdr_long
++         gethostbyname2_r         key_setsecret          xdr_longlong_t
++         gethostbyname_r          netname2host           xdrmem_create
++         gethostent               netname2user           xdr_netnamestr
++         gethostent_r             ntohl                  xdr_netobj
++         getifaddrs               ntohs                  xdr_opaque
++         getipv4sourcefilter      passwd2des             xdr_opaque_auth
++         get_myaddress            pmap_getmaps           xdr_pmap
++         getnameinfo              pmap_getport           xdr_pmaplist
++         getnetbyaddr             pmap_rmtcall           xdr_pointer
++         getnetbyaddr_r           pmap_set               xdr_quad_t
++         getnetbyname             pmap_unset             xdrrec_create
++         getnetbyname_r           rcmd                   xdrrec_endofrecord
++         getnetent                rcmd_af                xdrrec_eof
++         getnetent_r              registerrpc            xdrrec_skiprecord
++         getnetgrent              res_init               xdr_reference
++         getnetgrent_r            rexec                  xdr_rejected_reply
++         getnetname               rexec_af               xdr_replymsg
++         getprotobyname           rexecoptions           xdr_rmtcall_args
++         getprotobyname_r         rpc_createerr          xdr_rmtcallres
++         getprotobynumber         rresvport              xdr_short
++         getprotobynumber_r       rresvport_af           xdr_sizeof
++         getprotoent              rtime                  xdrstdio_create
++         getprotoent_r            ruserok                xdr_string
++         getpublickey             ruserok_af             xdr_u_char
++         getrpcbyname             ruserpass              xdr_u_hyper
++         getrpcbyname_r           setaliasent            xdr_u_int
++         getrpcbynumber           sethostent             xdr_uint16_t
++         getrpcbynumber_r         setipv4sourcefilter    xdr_uint32_t
++         getrpcent                setnetent              xdr_uint64_t
++         getrpcent_r              setnetgrent            xdr_uint8_t
++         getrpcport               setprotoent            xdr_u_long
++         getsecretkey             setrpcent              xdr_u_longlong_t
++         getservbyname            setservent             xdr_union
++         getservbyname_r          setsourcefilter        xdr_unixcred
++         getservbyport            svcauthdes_stats       xdr_u_quad_t
++         getservbyport_r          svcerr_auth            xdr_u_short
++         getservent               svcerr_decode          xdr_vector
++         getservent_r             svcerr_noproc          xdr_void
++         getsourcefilter          svcerr_noprog          xdr_wrapstring
++         h_errlist                svcerr_progvers        xencrypt
++         h_errno                  svcerr_systemerr       xprt_register
++         herror                   svcerr_weakauth        xprt_unregister
++         h_nerr                   svc_exit
++         host2netname             svcfd_create
++
++       - The rpcgen, nscd, and rpcinfo commands are not installed.
++
++       - The 'rpc' file (a text file listing RPC services) is not installed.
++
++       Socket-related system calls do not fall in this option group,
++       because many are also used for other inter-process
++       communication mechanisms.  For example, the 'syslog' routines
++       use Unix-domain sockets to communicate with the syslog daemon;
++       syslog is valuable in non-networked contexts.
++
++config EGLIBC_INET_ANL
++   bool "Asynchronous name lookup"
++   depends on EGLIBC_INET
++   help
++       This option group includes the `libanl' library which
++       provides support for asynchronous name lookup.
++
++config EGLIBC_LIBM
++   bool "libm (math library)"
++   help
++       This option group includes the 'libm' library, containing
++       mathematical functions.  If this option group is omitted, then
++       an EGLIBC installation does not include shared or unshared versions
++       of the math library.
++
++       Note that this does not remove all floating-point related
++       functionality from EGLIBC; for example, 'printf' and 'scanf'
++       can still print and read floating-point values with this option
++       group disabled.
++
++       Note that the ISO Standard C++ library 'libstdc++' depends on
++       EGLIBC's math library 'libm'.  If you disable this option
++       group, you will not be able to build 'libstdc++' against the
++       resulting EGLIBC installation.
++
++config EGLIBC_LOCALES
++   bool "Locale definitions"
++   help
++       This option group includes all locale definitions other than
++       that for the "C" locale.  If this option group is omitted, then
++       only the "C" locale is supported.
++
++
++config EGLIBC_LOCALE_CODE
++   bool "Locale functions"
++   depends on POSIX_C_LANG_WIDE_CHAR
++   help
++       This option group includes locale support functions, programs,
++       and libraries.  With EGLIBC_LOCALE_CODE disabled,
++       EGLIBC supports only the 'C' locale (also known as 'POSIX'),
++       and ignores the settings of the 'LANG' and 'LC_*' environment
++       variables.
++
++       With EGLIBC_LOCALE_CODE disabled, the following
++       functions are omitted from libc:
++
++         duplocale   localeconv  nl_langinfo    rpmatch  strfmon_l
++         freelocale  newlocale   nl_langinfo_l  strfmon  uselocale
++
++       Furthermore, only the LC_CTYPE and LC_TIME categories of the
++       standard "C" locale are available.
++
++       The EGLIBC_CATGETS option group depends on this option group.
++
++
++config EGLIBC_MEMUSAGE
++   bool "Memory profiling library"
++   help
++       This option group includes the `libmemusage' library and
++       the `memusage' and `memusagestat' utilities.
++       These components provide memory profiling functions.
++
++config EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE
++   int "Memory profiling library buffer size"
++   depends on EGLIBC_MEMUSAGE
++   default "32768"
++   help
++       Libmemusage library buffers the profiling data in memory
++       before writing it out to disk.  By default, the library
++       allocates 1.5M buffer, which can be substantial for some
++       systems.  EGLIBC_MEMUSAGE_DEFAULT_BUFFER_SIZE option
++       allows to change the default buffer size.  It specifies
++       the number of entries the buffer should have.
++       On most architectures one buffer entry amounts to 48 bytes,
++       so setting this option to the value of 512 will reduce the size of
++       the memory buffer to 24K.
++
++config EGLIBC_NIS
++   bool "Support for NIS, NIS+, and the special 'compat' services."
++   depends on EGLIBC_INET && EGLIBC_SUNRPC
++   help
++       This option group includes the NIS, NIS+, and 'compat' Name
++       Service Switch service libraries.  When it is disabled, those
++       services libraries are not installed; you should remove any
++       references to them from your 'nsswitch.conf' file.
++
++       This option group depends on the EGLIBC_INET option
++       group; you must enable that to enable this option group.
++
++config EGLIBC_NSSWITCH
++   bool "Name service switch (nsswitch) support"
++   help
++       This option group includes support for the 'nsswitch' facility.
++       With this option group enabled, all EGLIBC functions for
++       accessing various system databases (passwords and groups;
++       networking; aliases; public keys; and so on) consult the
++       '/etc/nsswitch.conf' configuration file to decide how to handle
++       queries.
++
++       With this option group disabled, EGLIBC uses a fixed list of
++       services to satisfy queries on each database, as requested by
++       configuration files specified when EGLIBC is built.  Your
++       'option-groups.config' file must set the following two
++       variables:
++
++config EGLIBC_NSSWITCH_FIXED_CONFIG
++   string "Nsswitch fixed config filename"
++   depends on !EGLIBC_NSSWITCH
++   default ""
++   help
++          Set this to the name of a file whose contents observe the
++          same syntax as an ordinary '/etc/nsswitch.conf' file.  The
++          EGLIBC build process parses this file just as EGLIBC would
++          at run time if EGLIBC_NSSWITCH were enabled, and
++          produces a C library that uses the nsswitch service
++          libraries to search for database entries as this file
++          specifies, instead of consulting '/etc/nsswitch.conf' at run
++          time.
++
++          This should be an absolute filename.  The EGLIBC build
++          process may use it from several different working
++          directories.  It may include references to Makefile
++          variables like 'common-objpfx' (the top of the build tree,
++          with a trailing slash), or '..' (the top of the source tree,
++          with a trailing slash).
++
++          The EGLIBC source tree includes a sample configuration file
++          named 'nss/fixed-nsswitch.conf'; for simple configurations,
++          you will probably want to delete references to databases not
++          needed on your system.
++
++config EGLIBC_NSSWITCH_FIXED_FUNCTIONS
++   string "Nsswitch fixed functions filename"
++   depends on !EGLIBC_NSSWITCH
++   default ""
++   help
++          The EGLIBC build process uses this file to decide which
++          functions to make available from which service libraries.
++          The file 'nss/fixed-nsswitch.functions' serves as a sample
++          configuration file for this setting, and explains its syntax
++          and meaning in more detail.
++
++          This should be an absolute file name.  The EGLIBC build
++          process may use it from several different working
++          directories.  It may include references to Makefile
++          variables like 'common-objpfx' (the top of the build tree,
++          with a trailing slash), or '..' (the top of the source tree,
++          with a trailing slash).
++
++          Be sure to mention each function in each service you wish to
++          use.  If you do not mention a service's function here, the
++          EGLIBC database access functions will not find it, even if
++          it is listed in the EGLIBC_NSSWITCH_FIXED_CONFIG
++          file.
++
++          In this arrangement, EGLIBC will not use the 'dlopen' and
++          'dlsym' functions to find database access functions.  Instead,
++          libc hard-codes references to the service libraries' database
++          access functions.  You must explicitly link your program
++          against the name service libraries (those whose names start
++          with 'libnss_', in the sysroot's '/lib' directory) whose
++          functions you intend to use.  This arrangement helps
++          system-wide static analysis tools decide which functions a
++          system actually uses.
++
++          Note that some nsswitch service libraries require other option
++          groups to be enabled; for example, the EGLIBC_INET
++          option group must be enabled to use the 'libnss_dns.so.2'
++          service library, which uses the Domain Name System network
++          protocol to answer queries.
++
++config EGLIBC_RCMD
++   bool "Support for 'rcmd' and related library functions"
++   depends on EGLIBC_INET
++   help
++      This option group includes functions for running commands on
++      remote machines via the 'rsh' protocol, and doing authentication
++      related to those functions.  This also includes functions that
++      use the 'rexec' protocol.
++
++      This option group includes the following functions:
++
++        rcmd            ruserok
++        rcmd_af         ruserok_af
++        rexec           iruserok
++        rexec_af        iruserok_af
++        rresvport       ruserpass
++        rresvport_af
++
++config EGLIBC_RTLD_DEBUG
++   bool "Runtime linker debug print outs"
++   help
++      This option group enables debug output of the runtime linker
++      which is activated via LD_DEBUG and LD_TRACE_PRELINKING
++      environment variables.  Disabling this option group yields
++      a smaller runtime linker binary.
++      BEWARE: Disabling this option group is likely to break
++      the `ldd' utility which may also be used by the prelinker.
++      In particular, the `--unused' ldd option will not work correctly.
++
++config EGLIBC_SPAWN
++   bool "Support for POSIX posix_spawn functions"
++   help
++      This option group includes the POSIX functions for executing
++      programs in child processes without using 'fork' or 'vfork'.
++
++      This option group includes the following functions:
++
++        posix_spawn
++        posix_spawnattr_destroy
++        posix_spawnattr_getflags
++        posix_spawnattr_getpgroup
++        posix_spawnattr_getschedparam
++        posix_spawnattr_getschedpolicy
++        posix_spawnattr_getsigdefault
++        posix_spawnattr_getsigmask
++        posix_spawnattr_init
++        posix_spawnattr_setflags
++        posix_spawnattr_setpgroup
++        posix_spawnattr_setschedparam
++        posix_spawnattr_setschedpolicy
++        posix_spawnattr_setsigdefault
++        posix_spawnattr_setsigmask
++        posix_spawn_file_actions_addclose
++        posix_spawn_file_actions_adddup2
++        posix_spawn_file_actions_addopen
++        posix_spawn_file_actions_destroy
++        posix_spawn_file_actions_init
++        posix_spawnp
++
++      This option group also provides the ability for the iconv,
++      localedef, and locale programs to operate transparently on
++      compressed charset definitions.  When this option group is
++      disabled, those programs will only operate on uncompressed
++      charmap files.
++
++config EGLIBC_STREAMS
++   bool "Support for accessing STREAMS."
++   help
++      This option group includes functions for reading and writing
++      messages to and from STREAMS.  The STREAMS interface provides a
++      uniform mechanism for implementing networking services and other
++      character-based I/O.  (STREAMS are not to be confused with
++      <stdio.h> FILE objects, also called 'streams'.)
++
++      This option group includes the following functions:
++
++        getmsg          putpmsg
++        getpmsg         fattach
++        isastream       fdetach
++        putmsg
++
++config EGLIBC_SUNRPC
++   bool "Support for the Sun 'RPC' protocol."
++   depends on EGLIBC_INET
++   help
++      This option group includes support for the Sun RPC protocols,
++      including the 'rpcgen' and 'rpcinfo' programs.
++
++config EGLIBC_UTMP
++    bool "Older access functions for 'utmp' login records"
++    help
++       This option group includes the older 'utent' family of
++       functions for accessing user login records in the 'utmp' file.
++       POSIX omits these functions in favor of the 'utxent' family,
++       and they are obsolete on systems other than Linux.
++
++       This option group includes the following functions:
++
++         endutent
++         getutent
++         getutent_r
++         getutid
++         getutid_r
++         getutline
++         getutline_r
++         logwtmp
++         pututline
++         setutent
++         updwtmp
++         utmpname
++
++       This option group includes the following libraries:
++
++         libutil.so (and libutil.a)
++
++config EGLIBC_UTMPX
++    bool "POSIX access functions for 'utmp' login records"
++    depends on EGLIBC_UTMP
++    help
++       This option group includes the POSIX functions for reading and
++       writing user login records in the 'utmp' file (usually
++       '/var/run/utmp').  The POSIX functions operate on 'struct
++       utmpx' structures, as opposed to the family of older 'utent'
++       functions, which operate on 'struct utmp' structures.
++
++       This option group includes the following functions:
++
++         endutxent
++         getutmp
++         getutmpx
++         getutxent
++         getutxid
++         getutxline
++         pututxline
++         setutxent
++         updwtmpx
++         utmpxname
++
++config EGLIBC_WORDEXP
++    bool "Shell-style word expansion"
++    help
++        This option group includes the 'wordexp' function for
++        performing word expansion in the manner of the shell, and the
++        accompanying 'wordfree' function.
++
++config POSIX_C_LANG_WIDE_CHAR
++    bool "ISO C library wide character functions, excluding I/O"
++    help
++        This option group includes the functions defined by the ISO C
++        standard for working with wide and multibyte characters in
++        memory.  Functions for reading and writing wide and multibyte
++        characters from and to files call in the
++        POSIX_WIDE_CHAR_DEVICE_IO option group.
++
++        This option group includes the following functions:
++
++          btowc         mbsinit       wcscspn       wcstoll
++          iswalnum      mbsrtowcs     wcsftime      wcstombs
++          iswalpha      mbstowcs      wcslen        wcstoul
++          iswblank      mbtowc        wcsncat       wcstoull
++          iswcntrl      swprintf      wcsncmp       wcstoumax
++          iswctype      swscanf       wcsncpy       wcsxfrm
++          iswdigit      towctrans     wcspbrk       wctob
++          iswgraph      towlower      wcsrchr       wctomb
++          iswlower      towupper      wcsrtombs     wctrans
++          iswprint      vswprintf     wcsspn        wctype
++          iswpunct      vswscanf      wcsstr        wmemchr
++          iswspace      wcrtomb       wcstod        wmemcmp
++          iswupper      wcscat        wcstof        wmemcpy
++          iswxdigit     wcschr        wcstoimax     wmemmove
++          mblen         wcscmp        wcstok        wmemset
++          mbrlen        wcscoll       wcstol
++          mbrtowc       wcscpy        wcstold
++
++config POSIX_REGEXP
++    bool "Regular expressions"
++    help
++        This option group includes the POSIX regular expression
++        functions, and the associated non-POSIX extensions and
++        compatibility functions.
++
++        With POSIX_REGEXP disabled, the following functions are
++        omitted from libc:
++
++          re_comp                 re_max_failures         regcomp
++          re_compile_fastmap      re_search               regerror
++          re_compile_pattern      re_search_2             regexec
++          re_exec                 re_set_registers        regfree
++          re_match                re_set_syntax           rpmatch
++          re_match_2              re_syntax_options
++
++        Furthermore, the compatibility regexp interface defined in the
++        <regexp.h> header file, 'compile', 'step', and 'advance', is
++        omitted.
++
++config POSIX_REGEXP_GLIBC
++    bool "Regular expressions from GLIBC"
++    depends on POSIX_REGEXP
++    help
++	This option group specifies which regular expression
++        library to use.  The choice is between regex
++        implementation from GLIBC and regex implementation from
++        libiberty.  The GLIBC variant is fully POSIX conformant and
++        optimized for speed; regex from libiberty is more than twice
++        as small while still is enough for most practical purposes.
++
++config POSIX_WIDE_CHAR_DEVICE_IO
++    bool "Input and output functions for wide characters"
++    depends on POSIX_C_LANG_WIDE_CHAR
++    help
++        This option group includes functions for reading and writing
++        wide characters to and from <stdio.h> streams.
++
++        This option group includes the following functions:
++
++          fgetwc        fwprintf      putwchar      vwscanf
++          fgetws        fwscanf       ungetwc       wprintf
++          fputwc        getwc         vfwprintf     wscanf
++          fputws        getwchar      vfwscanf
++          fwide         putwc         vwprintf
++
++        This option group further includes the following unlocked
++        variants of the above functions:
++
++          fgetwc_unlocked           getwc_unlocked
++          fgetws_unlocked           getwchar_unlocked
++          fputwc_unlocked           putwc_unlocked
++          fputws_unlocked           putwchar_unlocked
++
++        Note that the GNU standard C++ library, 'libstdc++.so', uses
++        some of these functions; you will not be able to link or run
++        C++ programs if you disable this option group.
++
++        This option group also affects the behavior of the following
++        functions:
++
++          fdopen
++          fopen
++          fopen64
++          freopen
++          freopen64
++
++        These functions all take an OPENTYPE parameter which may
++        contain a string of the form ",ccs=CHARSET", indicating that
++        the underlying file uses the character set named CHARSET.
++        This produces a wide-oriented stream, which is only useful
++        when the functions included in this option group are present.
++        If the user attempts to open a file specifying a character set
++        in the OPENTYPE parameter, and EGLIBC was built with this
++        option group disabled, the function returns NULL, and sets
++        errno to EINVAL.
++
++\f
++# This helps Emacs users browse this file using the page motion commands
++# and commands like 'pages-directory'.
++# Local Variables:
++# page-delimiter: "^config\\s-"
++# End:
+Index: git/option-groups.mak
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/option-groups.mak	2014-08-27 07:26:51.652070587 +0000
+@@ -0,0 +1,41 @@
++# Setup file for subdirectory Makefiles that define EGLIBC option groups.
++
++# EGLIBC shouldn't need to override this.  However, the
++# cross-build-friendly localedef includes this makefile to get option
++# group variable definitions; it uses a single build tree for all the
++# multilibs, and needs to be able to specify a different option group
++# configuration file for each multilib.
++option_group_config_file ?= $(objdir)/option-groups.config
++
++# Read the default settings for all options.
++# We're included before ../Rules, so we can't assume $(..) is set.
++include $(firstword $(..) ../)option-groups.defaults
++
++# Read the developer's option group selections, overriding the
++# defaults from option-groups.defaults.
++-include $(option_group_config_file)
++
++# $(call option-disabled, VAR) is 'y' if VAR is not 'y', or 'n' otherwise.
++# VAR should be a variable name, not a variable reference; this is
++# less general, but more terse for the intended use.
++# You can use it to add a file to a list if an option group is
++# disabled, like this:
++#   routines-$(call option-disabled, OPTION_POSIX_C_LANG_WIDE_CHAR) += ...
++define option-disabled
++$(firstword $(subst y,n,$(filter y,$($(strip $(1))))) y)
++endef
++
++# Establish 'routines-y', etc. as simply-expanded variables.
++aux-y	       	    :=
++extra-libs-others-y :=
++extra-libs-y   	    :=
++extra-objs-y   	    :=
++install-bin-y  	    :=
++install-others-y    :=
++install-sbin-y 	    :=
++others-y       	    :=
++others-pie-y   	    :=
++routines-y     	    :=
++test-srcs-y    	    :=
++tests-y        	    :=
++xtests-y       	    :=
+Index: git/option-groups.defaults
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/option-groups.defaults	2014-08-27 07:24:41.652070587 +0000
+@@ -0,0 +1,47 @@
++# This file sets default values for all option group variables
++# mentioned in option-groups.def; see that file for a description of
++# each option group.
++#
++# Subdirectory makefiles include this file before including the user's
++# settings from option-groups.config at the top of the build tree;
++# that file need only refer to those options whose default settings
++# are to be changed.
++#
++# By default, all option groups are enabled.
++OPTION_EGLIBC_ADVANCED_INET6 = y
++OPTION_EGLIBC_BACKTRACE = y
++OPTION_EGLIBC_BIG_MACROS = y
++OPTION_EGLIBC_BSD = y
++OPTION_EGLIBC_CXX_TESTS = y
++OPTION_EGLIBC_CATGETS = y
++OPTION_EGLIBC_CHARSETS = y
++OPTION_EGLIBC_CRYPT = y
++OPTION_EGLIBC_CRYPT_UFC = y
++OPTION_EGLIBC_DB_ALIASES = y
++OPTION_EGLIBC_ENVZ = y
++OPTION_EGLIBC_FCVT = y
++OPTION_EGLIBC_FMTMSG = y
++OPTION_EGLIBC_FSTAB = y
++OPTION_EGLIBC_FTRAVERSE = y
++OPTION_EGLIBC_GETLOGIN = y
++OPTION_EGLIBC_IDN = y
++OPTION_EGLIBC_INET = y
++OPTION_EGLIBC_INET_ANL = y
++OPTION_EGLIBC_LIBM = y
++OPTION_EGLIBC_LOCALES = y
++OPTION_EGLIBC_LOCALE_CODE = y
++OPTION_EGLIBC_MEMUSAGE = y
++OPTION_EGLIBC_NIS = y
++OPTION_EGLIBC_NSSWITCH = y
++OPTION_EGLIBC_RCMD = y
++OPTION_EGLIBC_RTLD_DEBUG = y
++OPTION_EGLIBC_SPAWN = y
++OPTION_EGLIBC_STREAMS = y
++OPTION_EGLIBC_SUNRPC = y
++OPTION_EGLIBC_UTMP = y
++OPTION_EGLIBC_UTMPX = y
++OPTION_EGLIBC_WORDEXP = y
++OPTION_POSIX_C_LANG_WIDE_CHAR = y
++OPTION_POSIX_REGEXP = y
++OPTION_POSIX_REGEXP_GLIBC = y
++OPTION_POSIX_WIDE_CHAR_DEVICE_IO = y
+Index: git/Makefile
+===================================================================
+--- git.orig/Makefile	2014-08-27 07:24:37.540070587 +0000
++++ git/Makefile	2014-08-27 07:24:41.656070587 +0000
+@@ -24,6 +24,7 @@
+ 
+ include Makeconfig
+ 
++include options-config/Makefile
+ 
+ # This is the default target; it makes everything except the tests.
+ .PHONY: all
+Index: git/EGLIBC.option-groups
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/EGLIBC.option-groups	2014-08-27 07:24:41.656070587 +0000
+@@ -0,0 +1,122 @@
++                                                        -*- mode: text -*-
++
++              The EGLIBC Component Configuration System
++                  Jim Blandy <jimb@codesourcery.com>
++
++Introduction
++
++The GNU C library (GLIBC) provides a broad range of functionality,
++ranging from internationalization support to transcendental
++mathematical functions.  Its website boasts that "nearly all known and
++useful functions from any other C library are available."  This
++exhaustive approach has been one of GLIBC's strengths on desktop and
++server systems, but it has also given GLIBC a large footprint, both in
++memory and on disk, making it a challenge to use in embedded systems
++with limited resources.
++
++The Embedded GNU C library (EGLIBC) is a variant of the GNU C library
++designed to work well on embedded systems.  In particular, EGLIBC's
++component configuration system allows embedded developers to build
++customized versions of the library that include only the features
++their application uses, reducing its space requirements.
++
++EGLIBC's component configuration system categorizes the library's
++functions into "option groups", and allows you to include or exclude
++option groups individually.  Some option groups depend on others;
++EGLIBC tracks these relationships, and ensures that the selected
++configuration yields a functioning library.
++
++
++Consistent and Predictable Behavior
++
++A flexible configuration system is a mixed blessing: if the options
++offered are poorly designed, it can be hard to see which choices will
++have the desired effects, and choices with obscure consequences can
++make debugging difficult.  EGLIBC's configuration follows some general
++principles to reduce these risks:
++
++- EGLIBC has a single default configuration for each target
++  architecture.
++
++- In the default configuration, all option groups are enabled, and
++  EGLIBC is upwardly API- and ABI-compatible with GLIBC.
++
++- As much as possible, configurations only affect what functions are
++  present, not how they behave.  If the system works with an option
++  group disabled, it will still work with it enabled.
++
++- As much as possible, configurations only select option groups ---
++  they do not describe characteristics of the target architecture.
++
++These rules mean that you have a simple debugging strategy available
++if you suspect that your EGLIBC configuration might be the source of a
++problem: fall back to the default configuration, re-test, and then
++disable option groups one by one, until the problem reappears.
++
++
++The Option Groups
++
++To see the current full list of implemented option groups, refer to the
++file 'option-groups.def' at the top of the source tree, or run
++'make menuconfig' from the top-level build directory.
++
++The POSIX.1-2001 specification includes a suggested partition of all
++the functions in the POSIX C API into option groups: math functions
++like 'sin' and 'cos'; networking functions like 'socket' and
++'connect'; and so on.  EGLIBC could use this partitioning as the basis
++for future option groups.
++
++
++Implementation
++
++The EGLIBC component configuration system resembles the approach used
++by the Linux kernel to select device drivers, network protocols, and
++other features.  A file named 'option-groups.config' in the top-level
++build directory contains assignments to Make variables, each of which
++enables or disables a particular option group.  If the variable's
++value is set to 'y', then the option group is enabled; if it set to
++anything else, the option group is omitted.  The file
++'option-groups.defaults', at the top of the source tree, establishes
++default values for all variables; all option groups are enabled by
++default.
++
++For example, the following 'option-groups.config' would omit locale
++data, but include mathematical functions, and everything else:
++
++   OPTION_EGLIBC_LOCALES = n
++   OPTION_EGLIBC_LIBM = y
++
++Like the Linux kernel, EGLIBC supports a similar set of '*config' make
++targets to make it easier to create 'option-groups.config', with all
++dependencies between option groups automatically satisfied.  Run
++'make help' to see the list of supported make config targets.  For
++example, 'make menuconfig' will update the current config utilising a
++menu based program.
++
++The option group names and their type (boolean, int, hex, string), help
++description, and dependencies with other option groups, are described by
++'option-groups.def' at the top of the source tree, analogous to the
++'Kconfig' files in the Linux kernel.
++
++In general, each option group variable controls whether a given set of
++object files in EGLIBC is compiled and included in the final
++libraries, or omitted from the build.
++
++Each subdirectory's Makefile categorizes its routines, libraries, and
++executables by option group.  For example, EGLIBC's 'math/Makefile'
++places the 'libm' library in the OPTION_EGLIBC_LIBM group as follows:
++
++   extra-libs-$(OPTION_EGLIBC_LIBM) := libm
++
++Finally, common code in 'Makerules' cites the value of the variable
++'extra-libs-y', selecting only those libraries that belong to enabled
++option groups to be built.
++
++
++Current Status and Future Directions
++
++The EGLIBC component configuration system described here is still
++under development.
++
++We have used the system to subset some portions of EGLIBC's
++Index: libc/configure.ac
+Index: git/configure.ac
+===================================================================
+--- git.orig/configure.ac	2014-08-27 07:24:41.196070587 +0000
++++ git/configure.ac	2014-08-27 07:24:41.656070587 +0000
+@@ -127,6 +127,16 @@
+ 	    [sysheaders=''])
+ AC_SUBST(sysheaders)
+ 
++AC_ARG_WITH([kconfig],
++	    AC_HELP_STRING([--with-kconfig=PATH],
++			   [location of kconfig tools to use (from Linux
++			    kernel builds) to re-use for configuring EGLIBC
++			    option groups]),
++	    [KCONFIG_TOOLS=$withval],
++	    [KCONFIG_TOOLS=''])
++AC_SUBST(KCONFIG_TOOLS)
++
++
+ AC_SUBST(use_default_link)
+ AC_ARG_WITH([default-link],
+ 	    AC_HELP_STRING([--with-default-link],
+Index: git/config.make.in
+===================================================================
+--- git.orig/config.make.in	2014-08-27 07:24:37.560070587 +0000
++++ git/config.make.in	2014-08-27 07:24:41.656070587 +0000
+@@ -46,6 +46,8 @@
+ c++-sysincludes = @CXX_SYSINCLUDES@
+ all-warnings = @all_warnings@
+ 
++kconfig_tools = @KCONFIG_TOOLS@
++
+ have-z-combreloc = @libc_cv_z_combreloc@
+ have-z-execstack = @libc_cv_z_execstack@
+ have-Bgroup = @libc_cv_Bgroup@
+Index: git/configure
+===================================================================
+--- git.orig/configure	2014-08-27 07:24:41.192070587 +0000
++++ git/configure	2014-08-27 07:24:41.660070587 +0000
+@@ -619,6 +619,7 @@
+ PERL
+ BASH_SHELL
+ libc_cv_gcc_static_libgcc
++KCONFIG_TOOLS
+ CXX_SYSINCLUDES
+ SYSINCLUDES
+ AUTOCONF
+@@ -733,6 +734,7 @@
+ with_binutils
+ with_selinux
+ with_headers
++with_kconfig
+ with_default_link
+ enable_sanity_checks
+ enable_shared
+@@ -1437,6 +1439,9 @@
+   --with-selinux          if building with SELinux support
+   --with-headers=PATH     location of system headers to use (for example
+                           /usr/src/linux/include) [default=compiler default]
++  --with-kconfig=PATH     location of kconfig tools to use (from Linux kernel
++                          builds) to re-use for configuring EGLIBC option
++                          groups
+   --with-default-link     do not use explicit linker scripts
+   --with-cpu=CPU          select code for CPU variant
+ 
+@@ -3400,6 +3405,14 @@
+ 
+ 
+ 
++# Check whether --with-kconfig was given.
++if test "${with_kconfig+set}" = set; then
++  withval=$with_kconfig; KCONFIG_TOOLS=$withval
++else
++  KCONFIG_TOOLS=''
++fi
++
++
+ 
+ # Check whether --with-default-link was given.
+ if test "${with_default_link+set}" = set; then :
+Index: git/options-config/Makefile
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/options-config/Makefile	2014-08-27 07:24:41.652070587 +0000
+@@ -0,0 +1,55 @@
++# ===========================================================================
++# EGLIBC option-groups configuration targets
++# These targets are included from top-level makefile
++
++ifneq ($(kconfig_tools),)
++ifneq (no,$(PERL))
++
++ocdir := options-config
++
++OconfigDefaults     := option-groups.defaults
++OconfigDefaults_tmp := $(common-objpfx).tmp.defconfig
++OconfigDef          := option-groups.def
++Oconfig             := $(common-objpfx)option-groups.config
++Oconfig_tmp         := $(common-objpfx).tmp.config
++
++conf  := $(kconfig_tools)/conf
++mconf := $(kconfig_tools)/mconf
++
++preproc  := $(PERL) $(ocdir)/config-preproc.pl
++postproc := $(PERL) $(ocdir)/config-postproc.pl
++
++PHONY += defconfig config menuconfig
++
++defconfig: $(conf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(OconfigDefaults_tmp)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(OconfigDefaults) > $(OconfigDefaults_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< --defconfig=$(OconfigDefaults_tmp) \
++				$(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++	rm $(OconfigDefaults_tmp)
++
++config: $(conf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< --oldaskconfig $(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++
++menuconfig: $(mconf) $(OconfigDefaults) $(OconfigDef)
++	rm -f $(Oconfig_tmp)
++	$(preproc) $(wildcard $(Oconfig)) > $(Oconfig_tmp)
++	KCONFIG_CONFIG=$(Oconfig_tmp) $< $(OconfigDef)
++	$(postproc) $(OconfigDefaults) $(Oconfig_tmp) > $(Oconfig)
++	rm $(Oconfig_tmp)
++
++# Help text used by make help
++help:
++	@echo  '  defconfig	  - New config with default from default config'
++	@echo  '  config	  - Update current config utilising a line-oriented program'
++	@echo  '  menuconfig	  - Update current config utilising a menu based program'
++
++endif
++endif
+Index: git/options-config/config-postproc.pl
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/options-config/config-postproc.pl	2014-08-27 07:24:41.652070587 +0000
+@@ -0,0 +1,58 @@
++#!/usr/bin/perl
++
++$usage = "usage: $0 <default config file> <config file>\n";
++
++die "$usage" unless @ARGV;
++$defaults = shift @ARGV;
++die "$usage" unless @ARGV;
++die "Could not open $ARGV[0]" unless -T $ARGV[0];
++
++sub yank {
++    @option = grep(!($_ =~ /$_[0]\s*=/), @option);
++}
++
++open(DEFAULTS, $defaults) || die "Could not open $defaults\n";
++
++# get the full list of available options using the default config file
++$i = 0;
++while (<DEFAULTS>) {
++    if (/^\s*OPTION_(\w+\s*=.*$)/) {
++	$option[$i++] = $1;
++    }
++}
++
++# now go through the config file, making the necessary changes
++while (<>) {
++    if (/Linux Kernel Configuration/) {
++	# change title
++	s/Linux Kernel/Option Groups/;
++	print;
++    } elsif (/^\s*CONFIG_(\w+)\s*=/) {
++	# this is an explicit option set line, change CONFIG_ to OPTION_
++	# before printing and remove this option from option list
++	$opt = $1;
++	yank($opt);
++	s/CONFIG_/OPTION_/g;
++	print;
++    } elsif (/^\s*#\s+CONFIG_(\w+) is not set/) {
++	# this is a comment line for an unset boolean option, change CONFIG_
++	# to OPTION_, remove this option from option list, and convert to
++	# explicit OPTION_FOO=n
++	$opt = $1;
++	yank($opt);
++	s/CONFIG_/OPTION_/g;
++	print "OPTION_$opt=n\n";
++    } else {
++	print;
++    }
++}
++
++# any boolean options left in @options, are options that were not mentioned in
++# the config file, and implicitly that means the option must be set =n,
++# so do that here.
++foreach $opt (@option) {
++    if ($opt =~ /=\s*[yn]/) {
++	$opt =~ s/=\s*[yn]/=n/;
++	print "OPTION_$opt\n";
++    }
++}
+Index: git/options-config/config-preproc.pl
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/options-config/config-preproc.pl	2014-08-27 07:24:41.652070587 +0000
+@@ -0,0 +1,8 @@
++#!/usr/bin/perl
++
++if (@ARGV) {
++    while (<>) {
++	s/OPTION_/CONFIG_/g;
++	print;
++    }
++}
+Index: git/scripts/option-groups.awk
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ git/scripts/option-groups.awk	2014-08-27 07:26:51.652070587 +0000
+@@ -0,0 +1,63 @@
++# option-groups.awk --- generate option group header file
++# Given input files containing makefile-style assignments to variables,
++# print out a header file that #defines an appropriate preprocessor
++# symbol for each variable left set to 'y'.
++
++BEGIN { FS="=" }
++
++# Trim spaces.
++{ gsub (/[[:blank:]]/, "") }
++
++# Skip comments.
++/^#/ { next }
++
++# Process assignments.
++NF == 2 {
++    vars[$1] = $2
++}
++
++# Print final values.
++END {
++    print "/* This file is automatically generated by scripts/option-groups.awk"
++    print "   in the EGLIBC source tree."
++    print ""
++    print "   It defines macros that indicate which EGLIBC option groups were"
++    print "   configured in 'option-groups.config' when this C library was"
++    print "   built.  For each option group named OPTION_foo, it #defines"
++    print "   __OPTION_foo to be 1 if the group is enabled, or #defines that"
++    print "   symbol to be 0 if the group is disabled.  */"
++    print ""
++    print "#ifndef __GNU_OPTION_GROUPS_H"
++    print "#define __GNU_OPTION_GROUPS_H"
++    print ""
++
++    # Produce a sorted list of variable names.
++    i=0
++    for (var in vars)
++        names[i++] = var
++    n = asort (names)
++
++    for (i = 1; i <= n; i++)
++    {
++        var = names[i]
++        if (var ~ /^OPTION_/)
++        {
++            if (vars[var] == "y")
++                print "#define __" var " 1"
++            else if (vars[var] == "n")
++                print "#define __" var " 0"
++	    else if (vars[var] ~ /^[0-9]+/ ||
++		     vars[var] ~ /^0x[0-9aAbBcCdDeEfF]+/ ||
++		     vars[var] ~ /^\"/)
++		 print "#define __" var " " vars[var]
++	    else
++		print "/* #undef __" var " */"
++            # Ignore variables that don't have boolean, int, hex, or
++	    # string values. Ideally, this would be driven by the types
++	    # given in option-groups.def.
++        }
++    }
++
++    print ""
++    print "#endif /* __GNU_OPTION_GROUPS_H */"
++}
diff --git a/recipes-core/glibc/glibc/ppc-sqrt_finite.patch b/recipes-core/glibc/glibc/ppc-sqrt_finite.patch
new file mode 100644
index 0000000..6ea666b
--- /dev/null
+++ b/recipes-core/glibc/glibc/ppc-sqrt_finite.patch
@@ -0,0 +1,184 @@
+on ppc fixes the errors like below
+| ./.libs/libpulsecore-1.1.so: undefined reference to `__sqrt_finite'
+| collect2: ld returned 1 exit status
+
+Upstream-Status: Pending
+
+ChangeLog
+
+2012-01-06  Khem Raj  <raj.khem@gmail.com>
+
+	* sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c: Add __*_finite alias.
+	Remove cruft.
+	* sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c: Ditto.
+	* sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c: Ditto.
+	* sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c: Ditto.
+ 
+Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+@@ -39,14 +39,8 @@ static const float half = 0.5;
+    We find the actual square root and half of its reciprocal
+    simultaneously.  */
+ 
+-#ifdef __STDC__
+ double
+ __ieee754_sqrt (double b)
+-#else
+-double
+-__ieee754_sqrt (b)
+-     double b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -132,3 +126,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+@@ -37,14 +37,8 @@ static const float threehalf = 1.5;
+    We find the reciprocal square root and use that to compute the actual
+    square root.  */
+ 
+-#ifdef __STDC__
+ float
+ __ieee754_sqrtf (float b)
+-#else
+-float
+-__ieee754_sqrtf (b)
+-     float b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -99,3 +93,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+@@ -39,14 +39,8 @@ static const float half = 0.5;
+    We find the actual square root and half of its reciprocal
+    simultaneously.  */
+ 
+-#ifdef __STDC__
+ double
+ __ieee754_sqrt (double b)
+-#else
+-double
+-__ieee754_sqrt (b)
+-     double b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -132,3 +126,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+@@ -37,14 +37,8 @@ static const float threehalf = 1.5;
+    We find the reciprocal square root and use that to compute the actual
+    square root.  */
+ 
+-#ifdef __STDC__
+ float
+ __ieee754_sqrtf (float b)
+-#else
+-float
+-__ieee754_sqrtf (b)
+-     float b;
+-#endif
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -99,3 +93,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+@@ -132,3 +132,4 @@ __ieee754_sqrt (b)
+     }
+   return f_wash (b);
+ }
++strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+===================================================================
+--- libc.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+@@ -99,3 +99,4 @@ __ieee754_sqrtf (b)
+     }
+   return f_washf (b);
+ }
++strong_alias (__ieee754_sqrtf, __sqrtf_finite)
diff --git a/recipes-core/glibc/glibc/ppc_slow_ieee754_sqrt.patch b/recipes-core/glibc/glibc/ppc_slow_ieee754_sqrt.patch
new file mode 100644
index 0000000..5b819bc
--- /dev/null
+++ b/recipes-core/glibc/glibc/ppc_slow_ieee754_sqrt.patch
@@ -0,0 +1,365 @@
+ __ieee754_sqrt{,f} are now inline functions and call out __slow versions
+
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Upstream-Status: Pending
+Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c	2014-08-29 10:35:02.604070587 -0700
+@@ -40,7 +40,7 @@
+    simultaneously.  */
+ 
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -77,7 +77,7 @@
+ 
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -126,4 +126,12 @@
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c	2014-08-29 10:35:02.604070587 -0700
+@@ -38,7 +38,7 @@
+    square root.  */
+ 
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -93,4 +93,10 @@
+     }
+   return f_washf (b);
+ }
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c	2014-08-29 10:35:02.604070587 -0700
+@@ -40,7 +40,7 @@
+    simultaneously.  */
+ 
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -77,7 +77,7 @@
+ 
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -126,4 +126,12 @@
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++  return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c	2014-08-29 10:35:02.604070587 -0700
+@@ -38,7 +38,7 @@
+    square root.  */
+ 
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ {
+   if (__builtin_expect (b > 0, 1))
+     {
+@@ -93,4 +93,11 @@
+     }
+   return f_washf (b);
+ }
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrt.c	2014-08-29 10:35:02.604070587 -0700
+@@ -41,10 +41,10 @@
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@
+ 
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -132,4 +132,12 @@
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc64/e6500/fpu/e_sqrtf.c	2014-08-29 10:35:02.604070587 -0700
+@@ -39,10 +39,10 @@
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
+@@ -99,4 +99,12 @@
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrt.c	2014-08-29 10:35:02.608070587 -0700
+@@ -41,10 +41,10 @@
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@
+ 
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -132,4 +132,12 @@
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/e500mc/fpu/e_sqrtf.c	2014-08-29 10:35:02.608070587 -0700
+@@ -39,10 +39,10 @@
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
+@@ -99,4 +99,12 @@
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrt.c	2014-08-29 10:35:02.608070587 -0700
+@@ -41,10 +41,10 @@
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@
+ 
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+@@ -132,4 +132,12 @@
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/e5500/fpu/e_sqrtf.c	2014-08-29 10:35:02.608070587 -0700
+@@ -39,10 +39,10 @@
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
+@@ -99,4 +99,12 @@
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
+Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-08-29 10:35:02.608070587 -0700
+@@ -132,4 +132,12 @@
+     }
+   return f_wash (b);
+ }
++
++#undef __ieee754_sqrt
++double
++__ieee754_sqrt (double x)
++{
++   return __slow_ieee754_sqrt (x);
++}
++
+ strong_alias (__ieee754_sqrt, __sqrt_finite)
+Index: git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+===================================================================
+--- git.orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-08-29 10:35:02.616070587 -0700
++++ git/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-08-29 10:35:02.608070587 -0700
+@@ -99,4 +99,12 @@
+     }
+   return f_washf (b);
+ }
++
++#undef __ieee754_sqrtf
++float
++__ieee754_sqrtf (float x)
++{
++  return __slow_ieee754_sqrtf (x);
++}
++
+ strong_alias (__ieee754_sqrtf, __sqrtf_finite)
diff --git a/recipes-core/glibc/glibc/ppce6500-32b_slow_ieee754_sqrt.patch b/recipes-core/glibc/glibc/ppce6500-32b_slow_ieee754_sqrt.patch
new file mode 100644
index 0000000..4c6c107
--- /dev/null
+++ b/recipes-core/glibc/glibc/ppce6500-32b_slow_ieee754_sqrt.patch
@@ -0,0 +1,47 @@
+ __ieee754_sqrt{,f} are now inline functions and call out __slow versions
+
+
+Signed-off-by: chunrong guo <B40290@freescale.com>
+Upstream-Status: Pending
+
+diff -rNu libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-04-08 04:39:58.487229887 -0500
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrt.c	2014-04-08 04:40:52.643069198 -0500
+@@ -41,10 +41,10 @@
+ 
+ #ifdef __STDC__
+ double
+-__ieee754_sqrt (double b)
++__slow_ieee754_sqrt (double b)
+ #else
+ double
+-__ieee754_sqrt (b)
++__slow_ieee754_sqrt (b)
+      double b;
+ #endif
+ {
+@@ -83,7 +83,7 @@
+ 
+           /* Handle small numbers by scaling.  */
+           if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
+-            return __ieee754_sqrt (b * two108) * twom54;
++            return __slow_ieee754_sqrt (b * two108) * twom54;
+ 
+ #define FMADD(a_, c_, b_)                                               \
+           ({ double __r;                                                \
+diff -rNu libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-04-08 04:39:58.487229887 -0500
++++ libc/sysdeps/powerpc/powerpc32/e6500/fpu/e_sqrtf.c	2014-04-08 04:41:26.017067682 -0500
+@@ -39,10 +39,10 @@
+ 
+ #ifdef __STDC__
+ float
+-__ieee754_sqrtf (float b)
++__slow_ieee754_sqrtf (float b)
+ #else
+ float
+-__ieee754_sqrtf (b)
++__slow_ieee754_sqrtf (b)
+      float b;
+ #endif
+ {
diff --git a/recipes-core/glibc/glibc/relocatable_sdk.patch b/recipes-core/glibc/glibc/relocatable_sdk.patch
new file mode 100644
index 0000000..ca5f17b
--- /dev/null
+++ b/recipes-core/glibc/glibc/relocatable_sdk.patch
@@ -0,0 +1,108 @@
+Upstream-Status: Inappropriate [SDK specific]
+
+This patch puts the dynamic loader path in the binaries, SYSTEM_DIRS strings
+and lengths as well as ld.so.cache path in the dynamic loader to specific
+sections in memory. The sections that contain paths have been allocated a 4096
+byte section, which is the maximum path length in linux. This will allow the
+relocating script to parse the ELF binary, detect the section and easily replace
+the strings in a certain path.
+
+Signed-off-by: Laurentiu Palcu <laurentiu.palcu@intel.com>
+
+Index: libc/elf/interp.c
+===================================================================
+--- libc.orig/elf/interp.c
++++ libc/elf/interp.c
+@@ -16,5 +16,5 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-const char __invoke_dynamic_linker__[] __attribute__ ((section (".interp")))
++const char __invoke_dynamic_linker__[4096] __attribute__ ((section (".interp")))
+   = RUNTIME_LINKER;
+Index: libc/elf/dl-load.c
+===================================================================
+--- libc.orig/elf/dl-load.c
++++ libc/elf/dl-load.c
+@@ -144,8 +144,8 @@ static size_t max_capstrlen attribute_re
+ /* Get the generated information about the trusted directories.  */
+ #include "trusted-dirs.h"
+ 
+-static const char system_dirs[] = SYSTEM_DIRS;
+-static const size_t system_dirs_len[] =
++static const char system_dirs[4096] __attribute__ ((section (".sysdirs"))) = SYSTEM_DIRS;
++volatile static const size_t system_dirs_len[] __attribute__ ((section (".sysdirslen"))) =
+ {
+   SYSTEM_DIRS_LEN
+ };
+Index: libc/elf/dl-cache.c
+===================================================================
+--- libc.orig/elf/dl-cache.c
++++ libc/elf/dl-cache.c
+@@ -133,6 +133,10 @@ do									      \
+ while (0)
+ 
+ 
++const char LD_SO_CACHE[4096] __attribute__ ((section (".ldsocache"))) =
++		SYSCONFDIR "/ld.so.cache";
++
++
+ int
+ internal_function
+ _dl_cache_libcmp (const char *p1, const char *p2)
+Index: libc/elf/ldconfig.c
+===================================================================
+--- libc.orig/elf/ldconfig.c
++++ libc/elf/ldconfig.c
+@@ -166,6 +166,9 @@ static struct argp argp =
+   options, parse_opt, NULL, doc, NULL, more_help, NULL
+ };
+ 
++
++extern const char LD_SO_CACHE[4096] __attribute__ ((section (".ldsocache")));
++
+ /* Check if string corresponds to an important hardware capability or
+    a platform.  */
+ static int
+Index: libc/sysdeps/generic/dl-cache.h
+===================================================================
+--- libc.orig/sysdeps/generic/dl-cache.h
++++ libc/sysdeps/generic/dl-cache.h
+@@ -27,10 +27,6 @@
+   ((flags) == 1 || (flags) == _DL_CACHE_DEFAULT_ID)
+ #endif
+ 
+-#ifndef LD_SO_CACHE
+-# define LD_SO_CACHE SYSCONFDIR "/ld.so.cache"
+-#endif
+-
+ #ifndef add_system_dir
+ # define add_system_dir(dir) add_dir (dir)
+ #endif
+Index: libc/elf/rtld.c
+===================================================================
+--- libc.orig/elf/rtld.c
++++ libc/elf/rtld.c
+@@ -99,6 +99,7 @@ uintptr_t __pointer_chk_guard_local
+ strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
+ #endif
+ 
++extern const char LD_SO_CACHE[4096] __attribute__ ((section (".ldsocache")));
+ 
+ /* List of auditing DSOs.  */
+ static struct audit_list
+@@ -1031,12 +1032,12 @@ of this helper program; chances are you
+   --list                list all dependencies and how they are resolved\n\
+   --verify              verify that given object really is a dynamically linked\n\
+ 			object we can handle\n\
+-  --inhibit-cache       Do not use " LD_SO_CACHE "\n\
++  --inhibit-cache       Do not use %s\n\
+   --library-path PATH   use given PATH instead of content of the environment\n\
+ 			variable LD_LIBRARY_PATH\n\
+   --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names\n\
+ 			in LIST\n\
+-  --audit LIST          use objects named in LIST as auditors\n");
++  --audit LIST          use objects named in LIST as auditors\n", LD_SO_CACHE);
+ 
+       ++_dl_skip_args;
+       --_dl_argc;
diff --git a/recipes-core/glibc/glibc/relocatable_sdk_fix_openpath.patch b/recipes-core/glibc/glibc/relocatable_sdk_fix_openpath.patch
new file mode 100644
index 0000000..f164f8f
--- /dev/null
+++ b/recipes-core/glibc/glibc/relocatable_sdk_fix_openpath.patch
@@ -0,0 +1,41 @@
+Upstream-Status: Inappropriate [SDK specific]
+
+eglibc-nativesdk: Fix buffer overrun with a relocated SDK
+
+When ld-linux-*.so.2 is relocated to a path that is longer than the
+original fixed location, the dynamic loader will crash in open_path
+because it implicitly assumes that max_dirnamelen is a fixed size that
+never changes.
+
+The allocated buffer will not be large enough to contain the directory
+path string which is larger than the fixed location provided at build
+time.
+
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+
+---
+ elf/dl-load.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1919,7 +1919,19 @@ open_path (const char *name, size_t name
+        given on the command line when rtld is run directly.  */
+     return -1;
+ 
++  do
++    {
++      struct r_search_path_elem *this_dir = *dirs;
++      if (this_dir->dirnamelen > max_dirnamelen)
++	{
++	  max_dirnamelen = this_dir->dirnamelen;
++	}
++    }
++  while (*++dirs != NULL);
++
+   buf = alloca (max_dirnamelen + max_capstrlen + namelen);
++
++  dirs = sps->dirs;
+   do
+     {
+       struct r_search_path_elem *this_dir = *dirs;
diff --git a/recipes-core/glibc/glibc/timezone-re-written-tzselect-as-posix-sh.patch b/recipes-core/glibc/glibc/timezone-re-written-tzselect-as-posix-sh.patch
new file mode 100644
index 0000000..55547de
--- /dev/null
+++ b/recipes-core/glibc/glibc/timezone-re-written-tzselect-as-posix-sh.patch
@@ -0,0 +1,38 @@
+timezone: re-written tzselect as posix sh
+
+To avoid the bash dependency.
+
+Upstream-Status: Pending
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ timezone/Makefile     | 2 +-
+ timezone/tzselect.ksh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+Index: git/timezone/Makefile
+===================================================================
+--- git.orig/timezone/Makefile	2014-08-27 05:35:58.008070587 +0000
++++ git/timezone/Makefile	2014-08-27 05:36:37.908070587 +0000
+@@ -114,7 +114,7 @@
+ 
+ 
+ $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make
+-	sed -e 's|/bin/bash|$(BASH)|' \
++	sed -e 's|/bin/bash|/bin/sh|' \
+ 	    -e 's|TZDIR=[^}]*|TZDIR=$(zonedir)|' \
+ 	    -e '/TZVERSION=/s|see_Makefile|"$(version)"|' \
+ 	    -e '/PKGVERSION=/s|=.*|="$(PKGVERSION)"|' \
+Index: git/timezone/tzselect.ksh
+===================================================================
+--- git.orig/timezone/tzselect.ksh	2014-08-27 05:35:58.008070587 +0000
++++ git/timezone/tzselect.ksh	2014-08-27 05:35:58.000070587 +0000
+@@ -35,7 +35,7 @@
+ 
+ # Specify default values for environment variables if they are unset.
+ : ${AWK=awk}
+-: ${TZDIR=`pwd`}
++: ${TZDIR=$(pwd)}
+ 
+ # Check for awk Posix compliance.
+ ($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
diff --git a/recipes-core/glibc/glibc_2.20.bb b/recipes-core/glibc/glibc_2.20.bb
new file mode 100644
index 0000000..e733a49
--- /dev/null
+++ b/recipes-core/glibc/glibc_2.20.bb
@@ -0,0 +1,193 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/glibc-fsl:"
+
+require recipes-core/glibc/glibc.inc
+
+DEPENDS += "gperf-native kconfig-frontends-native"
+
+PV = "2.20"
+
+SRCREV = "b8079dd0d360648e4e8de48656c5c38972621072"
+
+SRC_URI = "git://sourceware.org/git/glibc.git;branch=release/${PV}/master \
+           file://IO-acquire-lock-fix.patch \
+           file://mips-rld-map-check.patch \
+           file://etc/ld.so.conf \
+           file://generate-supported.mk \
+           file://glibc.fix_sqrt2.patch \
+           file://multilib_readlib.patch \
+           file://ppc-sqrt_finite.patch \
+           file://ppc_slow_ieee754_sqrt.patch \
+           file://add_resource_h_to_wait_h.patch \
+           file://fsl-ppc-no-fsqrt.patch \
+           file://0001-R_ARM_TLS_DTPOFF32.patch \
+           file://0001-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch \
+           file://fix-tibetian-locales.patch \
+           file://ppce6500-32b_slow_ieee754_sqrt.patch \
+           file://grok_gold.patch \
+           file://fix_am_rootsbindir.patch \
+           file://intl-Merge-with-gettext-version-0.19.3.patch \
+           file://0016-Remove-bash-dependency-for-nscd-init-script.patch \
+           ${EGLIBCPATCHES} \
+           ${CVEPATCHES} \
+           ${FSLPATCHES} \
+          "
+EGLIBCPATCHES = "\
+           file://timezone-re-written-tzselect-as-posix-sh.patch \
+           file://eglibc.patch \
+           file://option-groups.patch \
+           file://GLRO_dl_debug_mask.patch \
+           file://eglibc-header-bootstrap.patch \
+           file://eglibc-resolv-dynamic.patch \
+           file://eglibc-ppc8xx-cache-line-workaround.patch \
+           file://eglibc-sh4-fpscr_values.patch \
+           file://eglibc-use-option-groups.patch \
+          "
+#           file://eglibc-install-pic-archives.patch \
+#	    file://initgroups_keys.patch \
+#
+
+CVEPATCHES = "\
+        file://CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch \
+        file://CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch \
+        file://CVE-2014-9402_endless-loop-in-getaddr_r.patch \
+        file://CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch \
+    "
+
+FSLPATCHES = "\
+    file://0005.glibc.fix_prof.patch \
+    file://0006.glibc.fsl-crosszic.patch \
+    file://0007.glibc.fix_MTWX51911-enable_8xx.patch \
+    file://0008.glibc.e500v2_lib_support.patch \
+    file://0009.glibc.fsl-mcpy-e500mc-e5500-e6500.patch \
+    file://0010.glibc.fsl-e500mc-e5500-mset.patch \
+    file://0011.glibc.fsl-mset-e6500.patch \
+    file://0012.glibc.fsl-mcmp-e6500.patch \
+    file://0013.glibc.fsl-stcmp-e5500.patch \
+    file://0014.glibc.fsl-strchr-e500mc-e5500.patch \
+    file://0015.glibc.fsl-strcpy-e500mc-e5500.patch \
+    file://0016.glibc.fsl-strlen-e500mc-e5500.patch \
+    file://0017.glibc.fsl-strrchr-e500mc-e5500.patch \
+    file://0018.glibc.testsuite_remove-blocking-test.patch \
+    file://0019.glibc.readv_proto.patch \
+    file://0020.glibc.fsl-largemcpy-e500mc-e5500-e6500.patch \
+    file://0021.glibc.undefined_static.patch \
+    file://0022.glibc.use-option-groups.patch \
+"
+
+LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \
+      file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
+      file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \
+      file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c"
+
+SRC_URI_append_class-nativesdk = " file://ld-search-order.patch \
+            file://relocatable_sdk.patch \
+            file://relocatable_sdk_fix_openpath.patch \
+            "
+S = "${WORKDIR}/git"
+B = "${WORKDIR}/build-${TARGET_SYS}"
+
+PACKAGES_DYNAMIC = ""
+
+# the -isystem in bitbake.conf screws up glibc do_stage
+BUILD_CPPFLAGS = "-I${STAGING_INCDIR_NATIVE}"
+TARGET_CPPFLAGS = "-I${STAGING_DIR_TARGET}${includedir}"
+
+GLIBC_BROKEN_LOCALES = " _ER _ET so_ET yn_ER sid_ET tr_TR mn_MN gez_ET gez_ER bn_BD te_IN es_CR.ISO-8859-1"
+
+#
+# For now, we will skip building of a gcc package if it is a uclibc one
+# and our build is not a uclibc one, and we skip a glibc one if our build
+# is a uclibc build.
+#
+# See the note in gcc/gcc_3.4.0.oe
+#
+
+python __anonymous () {
+    import re
+    uc_os = (re.match('.*uclibc$', d.getVar('TARGET_OS', True)) != None)
+    if uc_os:
+        raise bb.parse.SkipPackage("incompatible with target %s" %
+                                   d.getVar('TARGET_OS', True))
+}
+
+EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
+                --without-cvs --disable-profile \
+                --disable-debug --without-gd \
+                --enable-clocale=gnu \
+                --enable-add-ons \
+                --with-headers=${STAGING_INCDIR} \
+                --without-selinux \
+                --enable-obsolete-rpc \
+                --with-kconfig=${STAGING_BINDIR_NATIVE} \
+                --disable-nscd \
+                ${GLIBC_EXTRA_OECONF}"
+
+EXTRA_OECONF += "${@get_libc_fpu_setting(bb, d)}"
+EXTRA_OECONF += "${@bb.utils.contains('DISTRO_FEATURES', 'libc-inet-anl', '--enable-nscd', '--disable-nscd', d)}"
+EXTRA_OECONF += "--disable-multi-arch"
+
+do_patch_append() {
+    bb.build.exec_func('do_fix_readlib_c', d)
+}
+
+# for mips glibc now builds syscall tables for all abi's
+# so we make sure that we choose right march option which is
+# compatible with o32,n32 and n64 abi's
+# e.g. -march=mips32 is not compatible with n32 and n64 therefore
+# we filter it out in such case -march=from-abi which will be
+# mips1 when using o32 and mips3 when using n32/n64
+
+TUNE_CCARGS_mips := "${@oe_filter_out('-march=mips32', '${TUNE_CCARGS}', d)}"
+TUNE_CCARGS_mipsel := "${@oe_filter_out('-march=mips32', '${TUNE_CCARGS}', d)}"
+
+do_fix_readlib_c () {
+	sed -i -e 's#OECORE_KNOWN_INTERPRETER_NAMES#${EGLIBC_KNOWN_INTERPRETER_NAMES}#' ${S}/elf/readlib.c
+}
+
+do_configure () {
+# override this function to avoid the autoconf/automake/aclocal/autoheader
+# calls for now
+# don't pass CPPFLAGS into configure, since it upsets the kernel-headers
+# version check and doesn't really help with anything
+        if [ -z "`which rpcgen`" ]; then
+                echo "rpcgen not found.  Install glibc-devel."
+                exit 1
+        fi
+        (cd ${S} && gnu-configize) || die "failure in running gnu-configize"
+        find ${S} -name "configure" | xargs touch
+        CPPFLAGS="" oe_runconf
+}
+
+rpcsvc = "bootparam_prot.x nlm_prot.x rstat.x \
+	  yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \
+	  rusers.x spray.x nfs_prot.x rquota.x key_prot.x"
+
+do_compile () {
+	# -Wl,-rpath-link <staging>/lib in LDFLAGS can cause breakage if another glibc is in staging
+	unset LDFLAGS
+	base_do_compile
+	(
+		cd ${S}/sunrpc/rpcsvc
+		for r in ${rpcsvc}; do
+			h=`echo $r|sed -e's,\.x$,.h,'`
+			rpcgen -h $r -o $h || bbwarn "unable to generate header for $r"
+		done
+	)
+	echo "Adjust ldd script"
+	if [ -n "${RTLDLIST}" ]
+	then
+		prevrtld=`cat ${B}/elf/ldd | grep "^RTLDLIST=" | sed 's#^RTLDLIST="\?\([^"]*\)"\?$#\1#'`
+		if [ "${prevrtld}" != "${RTLDLIST}" ]
+		then
+			sed -i ${B}/elf/ldd -e "s#^RTLDLIST=.*\$#RTLDLIST=\"${prevrtld} ${RTLDLIST}\"#"
+		fi
+	fi
+
+}
+
+do_install_append () {
+        rm -rf ${D}/usr/include/gnu/lib-names.h
+}
+require glibc-package.inc
+
+BBCLASSEXTEND = "nativesdk"
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/32and64bit.patch b/recipes-core/glibc/ldconfig-native-2.12.1/32and64bit.patch
new file mode 100644
index 0000000..cdfeaea
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/32and64bit.patch
@@ -0,0 +1,331 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+We run the ldconfig in the cross fashion. make the code bitsize aware so that 
+we can cross build ldconfig cache for various architectures.
+
+Richard Purdie <richard.purdie@linuxfoundation.org> 2009/05/19
+Nitin A Kamble <nitin.a.kamble@intel.com> 2009/03/29
+
+Index: ldconfig-native-2.12.1/readelflib.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/readelflib.c
++++ ldconfig-native-2.12.1/readelflib.c
+@@ -40,39 +40,212 @@ do								\
+ 
+ /* Returns 0 if everything is ok, != 0 in case of error.  */
+ int
+-process_elf_file (const char *file_name, const char *lib, int *flag,
++process_elf_file32 (const char *file_name, const char *lib, int *flag,
+ 		  unsigned int *osversion, char **soname, void *file_contents,
+ 		  size_t file_length)
+ {
+   int i;
+   unsigned int j;
+-  ElfW(Addr) loadaddr;
++  Elf32_Addr loadaddr;
+   unsigned int dynamic_addr;
+   size_t dynamic_size;
+   char *program_interpreter;
+ 
+-  ElfW(Ehdr) *elf_header;
+-  ElfW(Phdr) *elf_pheader, *segment;
+-  ElfW(Dyn) *dynamic_segment, *dyn_entry;
++  Elf32_Ehdr *elf_header;
++  Elf32_Phdr *elf_pheader, *segment;
++  Elf32_Dyn *dynamic_segment, *dyn_entry;
+   char *dynamic_strings;
+ 
+-  elf_header = (ElfW(Ehdr) *) file_contents;
++  elf_header = (Elf32_Ehdr *) file_contents;
+   *osversion = 0;
+ 
+-  if (elf_header->e_ident [EI_CLASS] != ElfW (CLASS))
++  if (elf_header->e_type != ET_DYN)
+     {
+-      if (opt_verbose)
++      error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
++	     elf_header->e_type);
++      return 1;
++    }
++
++  /* Get information from elf program header.  */
++  elf_pheader = (Elf32_Phdr *) (elf_header->e_phoff + file_contents);
++  check_ptr (elf_pheader);
++
++  /* The library is an elf library, now search for soname and
++     libc5/libc6.  */
++  *flag = FLAG_ELF;
++
++  loadaddr = -1;
++  dynamic_addr = 0;
++  dynamic_size = 0;
++  program_interpreter = NULL;
++  for (i = 0, segment = elf_pheader;
++       i < elf_header->e_phnum; i++, segment++)
++    {
++      check_ptr (segment);
++
++      switch (segment->p_type)
+ 	{
+-	  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
+-	    error (0, 0, _("%s is a 32 bit ELF file.\n"), file_name);
+-	  else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
+-	    error (0, 0, _("%s is a 64 bit ELF file.\n"), file_name);
+-	  else
+-	    error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
++	case PT_LOAD:
++	  if (loadaddr == (Elf32_Addr) -1)
++	    loadaddr = segment->p_vaddr - segment->p_offset;
++	  break;
++
++	case PT_DYNAMIC:
++	  if (dynamic_addr)
++	    error (0, 0, _("more than one dynamic segment\n"));
++
++	  dynamic_addr = segment->p_offset;
++	  dynamic_size = segment->p_filesz;
++	  break;
++
++	case PT_INTERP:
++	  program_interpreter = (char *) (file_contents + segment->p_offset);
++	  check_ptr (program_interpreter);
++
++	  /* Check if this is enough to classify the binary.  */
++	  for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]);
++	       ++j)
++	    if (strcmp (program_interpreter, interpreters[j].soname) == 0)
++	      {
++		*flag = interpreters[j].flag;
++		break;
++	      }
++	  break;
++
++	case PT_NOTE:
++	  if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4)
++	    {
++	      Elf32_Word *abi_note = (Elf32_Word *) (file_contents
++						     + segment->p_offset);
++	      Elf32_Addr size = segment->p_filesz;
++
++	      while (abi_note [0] != 4 || abi_note [1] != 16
++		     || abi_note [2] != 1
++		     || memcmp (abi_note + 3, "GNU", 4) != 0)
++		{
++#define ROUND(len) (((len) + sizeof (Elf32_Word)) - 1) & -sizeof (Elf32_Word)))
++		  Elf32_Addr) note_size = 3 * sizeof (Elf32_Word))
++					 + ROUND (abi_note[0])
++					 + ROUND (abi_note[1]);
++
++		  if (size - 32 < note_size || note_size == 0)
++		    {
++		      size = 0;
++		      break;
++		    }
++		  size -= note_size;
++		  abi_note = (void *) abi_note + note_size;
++		}
++
++	      if (size == 0)
++		break;
++
++	      *osversion = (abi_note [4] << 24) |
++			   ((abi_note [5] & 0xff) << 16) |
++			   ((abi_note [6] & 0xff) << 8) |
++			   (abi_note [7] & 0xff);
++	    }
++	  break;
++
++	default:
++	  break;
++	}
++
++    }
++  if (loadaddr == (Elf32_Addr) -1)
++    {
++      /* Very strange. */
++      loadaddr = 0;
++    }
++
++  /* Now we can read the dynamic sections.  */
++  if (dynamic_size == 0)
++    return 1;
++
++  dynamic_segment = (Elf32_Dyn *) (file_contents + dynamic_addr);
++  check_ptr (dynamic_segment);
++
++  /* Find the string table.  */
++  dynamic_strings = NULL;
++  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++       ++dyn_entry)
++    {
++      check_ptr (dyn_entry);
++      if (dyn_entry->d_tag == DT_STRTAB)
++	{
++	  dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
++	  check_ptr (dynamic_strings);
++	  break;
+ 	}
+-      return 1;
+     }
+ 
++  if (dynamic_strings == NULL)
++    return 1;
++
++  /* Now read the DT_NEEDED and DT_SONAME entries.  */
++  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++       ++dyn_entry)
++    {
++      if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
++	{
++	  char *name = dynamic_strings + dyn_entry->d_un.d_val;
++	  check_ptr (name);
++
++	  if (dyn_entry->d_tag == DT_NEEDED)
++	    {
++
++	      if (*flag == FLAG_ELF)
++		{
++		  /* Check if this is enough to classify the binary.  */
++		  for (j = 0;
++		       j < sizeof (known_libs) / sizeof (known_libs [0]);
++		       ++j)
++		    if (strcmp (name, known_libs [j].soname) == 0)
++		      {
++			*flag = known_libs [j].flag;
++			break;
++		      }
++		}
++	    }
++
++	  else if (dyn_entry->d_tag == DT_SONAME)
++	    *soname = xstrdup (name);
++
++	  /* Do we have everything we need?  */
++	  if (*soname && *flag != FLAG_ELF)
++	    return 0;
++	}
++    }
++
++  /* We reach this point only if the file doesn't contain a DT_SONAME
++     or if we can't classify the library.  If it doesn't have a
++     soname, return the name of the library.  */
++  if (*soname == NULL)
++    *soname = xstrdup (lib);
++
++  return 0;
++}
++
++int
++process_elf_file64 (const char *file_name, const char *lib, int *flag,
++		  unsigned int *osversion, char **soname, void *file_contents,
++		  size_t file_length)
++{
++  int i;
++  unsigned int j;
++  Elf64_Addr loadaddr;
++  unsigned int dynamic_addr;
++  size_t dynamic_size;
++  char *program_interpreter;
++
++  Elf64_Ehdr *elf_header;
++  Elf64_Phdr *elf_pheader, *segment;
++  Elf64_Dyn *dynamic_segment, *dyn_entry;
++  char *dynamic_strings;
++
++  elf_header = (Elf64_Ehdr *) file_contents;
++  *osversion = 0;
++
+   if (elf_header->e_type != ET_DYN)
+     {
+       error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
+@@ -81,7 +254,7 @@ process_elf_file (const char *file_name,
+     }
+ 
+   /* Get information from elf program header.  */
+-  elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents);
++  elf_pheader = (Elf64_Phdr *) (elf_header->e_phoff + file_contents);
+   check_ptr (elf_pheader);
+ 
+   /* The library is an elf library, now search for soname and
+@@ -100,7 +273,7 @@ process_elf_file (const char *file_name,
+       switch (segment->p_type)
+ 	{
+ 	case PT_LOAD:
+-	  if (loadaddr == (ElfW(Addr)) -1)
++	  if (loadaddr == (Elf64_Addr) -1)
+ 	    loadaddr = segment->p_vaddr - segment->p_offset;
+ 	  break;
+ 
+@@ -129,16 +302,16 @@ process_elf_file (const char *file_name,
+ 	case PT_NOTE:
+ 	  if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4)
+ 	    {
+-	      ElfW(Word) *abi_note = (ElfW(Word) *) (file_contents
++	      Elf64_Word *abi_note = (Elf64_Word *) (file_contents
+ 						     + segment->p_offset);
+-	      ElfW(Addr) size = segment->p_filesz;
++	      Elf64_Addr size = segment->p_filesz;
+ 
+ 	      while (abi_note [0] != 4 || abi_note [1] != 16
+ 		     || abi_note [2] != 1
+ 		     || memcmp (abi_note + 3, "GNU", 4) != 0)
+ 		{
+-#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+-		  ElfW(Addr) note_size = 3 * sizeof (ElfW(Word))
++#define ROUND(len) (((len) + sizeof (Elf64_Word) - 1) & -sizeof (Elf64_Word))
++		  Elf64_Addr note_size = 3 * sizeof (Elf64_Word)
+ 					 + ROUND (abi_note[0])
+ 					 + ROUND (abi_note[1]);
+ 
+@@ -166,7 +339,7 @@ process_elf_file (const char *file_name,
+ 	}
+ 
+     }
+-  if (loadaddr == (ElfW(Addr)) -1)
++  if (loadaddr == (Elf64_Addr) -1)
+     {
+       /* Very strange. */
+       loadaddr = 0;
+@@ -176,7 +349,7 @@ process_elf_file (const char *file_name,
+   if (dynamic_size == 0)
+     return 1;
+ 
+-  dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr);
++  dynamic_segment = (Elf64_Dyn *) (file_contents + dynamic_addr);
+   check_ptr (dynamic_segment);
+ 
+   /* Find the string table.  */
+@@ -233,3 +406,33 @@ process_elf_file (const char *file_name,
+ 
+   return 0;
+ }
++/* Returns 0 if everything is ok, != 0 in case of error.  */
++int
++process_elf_file (const char *file_name, const char *lib, int *flag,
++		  unsigned int *osversion, char **soname, void *file_contents,
++		  size_t file_length)
++{
++  int i;
++  unsigned int j;
++  ElfW(Addr) loadaddr;
++  unsigned int dynamic_addr;
++  size_t dynamic_size;
++  char *program_interpreter;
++
++  ElfW(Ehdr) *elf_header;
++  ElfW(Phdr) *elf_pheader, *segment;
++  ElfW(Dyn) *dynamic_segment, *dyn_entry;
++  char *dynamic_strings;
++
++  elf_header = (ElfW(Ehdr) *) file_contents;
++  *osversion = 0;
++
++  if (elf_header->e_ident [EI_CLASS] == ELFCLASS32)
++    return process_elf_file32(file_name, lib,flag, osversion, soname, file_contents, file_length);
++  else if (elf_header->e_ident [EI_CLASS] == ELFCLASS64)
++    return process_elf_file64(file_name, lib,flag, osversion, soname, file_contents, file_length);
++  error (0, 0, _("Unknown ELFCLASS in file %s.\n"), file_name);
++  return 1;
++}
++
++
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/README b/recipes-core/glibc/ldconfig-native-2.12.1/README
new file mode 100644
index 0000000..43fb983
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/README
@@ -0,0 +1,8 @@
+The files are pulled verbatim from glibc 2.5 and then patched to allow
+standalone compilation of ldconfig.
+
+Richard Purdie
+OpenedHand Ltd.
+
+Upgraded the ldconfig recipe to eglibc 2.12.1
+Nitin A Kamble <nitin.a.kamble@intel.com> 2011/03/29
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling.patch b/recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling.patch
new file mode 100644
index 0000000..7f8e4db
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling.patch
@@ -0,0 +1,454 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+Do data input/output handling according to endien-ness of the library file. That 
+enables use of ldconfig in the cross fashion for any architecture.
+
+2011/04/04
+Richard Purdie <richard.purdie@linuxfoundation.org>
+Nitin Kamble <nitin.a.kamble@intel.com>
+
+Index: ldconfig-native-2.12.1/readelflib.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/readelflib.c
++++ ldconfig-native-2.12.1/readelflib.c
+@@ -38,6 +38,28 @@ do								\
+   }								\
+  while (0);
+ 
++int be;
++static uint16_t read16(uint16_t x, int be)
++{
++  if (be)
++        return be16toh(x);
++  return le16toh(x);
++}
++
++static uint32_t read32(uint32_t x, int be)
++{
++  if (be)
++        return be32toh(x);
++  return le32toh(x);
++}
++
++static uint64_t read64(uint64_t x, int be)
++{
++  if (be)
++        return be64toh(x);
++  return le64toh(x);
++}
++
+ /* Returns 0 if everything is ok, != 0 in case of error.  */
+ int
+ process_elf_file32 (const char *file_name, const char *lib, int *flag,
+@@ -59,15 +81,17 @@ process_elf_file32 (const char *file_nam
+   elf_header = (Elf32_Ehdr *) file_contents;
+   *osversion = 0;
+ 
+-  if (elf_header->e_type != ET_DYN)
++  be = (elf_header->e_ident[EI_DATA] == ELFDATA2MSB);
++
++  if (read16(elf_header->e_type, be) != ET_DYN)
+     {
+       error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
+-	     elf_header->e_type);
++	     read16(elf_header->e_type, be));
+       return 1;
+     }
+ 
+   /* Get information from elf program header.  */
+-  elf_pheader = (Elf32_Phdr *) (elf_header->e_phoff + file_contents);
++  elf_pheader = (Elf32_Phdr *) (read32(elf_header->e_phoff, be) + file_contents);
+   check_ptr (elf_pheader);
+ 
+   /* The library is an elf library, now search for soname and
+@@ -79,27 +103,27 @@ process_elf_file32 (const char *file_nam
+   dynamic_size = 0;
+   program_interpreter = NULL;
+   for (i = 0, segment = elf_pheader;
+-       i < elf_header->e_phnum; i++, segment++)
++       i < read16(elf_header->e_phnum, be); i++, segment++)
+     {
+       check_ptr (segment);
+ 
+-      switch (segment->p_type)
++      switch (read32(segment->p_type, be))
+ 	{
+ 	case PT_LOAD:
+ 	  if (loadaddr == (Elf32_Addr) -1)
+-	    loadaddr = segment->p_vaddr - segment->p_offset;
++	    loadaddr = read32(segment->p_vaddr, be) - read32(segment->p_offset, be);
+ 	  break;
+ 
+ 	case PT_DYNAMIC:
+ 	  if (dynamic_addr)
+ 	    error (0, 0, _("more than one dynamic segment\n"));
+ 
+-	  dynamic_addr = segment->p_offset;
+-	  dynamic_size = segment->p_filesz;
++	  dynamic_addr = read32(segment->p_offset, be);
++	  dynamic_size = read32(segment->p_filesz, be);
+ 	  break;
+ 
+ 	case PT_INTERP:
+-	  program_interpreter = (char *) (file_contents + segment->p_offset);
++	  program_interpreter = (char *) (file_contents + read32(segment->p_offset, be));
+ 	  check_ptr (program_interpreter);
+ 
+ 	  /* Check if this is enough to classify the binary.  */
+@@ -113,20 +137,20 @@ process_elf_file32 (const char *file_nam
+ 	  break;
+ 
+ 	case PT_NOTE:
+-	  if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4)
++	  if (!*osversion && read32(segment->p_filesz, be) >= 32 && segment->p_align >= 4)
+ 	    {
+ 	      Elf32_Word *abi_note = (Elf32_Word *) (file_contents
+-						     + segment->p_offset);
+-	      Elf32_Addr size = segment->p_filesz;
++						     + read32(segment->p_offset, be));
++	      Elf32_Addr size = read32(segment->p_filesz, be);
+ 
+-	      while (abi_note [0] != 4 || abi_note [1] != 16
+-		     || abi_note [2] != 1
++	      while (read32(abi_note [0], be) != 4 || read32(abi_note [1], be) != 16
++		     || read32(abi_note [2], be) != 1
+ 		     || memcmp (abi_note + 3, "GNU", 4) != 0)
+ 		{
+-#define ROUND(len) (((len) + sizeof (Elf32_Word)) - 1) & -sizeof (Elf32_Word)))
+-		  Elf32_Addr) note_size = 3 * sizeof (Elf32_Word))
+-					 + ROUND (abi_note[0])
+-					 + ROUND (abi_note[1]);
++#define ROUND(len) (((len) + sizeof (Elf32_Word) - 1) & -sizeof (Elf32_Word))
++		  Elf32_Addr note_size = 3 * sizeof (Elf32_Word)
++					 + ROUND (read32(abi_note[0], be))
++					 + ROUND (read32(abi_note[1], be));
+ 
+ 		  if (size - 32 < note_size || note_size == 0)
+ 		    {
+@@ -140,10 +164,10 @@ process_elf_file32 (const char *file_nam
+ 	      if (size == 0)
+ 		break;
+ 
+-	      *osversion = (abi_note [4] << 24) |
+-			   ((abi_note [5] & 0xff) << 16) |
+-			   ((abi_note [6] & 0xff) << 8) |
+-			   (abi_note [7] & 0xff);
++	      *osversion = (read32(abi_note [4], be) << 24) |
++			   ((read32(abi_note [5], be) & 0xff) << 16) |
++			   ((read32(abi_note [6], be) & 0xff) << 8) |
++			   (read32(abi_note [7], be) & 0xff);
+ 	    }
+ 	  break;
+ 
+@@ -167,13 +191,13 @@ process_elf_file32 (const char *file_nam
+ 
+   /* Find the string table.  */
+   dynamic_strings = NULL;
+-  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++  for (dyn_entry = dynamic_segment; read32(dyn_entry->d_tag, be) != DT_NULL;
+        ++dyn_entry)
+     {
+       check_ptr (dyn_entry);
+-      if (dyn_entry->d_tag == DT_STRTAB)
++      if (read32(dyn_entry->d_tag, be) == DT_STRTAB)
+ 	{
+-	  dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
++	  dynamic_strings = (char *) (file_contents + read32(dyn_entry->d_un.d_val, be) - loadaddr);
+ 	  check_ptr (dynamic_strings);
+ 	  break;
+ 	}
+@@ -183,15 +207,15 @@ process_elf_file32 (const char *file_nam
+     return 1;
+ 
+   /* Now read the DT_NEEDED and DT_SONAME entries.  */
+-  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++  for (dyn_entry = dynamic_segment; read32(dyn_entry->d_tag, be) != DT_NULL;
+        ++dyn_entry)
+     {
+-      if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
++      if (read32(dyn_entry->d_tag, be) == DT_NEEDED || read32(dyn_entry->d_tag, be) == DT_SONAME)
+ 	{
+-	  char *name = dynamic_strings + dyn_entry->d_un.d_val;
++	  char *name = dynamic_strings + read32(dyn_entry->d_un.d_val, be);
+ 	  check_ptr (name);
+ 
+-	  if (dyn_entry->d_tag == DT_NEEDED)
++	  if (read32(dyn_entry->d_tag, be) == DT_NEEDED)
+ 	    {
+ 
+ 	      if (*flag == FLAG_ELF)
+@@ -208,7 +232,7 @@ process_elf_file32 (const char *file_nam
+ 		}
+ 	    }
+ 
+-	  else if (dyn_entry->d_tag == DT_SONAME)
++	  else if (read32(dyn_entry->d_tag, be) == DT_SONAME)
+ 	    *soname = xstrdup (name);
+ 
+ 	  /* Do we have everything we need?  */
+@@ -246,15 +270,17 @@ process_elf_file64 (const char *file_nam
+   elf_header = (Elf64_Ehdr *) file_contents;
+   *osversion = 0;
+ 
+-  if (elf_header->e_type != ET_DYN)
++  be = (elf_header->e_ident[EI_DATA] == ELFDATA2MSB);
++
++  if (read16(elf_header->e_type, be) != ET_DYN)
+     {
+       error (0, 0, _("%s is not a shared object file (Type: %d).\n"), file_name,
+-	     elf_header->e_type);
++	     read16(elf_header->e_type, be));
+       return 1;
+     }
+ 
+   /* Get information from elf program header.  */
+-  elf_pheader = (Elf64_Phdr *) (elf_header->e_phoff + file_contents);
++  elf_pheader = (Elf64_Phdr *) (read64(elf_header->e_phoff, be) + file_contents);
+   check_ptr (elf_pheader);
+ 
+   /* The library is an elf library, now search for soname and
+@@ -266,27 +292,27 @@ process_elf_file64 (const char *file_nam
+   dynamic_size = 0;
+   program_interpreter = NULL;
+   for (i = 0, segment = elf_pheader;
+-       i < elf_header->e_phnum; i++, segment++)
++       i < read16(elf_header->e_phnum, be); i++, segment++)
+     {
+       check_ptr (segment);
+ 
+-      switch (segment->p_type)
++      switch (read32(segment->p_type, be))
+ 	{
+ 	case PT_LOAD:
+ 	  if (loadaddr == (Elf64_Addr) -1)
+-	    loadaddr = segment->p_vaddr - segment->p_offset;
++	    loadaddr = read64(segment->p_vaddr, be) - read64(segment->p_offset, be);
+ 	  break;
+ 
+ 	case PT_DYNAMIC:
+ 	  if (dynamic_addr)
+ 	    error (0, 0, _("more than one dynamic segment\n"));
+ 
+-	  dynamic_addr = segment->p_offset;
+-	  dynamic_size = segment->p_filesz;
++	  dynamic_addr = read64(segment->p_offset, be);
++	  dynamic_size = read32(segment->p_filesz, be);
+ 	  break;
+ 
+ 	case PT_INTERP:
+-	  program_interpreter = (char *) (file_contents + segment->p_offset);
++	  program_interpreter = (char *) (file_contents + read64(segment->p_offset, be));
+ 	  check_ptr (program_interpreter);
+ 
+ 	  /* Check if this is enough to classify the binary.  */
+@@ -300,20 +326,21 @@ process_elf_file64 (const char *file_nam
+ 	  break;
+ 
+ 	case PT_NOTE:
+-	  if (!*osversion && segment->p_filesz >= 32 && segment->p_align >= 4)
++	  if (!*osversion && read32(segment->p_filesz, be) >= 32 && read32(segment->p_align, be) >= 4)
+ 	    {
+ 	      Elf64_Word *abi_note = (Elf64_Word *) (file_contents
+-						     + segment->p_offset);
+-	      Elf64_Addr size = segment->p_filesz;
++						     + read64(segment->p_offset, be));
++	      Elf64_Addr size = read32(segment->p_filesz, be);
+ 
+-	      while (abi_note [0] != 4 || abi_note [1] != 16
+-		     || abi_note [2] != 1
++	      while (read32(abi_note [0], be) != 4 || read32(abi_note [1], be) != 16
++		     || read32(abi_note [2], be) != 1
+ 		     || memcmp (abi_note + 3, "GNU", 4) != 0)
+ 		{
++#undef ROUND
+ #define ROUND(len) (((len) + sizeof (Elf64_Word) - 1) & -sizeof (Elf64_Word))
+ 		  Elf64_Addr note_size = 3 * sizeof (Elf64_Word)
+-					 + ROUND (abi_note[0])
+-					 + ROUND (abi_note[1]);
++					 + ROUND (read32(abi_note[0], be))
++					 + ROUND (read32(abi_note[1], be));
+ 
+ 		  if (size - 32 < note_size || note_size == 0)
+ 		    {
+@@ -327,10 +354,10 @@ process_elf_file64 (const char *file_nam
+ 	      if (size == 0)
+ 		break;
+ 
+-	      *osversion = (abi_note [4] << 24) |
+-			   ((abi_note [5] & 0xff) << 16) |
+-			   ((abi_note [6] & 0xff) << 8) |
+-			   (abi_note [7] & 0xff);
++	      *osversion = (read32(abi_note [4], be) << 24) |
++			   ((read32(abi_note [5], be) & 0xff) << 16) |
++			   ((read32(abi_note [6], be) & 0xff) << 8) |
++			   (read32(abi_note [7], be) & 0xff);
+ 	    }
+ 	  break;
+ 
+@@ -354,13 +381,13 @@ process_elf_file64 (const char *file_nam
+ 
+   /* Find the string table.  */
+   dynamic_strings = NULL;
+-  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++  for (dyn_entry = dynamic_segment; read64(dyn_entry->d_tag, be) != DT_NULL;
+        ++dyn_entry)
+     {
+       check_ptr (dyn_entry);
+-      if (dyn_entry->d_tag == DT_STRTAB)
++      if (read64(dyn_entry->d_tag, be) == DT_STRTAB)
+ 	{
+-	  dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
++	  dynamic_strings = (char *) (file_contents + read64(dyn_entry->d_un.d_val, be) - loadaddr);
+ 	  check_ptr (dynamic_strings);
+ 	  break;
+ 	}
+@@ -370,15 +397,15 @@ process_elf_file64 (const char *file_nam
+     return 1;
+ 
+   /* Now read the DT_NEEDED and DT_SONAME entries.  */
+-  for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
++  for (dyn_entry = dynamic_segment; read64(dyn_entry->d_tag, be) != DT_NULL;
+        ++dyn_entry)
+     {
+-      if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
++      if (read64(dyn_entry->d_tag, be) == DT_NEEDED || read64(dyn_entry->d_tag, be) == DT_SONAME)
+ 	{
+-	  char *name = dynamic_strings + dyn_entry->d_un.d_val;
++	  char *name = dynamic_strings + read64(dyn_entry->d_un.d_val, be);
+ 	  check_ptr (name);
+ 
+-	  if (dyn_entry->d_tag == DT_NEEDED)
++	  if (read64(dyn_entry->d_tag, be) == DT_NEEDED)
+ 	    {
+ 
+ 	      if (*flag == FLAG_ELF)
+@@ -395,7 +422,7 @@ process_elf_file64 (const char *file_nam
+ 		}
+ 	    }
+ 
+-	  else if (dyn_entry->d_tag == DT_SONAME)
++	  else if (read64(dyn_entry->d_tag, be) == DT_SONAME)
+ 	    *soname = xstrdup (name);
+ 
+ 	  /* Do we have everything we need?  */
+Index: ldconfig-native-2.12.1/readlib.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/readlib.c
++++ ldconfig-native-2.12.1/readlib.c
+@@ -169,7 +169,8 @@ process_file (const char *real_file_name
+       ret = 1;
+     }
+   /* Libraries have to be shared object files.  */
+-  else if (elf_header->e_type != ET_DYN)
++  else if ((elf_header->e_ident[EI_DATA] == ELFDATA2MSB && be16toh(elf_header->e_type) != ET_DYN) ||
++      (elf_header->e_ident[EI_DATA] == ELFDATA2LSB && le16toh(elf_header->e_type) != ET_DYN))
+     ret = 1;
+   else if (process_elf_file (file_name, lib, flag, osversion, soname,
+ 			     file_contents, statbuf.st_size))
+Index: ldconfig-native-2.12.1/cache.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/cache.c
++++ ldconfig-native-2.12.1/cache.c
+@@ -39,6 +39,29 @@
+ # define N_(msgid)  msgid
+ #define _(msg) msg
+ 
++extern int be;
++
++static uint16_t write16(uint16_t x, int be)
++{
++  if (be)
++        return htobe16(x);
++  return htole16(x);
++}
++
++static uint32_t write32(uint32_t x, int be)
++{
++  if (be)
++        return htobe32(x);
++  return htole32(x);
++}
++
++static uint64_t write64(uint64_t x, int be)
++{
++  if (be)
++        return htobe64(x);
++  return htole64(x);
++}
++
+ struct cache_entry
+ {
+   char *lib;			/* Library name.  */
+@@ -279,7 +302,12 @@ save_cache (const char *cache_name)
+   /* Number of normal cache entries.  */
+   int cache_entry_old_count = 0;
+ 
+-  for (entry = entries; entry != NULL; entry = entry->next)
++    if (be)
++      printf("saving cache in big endian encoding\n");
++    else
++      printf("saving cache in little endian encoding\n");
++
++    for (entry = entries; entry != NULL; entry = entry->next)
+     {
+       /* Account the final NULs.  */
+       total_strlen += strlen (entry->lib) + strlen (entry->path) + 2;
+@@ -310,7 +338,7 @@ save_cache (const char *cache_name)
+       memset (file_entries, '\0', sizeof (struct cache_file));
+       memcpy (file_entries->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1);
+ 
+-      file_entries->nlibs = cache_entry_old_count;
++      file_entries->nlibs = write32(cache_entry_old_count, be);
+     }
+ 
+   struct cache_file_new *file_entries_new = NULL;
+@@ -330,8 +358,8 @@ save_cache (const char *cache_name)
+       memcpy (file_entries_new->version, CACHE_VERSION,
+ 	      sizeof CACHE_VERSION - 1);
+ 
+-      file_entries_new->nlibs = cache_entry_count;
+-      file_entries_new->len_strings = total_strlen;
++      file_entries_new->nlibs = write32(cache_entry_count, be);
++      file_entries_new->len_strings = write32(total_strlen, be);
+     }
+ 
+   /* Pad for alignment of cache_file_new.  */
+@@ -358,9 +386,9 @@ save_cache (const char *cache_name)
+       /* First the library.  */
+       if (opt_format != 2 && entry->hwcap == 0)
+ 	{
+-	  file_entries->libs[idx_old].flags = entry->flags;
++	  file_entries->libs[idx_old].flags = write32(entry->flags, be);
+ 	  /* XXX: Actually we can optimize here and remove duplicates.  */
+-	  file_entries->libs[idx_old].key = str_offset + pad;
++	  file_entries->libs[idx_old].key = write32(str_offset + pad, be);
+ 	}
+       if (opt_format != 0)
+ 	{
+@@ -368,10 +396,10 @@ save_cache (const char *cache_name)
+ 	     not doing so makes the code easier, the string table
+ 	     always begins at the beginning of the the new cache
+ 	     struct.  */
+-	  file_entries_new->libs[idx_new].flags = entry->flags;
+-	  file_entries_new->libs[idx_new].osversion = entry->osversion;
+-	  file_entries_new->libs[idx_new].hwcap = entry->hwcap;
+-	  file_entries_new->libs[idx_new].key = str_offset;
++	  file_entries_new->libs[idx_new].flags = write32(entry->flags, be);
++	  file_entries_new->libs[idx_new].osversion = write32(entry->osversion, be);
++	  file_entries_new->libs[idx_new].hwcap = write64(entry->hwcap, be);
++	  file_entries_new->libs[idx_new].key = write32(str_offset, be);
+ 	}
+ 
+       size_t len = strlen (entry->lib) + 1;
+@@ -379,9 +407,9 @@ save_cache (const char *cache_name)
+       str_offset += len;
+       /* Then the path.  */
+       if (opt_format != 2 && entry->hwcap == 0)
+-	file_entries->libs[idx_old].value = str_offset + pad;
++	file_entries->libs[idx_old].value = write32(str_offset + pad, be);
+       if (opt_format != 0)
+-	file_entries_new->libs[idx_new].value = str_offset;
++	file_entries_new->libs[idx_new].value = write32(str_offset, be);
+       len = strlen (entry->path) + 1;
+       str = mempcpy (str, entry->path, len);
+       str_offset += len;
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling_fix.patch b/recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling_fix.patch
new file mode 100644
index 0000000..6aecfe5
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/endian-ness_handling_fix.patch
@@ -0,0 +1,47 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+Fix problem during parsing of ELF headers for 64bit on big-endian.
+Some header fields were read with wrong size.
+
+2014/10/24
+Par Olsson <Par.Olsson@windriver.com>
+Shan Hai <shan.hai@windriver.com>
+
+diff --git a/readelflib.c b/readelflib.c
+index 3f5b25b..0bf0de3 100644
+--- a/readelflib.c
++++ b/readelflib.c
+@@ -261,8 +261,8 @@ process_elf_file64 (const char *file_name, const char *lib, int *flag,
+   int i;
+   unsigned int j;
+   Elf64_Addr loadaddr;
+-  unsigned int dynamic_addr;
+-  size_t dynamic_size;
++  Elf64_Addr dynamic_addr;
++  Elf64_Xword dynamic_size;
+   char *program_interpreter;
+ 
+   Elf64_Ehdr *elf_header;
+@@ -311,7 +311,7 @@ process_elf_file64 (const char *file_name, const char *lib, int *flag,
+ 	    error (0, 0, _("more than one dynamic segment\n"));
+ 
+ 	  dynamic_addr = read64(segment->p_offset, be);
+-	  dynamic_size = read32(segment->p_filesz, be);
++	  dynamic_size = read64(segment->p_filesz, be);
+ 	  break;
+ 
+ 	case PT_INTERP:
+@@ -329,11 +329,11 @@ process_elf_file64 (const char *file_name, const char *lib, int *flag,
+ 	  break;
+ 
+ 	case PT_NOTE:
+-	  if (!*osversion && read32(segment->p_filesz, be) >= 32 && read32(segment->p_align, be) >= 4)
++	  if (!*osversion && read64(segment->p_filesz, be) >= 32 && read64(segment->p_align, be) >= 4)
+ 	    {
+ 	      Elf64_Word *abi_note = (Elf64_Word *) (file_contents
+ 						     + read64(segment->p_offset, be));
+-	      Elf64_Addr size = read32(segment->p_filesz, be);
++	      Elf64_Xword size = read64(segment->p_filesz, be);
+ 
+ 	      while (read32(abi_note [0], be) != 4 || read32(abi_note [1], be) != 16
+ 		     || read32(abi_note [2], be) != 1
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/endianess-header.patch b/recipes-core/glibc/ldconfig-native-2.12.1/endianess-header.patch
new file mode 100644
index 0000000..a18b2c2
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/endianess-header.patch
@@ -0,0 +1,113 @@
+Upstream-Status: Inappropriate [fix poky patch]
+
+This patch fixes build issues with a previous endian-ness_handling.patch on
+distros that don't have macros referenced
+
+7/20/2011
+Matthew McClintock <msm@freescale.com>
+
+diff -purN ldconfig-native-2.12.1.orig/endian_extra.h ldconfig-native-2.12.1/endian_extra.h
+--- ldconfig-native-2.12.1.orig/endian_extra.h	1969-12-31 18:00:00.000000000 -0600
++++ ldconfig-native-2.12.1/endian_extra.h	2011-07-19 18:09:14.323048417 -0500
+@@ -0,0 +1,64 @@
++/* Copyright (C) 1992, 1996, 1997, 2000, 2008 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 <endian.h>
++
++#ifndef	_ENDIAN_EXTRA_H
++#define	_ENDIAN_EXTRA_H	1
++
++/* Don't redefine these macros if they already exist */
++#ifndef htobe16
++#ifdef __USE_BSD
++/* Conversion interfaces.  */
++# include <byteswap.h>
++
++# if __BYTE_ORDER == __LITTLE_ENDIAN
++#  define htobe16(x) __bswap_16 (x)
++#  define htole16(x) (x)
++#  define be16toh(x) __bswap_16 (x)
++#  define le16toh(x) (x)
++
++#  define htobe32(x) __bswap_32 (x)
++#  define htole32(x) (x)
++#  define be32toh(x) __bswap_32 (x)
++#  define le32toh(x) (x)
++
++#  define htobe64(x) __bswap_64 (x)
++#  define htole64(x) (x)
++#  define be64toh(x) __bswap_64 (x)
++#  define le64toh(x) (x)
++# else
++#  define htobe16(x) (x)
++#  define htole16(x) __bswap_16 (x)
++#  define be16toh(x) (x)
++#  define le16toh(x) __bswap_16 (x)
++
++#  define htobe32(x) (x)
++#  define htole32(x) __bswap_32 (x)
++#  define be32toh(x) (x)
++#  define le32toh(x) __bswap_32 (x)
++
++#  define htobe64(x) (x)
++#  define htole64(x) __bswap_64 (x)
++#  define be64toh(x) (x)
++#  define le64toh(x) __bswap_64 (x)
++# endif
++#endif
++#endif
++
++#endif	/* endian_extra.h */
+diff -purN ldconfig-native-2.12.1.orig/cache.c ldconfig-native-2.12.1/cache.c
+--- ldconfig-native-2.12.1.orig/cache.c	2011-07-19 18:21:28.347041301 -0500
++++ ldconfig-native-2.12.1/cache.c	2011-07-19 18:22:54.118048064 -0500
+@@ -39,6 +39,8 @@
+ # define N_(msgid)  msgid
+ #define _(msg) msg
+ 
++#include "endian_extra.h"
++
+ extern int be;
+ 
+ static uint16_t write16(uint16_t x, int be)
+diff -purN ldconfig-native-2.12.1.orig/readelflib.c ldconfig-native-2.12.1/readelflib.c
+--- ldconfig-native-2.12.1.orig/readelflib.c	2011-07-19 18:21:28.346041593 -0500
++++ ldconfig-native-2.12.1/readelflib.c	2011-07-19 18:23:05.324059875 -0500
+@@ -25,6 +25,9 @@
+ 
+ /* check_ptr checks that a pointer is in the mmaped file and doesn't
+    point outside it.  */
++
++#include "endian_extra.h"
++
+ #undef check_ptr
+ #define check_ptr(ptr)						\
+ do								\
+diff -purN ldconfig-native-2.12.1.orig/readlib.c ldconfig-native-2.12.1/readlib.c
+--- ldconfig-native-2.12.1.orig/readlib.c	2011-07-19 18:21:28.346041593 -0500
++++ ldconfig-native-2.12.1/readlib.c	2011-07-19 18:23:23.877046210 -0500
+@@ -40,6 +40,8 @@
+ 
+ #include "ldconfig.h"
+ 
++#include "endian_extra.h"
++
+ #define _(msg) msg
+ 
+ #define Elf32_CLASS ELFCLASS32
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/flag_fix.patch b/recipes-core/glibc/ldconfig-native-2.12.1/flag_fix.patch
new file mode 100644
index 0000000..4e9aab9
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/flag_fix.patch
@@ -0,0 +1,24 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+The native version of ldconfig was using native definition of LD_SO (i.e. 
+ld-linux-x86-64.so.2 ) which is not correct for doing the cross ldconfig.
+This was causing libc.so on the target marked as ELF lib rather than 
+FLAG_ELF_LIBC6 in the ld.so.cache.
+
+Nitin A Kamble <nitin.a.kamble@intel.com> 2011/04/4
+
+Index: ldconfig-native-2.12.1/readlib.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/readlib.c
++++ ldconfig-native-2.12.1/readlib.c
+@@ -51,6 +51,10 @@ struct known_names
+   int flag;
+ };
+ 
++/* don't use host's definition of LD_SO */
++#undef LD_SO 
++#define LD_SO "ld.so.1"
++
+ static struct known_names interpreters[] =
+ {
+   { "/lib/" LD_SO, FLAG_ELF_LIBC6 },
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig-default-to-all-multilib-dirs.patch b/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig-default-to-all-multilib-dirs.patch
new file mode 100644
index 0000000..5ed4f6f
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig-default-to-all-multilib-dirs.patch
@@ -0,0 +1,37 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+make ldconfig default to both /lib+/usr/lib, /lib32+/usr/lib32 and
+/lib64+/usr/lib64 on bi-ABI architectures.
+
+---
+ ldconfig.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff -urpN a/ldconfig.c b/ldconfig.c
+--- a/ldconfig.c
++++ b/ldconfig.c
+@@ -52,7 +52,11 @@
+ 
+ #define SYSCONFDIR "/etc"
+ #define LIBDIR "/usr/lib"
++#define LIBDIR32 "/usr/lib32"
++#define LIBDIR64 "/usr/lib64"
+ #define SLIBDIR "/lib"
++#define SLIBDIR32 "/lib32"
++#define SLIBDIR64 "/lib64"
+ # define N_(msgid)  msgid
+ #define _(msg) msg
+ 
+@@ -1373,6 +1377,12 @@ main (int argc, char **argv)
+       add_system_dir (SLIBDIR);
+       if (strcmp (SLIBDIR, LIBDIR))
+ 	add_system_dir (LIBDIR);
++      add_system_dir (SLIBDIR32);
++      if (strcmp (SLIBDIR32, LIBDIR32))
++	add_system_dir (LIBDIR32);
++      add_system_dir (SLIBDIR64);
++      if (strcmp (SLIBDIR64, LIBDIR64))
++	add_system_dir (LIBDIR64);
+     }
+ 
+   const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig-native-2.12.1.tar.bz2 b/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig-native-2.12.1.tar.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..dc1e79888e9bf28226cf18513ebd4478ec90175f
GIT binary patch
literal 21491
zcmV()K;OSYT4*^jL0KkKSzNplS^$e*|NsB+0D*h||NsC0|NsC0|Nj6$0t5gA00962
z004jx00>}o9{1DbKmvVzDYv|Oo@Idd)&QPl`WXNy6zLn^T+aJFJ@xJHcJ(j5^}OEz
z8{PFaqTAjmX}$Aq(Durg+s;0^QlCt=)lQn~!262meCXQ+o>U5bXs3@iDt%-d-(Pv~
zKH2X0ci!{X_ulRAWG!S;gi;&5LVd*9)33dyT}f1d6e)Im&wI)?we`!~-S01U_15Z|
z*{;rZvtFJO<IZVZ4c)eOS6$CXU<cEy*{_G*<Z!PZ`+DuCmt&VKYwl$^t%^(A9p2sQ
znR&kZ$9o@l7V6h^w_Wb<eYZY#+?lQ@pmomK%b`x(aXRa=mpGlTuDyZjSAE*=c5r+t
z+P$8uJ9};1_Vvv1L(|i)*KGH9Ofy?Hw$c|px4gtL5GH^?35W>Mq|u6cnUOOpeu*}d
z%}Rc$>66lfAZYb81_3FcLI_O+CL(PDqx4hsru9eYBzlMHPt_h!+DE7W7>0lV2{ef!
zOp_A|dNN6<{HgeYPe^)Al)(eh1JnVdKzdCEngO6fk`W1lWK+{dO-G=ZihB`H$xVpV
z@uVivsp&L&BSwG#03t|&WHca5fJw4wCQ^RXdYWpU(KSC&<caD(RKjgfYMKCghol;L
zK@uV+flLEYrh!jNc~g3A6pvB)4JIk&1NA0=c}J)K004dH>->MK`=bcS=f9vIRwbb_
zMw%EY4A4NyLEaa=4n8~J4}kb<IOEWz2Tc4x^OSdMEZZ0J-wWZ4Rp$k1S@G3S;%^uX
z;zp6HBtghfOqE9z92Xr(4g(*^LMfz#Q&7+dtPBPs5V948BLHepAP1lEdXK2cew$63
z{8w_9Lc+hk)PIovTypfsCWHEahni-cz|_{XU>h8cS=XOF=sO>h&LBG`l_~{6D8=YY
zw`3F)Mhrn>kx?n3n4%gt%)f1$F__tidOwTN=>1z9blk{-B7%m5C<rK;D5Yr_sflI;
zf)R#^h=!^_kL>?uCx-YKe{MRC?Q+ooOj3mcQj}E%4HVHuRWU^oOw?5rG$}<T1rWp%
z4J}bZQZ$WFOq2xzP}4v$G!RuuQwE&I3MeFqsu-zou!M;q>x_#mT$apEim!g^`#(<y
z67s{Q)iOYnEmbiz(^S<{RRq*PL@Pl70+A39Ddzs!`aJ)h=ds7DqW%moJ%)b-CJ2Tn
z^3R)0HTbYT?w&k7{L}mCQPQP#&P@a3_FvPb6T(xj&Y3N2chvLll<S1M3cJHpF6wd@
zgmicgZXE?_0O&@XadyaWbXngg1WdK9y|7cHDixZ6K?2AWfq@c06oq?sc248&W{2*}
zp6yxcpw+2*y@mO2DY=7`Lw~*2atx`q=0?HxIP0ZzGT^;)n5McWT*&)Qc{JZ2`rg5#
z!3Cn=ZgHRDy7cSe{Q2LUZf8g=${~W%&ldfN4Pg&!!?0YXl`EFaNpjX{mgGC(ap8e&
zl<N$7<`*7i=3tDM4jHPv+}}?Oq|}dMAz|tZPAn-znFQ_bFuneqf6^Ys_@nNB=MN2i
zkqHbls{lW?i_4r69K`Yl7DSb>ML-A;-PggxP(mIO?bi7J9vknneZDyjdZ{RZtWBqH
zZu+Gu0+yZ4!`z0cDk@r2vNC&PDnm0OQ&EjO#$Nt86uq)J2}=_<Ut*q^2SKr2_+mv1
zZ9E#Nj96n;Shm#_WI<-BqM(CTH563?6h#FBqNF=NAHwyIjrQ8_M-9xKuis7@B~Z4v
zhYtj4(~MffP{Om0a<->*DGnt{0}fiphNl%en73woOd2%p;G!KNIQ4r$KUJ9z<<ok*
zN#mwr9*pjRBVtp7@{VvPnhcDP$#n*&QIaN9v;{FB(p6rZ4b(i66-5C;(83lFIs}3W
z7wEm@pPS{sUDIbBYwV-r_2a>KbzNcUuO3>f^xEfF0eUI#atfv`6kBcR_Gf>RmpR?u
z+K?70q|MyJS}CoD>0{uih>9v|6^07Bg=Z|(sPL*@VU_{`o4J>s!MeJbWR|L9$9oQ(
zX|=sH$5>l&>dx9@oa0*V=PqGRHe-SbhRV!Lr#VM--6{y0(K{iJ9Ar1Hi=8rwH*qf<
zC^$l4{wfOJn@fmDP0<<Ya`nOcfoy*wIziSDbDt(7Uik6*)6^%4Oj9*A&nPXBclBaA
zBy<C#{`^N9tl17z1@H3TGA0>aFZ^WEBMC}7#{@Jc7Eedr_+ch6!C5&FHC}F94bH}3
zrXTGY!vk?D<)MOQGSdjFD{eG085mV$u2H8-LX4)Q#%Q*RShcHzDq!|;!LraOS|hnw
zu2tNtjHFc_HMy80IMib8)n*e?<Sf*|Fd3yR8$@E!D$_9=Qp%ZS$9Cvo!mKMT%*bk4
zQ!<Hj5dwl#R}{FnFd7zXu5Dr<hEXY&;w(p8!)6`L?kONbL5w7rb$s9T>i>5SZdyFv
z*ynlk3)_<YUU%|#Bkn>9&syJS){g~#8zv!`Vi;)idOB|7^s7{)5Z|W?SJLZF`#Q&O
zICl0Qw{4<Fi{{Mn#MZH-AetW-%7Tt?21~5I;rDYw2j+#zM`@Y!bf?;T;r4QG`0&l_
zcg~W=*21SpB`{gmy0>YA5f)z_LZYaQk4>nwNU23d1jSUD?75u7+z+NUWA9Z#)_zXE
zk7VLFgML}GZ4@1ovTQ!GN>Q#gO#8Xqll9hRpFqE<6#+fSzz`5WQuxgkQ28?mU|N`B
zppk-#Xd-AL2!f(YXenBn0hJN~loEsWVT4r-Oau{0M3hiaP+U$(($G+fMS_G89{XS3
zKRWfBFYj;f?ME$Cyt{h5H!*p+onCcbvR3AolTMzt?5|BU+0m;xfdnH>0YpPcLsL;q
zEh5z|0YeZZO%%k`)RdGog$YAQP_ZpEQb{QlP|-0FKvfG6P^?8UK_L<pkwp~~5g}DE
z5i=Y~l0?xFBoO+!;H#)b>GWyP8$uXCLNvq#9!VI<bAdgO2l;AHK8O%Mo<~qbsuT;v
zJaTHN)&y8JGL)3DRS^`a6;f4+j*|hZIE6-HfMIC}%q@gq#uHN1Bc}`pq780jz+f1r
zAWcN#Qk4)TG!;=f0h1+0Sfx2-5d@I66F|$Dm^3+xVGa^w1r)Gm1Azrq6a@@XQv}pW
zOw`p8QB4yC08kXsNkIfzf`yS1treh+C5@<xqg1LM8F85rAj~wh1i@5MNR)|`9}mf(
zO^IR~Wy-=sF~VgGz(_Dhr{H>#<cF$bF?X}BKj0!p0RvI@B#U>eLxXgmoR=|n)28ED
zR{87IXTzcnT+4mVuif}bJci_t(F4_fQ~gKR>-}c_d+$saXCLd<TVG6S2^vB4;qSbE
zO7!mFUQmqrBZ)sK_(*?;DM)Q(1gvX6Pbo}<qYk{gvFkl-FBXu}2_y7+`F5Z($M}%#
zAGArc5d!A@pO1^~9_z8+OI+P>fVpq3r7F!#Wnt^>1e;R=QW$~y0f&wqD&Z=E0M%7h
zRrq}bgHT^YixU%{>(Rpl5_lEa@6cZf##q;x@{kfj>Z9EFN;A9gAh!CCf0XII*L0Eu
zEr<HyxaveT`#J6VaKs;z%Ggr`-w5yV73<95d6xoT5$l8@9eV?n@nU^dobcb?Aa`A0
zL_`*Vn;}dU;t}4%Bz+Jcd0(F~l&&iXTpr30zz2|BPVKJ1BD2N`>fzBHxqN|*z{rA8
z&H7kKdTjKT6(6=aEyGLG9hRNu7ZC>glfdlsIaYqz9up!}pk!d8lNdiWF%M<!ogC1s
z9QqR@hg{Q#1}U7VFuX{Vo<2pUht)U+pJ$-Ooz2I0Jy~AGdg|Hrou9YPS=}CKdN>rc
zhWk*?#vFb2>^UKn+m_fA9~8S8!NC?Fmak=%;ecw#?);wnp?4UWL$U{25YWbVMZ+7+
zJ^xJ%$31NfK)@}B9k3clu=K_Uz!7$E=M)m7Nbs4Qx2%pW<{j<XGPd=}0qOq-xzAp`
zbAiKvfS%?Y0y|`HGBe&r(9z0!oO=W;vUnK)T|PVO$E=3kITv>LJ(5lBCwSFKuwEVp
zoK$r<`K_TMRuGttaFz&dLPTXu`8SCaSIvKK5%K;Ta)&LS&TCRgcH#vS6qxIj7(E1)
zAp1SydSLi3au4FES`i494<rfvG8%!EKnW+aT{rNfI0uS~TG;NeyNLRE*P5F7&E5xZ
zZ|jmq5$Dw==yM};o=-rOE*4Lb++3kFgPqh=UL=7rxM|P0-f#MHTP|IGLqNitw5lM~
zOGdP4PIH~CJc8}Hl!q+jk}!rpKv|$J4V;4wt!#uOnG#+CL&f%w%1%UwG1B-?eZaxo
zWnzBp@OQc4L>!@amtsA%`rDZ~Gk_P1J!|XsJA}SQc2D!OsAFt}p}0m<P$!Ym@9<`R
z7f9*7y?nk+ViL;C!xE-D^`UQa1tKB~S$~tqA|DQ(B0f?Ak^oUMKCpCO%kO)NwuCL|
z{FP*qMIzQzP*9~Rgi#X~u&L{T$N__;J@MCh`ga4uRQct^gz+8}ugBN%vL1(PvnM;G
zxCBVatgj2AO%8wG!KQh4^l0Xj44!_To3oy&s~nAJFkmRA31&DY1J6U>!dcs(P~C!L
zf#FsbeiIZ*0h+#9`K8;ekl!r>SP<w(QUKtsmbea>$}J9fGl*-yr{C<(5xp&}k-(sn
zN5}lh?vr`MsPtb&f97bw<A1@~mu%e1`8geFBS8IRsPj7DZ{GIeY3VJ{^!bi3<TfTc
z$o>8z#LMn#9Q)5`?JLi}d{p^wk3S*RJI`cxQrf3b^O!ilOyk2ayfg<Dw+XYuiP(I*
z$Mv2m$K`ztTi{fLB#*PRn|An2c3579j2n1&-vh^IdE`tSrrt<&(1$SG8`GwHWIa{x
zlQ|C1Oe9P^`N7qwHQ_AUZEbsX?L)(sX|`+<$7-_Vx)m1hJ1fT?5KptE^<>+}SBJR@
zt-?yqBF&n2#S!FTp$Nc=O|-sF2k_a_F_8_V8%&P0DeK9{r>9o&u3LfRa7rBUjnlEh
zZG=fh9>FA;x)|nSK_nd^)Ng8H5;5djZG<ymfnL#!OeK_MMXf?nZ<vRMC^oMd5#l(u
zc#DLWb8Q{+JE=QfTtsLv|I)IFhA2^4$IjOKKs~-6!?4HDNUIJn#MS!Z8$dkL0a|5C
zKX8qjh8m#zt)p0LG#YT<z5|gVDN@p3LDAOn53(|ekU391Ry=WI=A84Bc^(;5Cgt42
zFmH9Fs!NLuXE2;=F?z`+IfJe_G64b?MLpkb|Ec`ac`;KVj;6mYluX76z)ryknGVNP
z!QFJq0kV`ZX=)mcA31+c|Lbqxu~ols=FHoWm`eM^kOS=-NHHRrsdBsu9MsdlQM1!O
zwzN}hO~_;L-n~7Yne%#}>Xb~Q%Ckssq4%PwT3^evkdhx?6$;VDg3gCNoPRJjuA1lg
zszSU*1vjAe1FBMxU62jg-zkwXSFamjR@3PFYm}HzVXL6oNRkBHff55n8|g7mq-g(o
zo1>LiJU&ZI(?q2}K>4muz|>C+hYWiS8!`Ko_Nhu@NCZ>SpCS%gF#fNbz{9V481tnH
zh%&cbHLBLSq$q=LCC@LccbE4kOZcRW&rz=j9T^I+^Ng)DP(YI<?fip{ne=biC2)R3
zj(DoIloK7z6!N3z7=)}$A$5-hV3wL_7YWn%PRvF3dmC(VtK)_%3EUNkI;`th2b(y_
zgv@=AeF`c{0(R;k-H(2CSVGtlKwcUI8Ahl(YB!Y8JSO(vZ2SdU{cDwt>c!95GDqh8
z`INAll6KgyTNH^D&*_HZMVCcmx=&)2ssJOn4ifhc4NDrRjJI2F*KYothT~qJ1yV=R
zSq;~V<euZ(*fsgEAPsv%6QvX+&f{2QfJ6JCK-Y~*88uTZlsDgQe52bU!C3`tNg5+D
zRP0-JS<)ua{XIUs#4CdfC?4$I;zUlCnQaUdzpr-DAux%6&*}MpQS|z>J3UQqbtv(5
zfYVGj3-wB6<kH3?T8Uc%4N$|HvTK;=32x<N@0%BFnbX5Q?5s81ExeI<LIIiGi2XP*
znhecIxXk;=QcaUPwky3JWD-wZ*R=#A@v|O|-u?Amdmn$t1EzbMujai_9RcLBBsC{Y
za)Sk8MX3s+n9y5F3kD)Fh>9SnvLlUQ`a9>E*Wc~xACGu)dE@vk-rPL-GaPzq{s+=>
zbcd~vQYVsl`6?{;o%$XdzOOsb_!nt}_{peZVl>s{d2-YS@2k7DPXg&vJX}~QYO7%j
zBVgw$04x2(4O<*c$pwX@lkKS^l3x?gOTPNpC75zPU5-yq7Xg&%{9D)O8!@{JnwF9`
z$e+Aog4H@Wu?J2OW^TqIwdwsDjN&axwdsEiVZNme0SYHykhsIP6^4<gfRBO{4_49;
zW?^=m{C?D#m@ELT<alt`XqveKOykFH1HO16Hr(vvp-5NK>cYZeo`*eQQXsZx#x7uO
z*%jErcmu(Vpjedz&Wc$XNKq?nclfIpQ&TV;*Q4#x?{NA|14*-<pA)wt*~$$3z`UcF
zi!c&fos+11+_Lo2_nlhdRs!{GSRz6}0R$Z-a7S`CBMTKATr{1J!ybJAUL1*{$P0r)
z4(UI9pfPka7DRlVB(HUECyq{J>ksI>h#-a`7;U}0UT{dJC>KOJA;OCr?j#LY*S;};
z<LWY<MMN5WC{UIMW*_GFW^&eeardEZDQ<D~TGo_wk<ghzgfETFF^0ooFdkA2xt`cD
zj^}r9efApc&@^Ap+n%D+(JpfE%bjn#WtR;VN3c<_tK+F4ny5Xn_s4vab5kAnP{e*S
z&_@SsIoP<GI`Ng{(cV4l!Iw&iJYnm4W5#2}>vcmA1wll#hZF3o;K-o7p}$3|V}eMS
zlnP{sqFMrliAofuDWGCquyN1q6o%d#Ub#E1o~(%$*c6)dY!2a?8bcB_+rBWsj6!$x
z{<@g?BH5G#&{>;j0z!djc*;Ccf0XQxi($#nS{m)L5Yy9!BI*jX=^kfjEDa<}ARM9*
z5awH9W(^i&dBzSxCPAk$<({9p3!cP#Tl?I3-wwSGMJ*d2C4++kBVq{%ry>BrOx67o
z_vq*Bmo(|C+u~5oBPvb^;yzToT=En)+~}xCj>>p(o_gg#DR?;$#EC%&o1LKHE~c_7
zcL`tG9$?SBCgq|vfm}p@Yd|p6zoUiY)BAUasGpx>^zP0OnM5R+ChXE8#}VlvHSsU=
zMB?$!tnXzfN3?Bncs4fk)ALET3>-%-zgO?`XzaXk)pe*tEf*`}6`6TL(PlFe*K&W$
zRr=xF-I+%ZC!we^r1A(A<ySTX*<*b3vUFh8!ppn)J6MkylQ{amoNeemw;G40A6;?P
zXmpoGeD&{T(pu5W8jTbWNn(=EeZQb~q>;4b+a`?@80<zuyLts8bg*L<61WsXByE=K
zqI~LxA_N#Yon7^w)YNe+e{OouM`@XGo;~z*nMK1^&()L=H=+@4>Q;dYu#^C3WXw`l
z+1S*K(E@W7bQHW879?%o>c0-JuSKg1_&8VMHxe7EG@~*%2&Iz%k91o>sAo@0<D&|$
zuR-(E7R+uoMocC@IN#G_XeiU*QKC%mKNR;P0I;&gkak!BWU_Wrh)gCq#yomcS=rms
z4d7H8S-j2M9D9&%mQ1+v2Zim>d!l}jcv~Jhc21j6ZemdhB-4356CPse^fd6sG-xM@
zJw$a;(T04Ro*s_)eexV29A<==L}EQs8l!Z#w{q-PQy0QR?d92=?x<F5j4fN2gU8j1
z>|<{vie6yL-j1*~<=go#Sf*le5q4RNMq$O`=7AikmB_+$ButTpoV?Ybd#}*p?#pHR
z=Nai#b!!|$u*JabId`?kv2S=6GTHW<#4QB|prREbXtl?u;TKx&x*7#VzF#Hqyl)td
z0|peIKOUidw~1rFQg_|<5;#J@tD{iD0;2A|LIya{OEi#`fVGu9e!REueZJ@PVv6*0
z3%QwiT+sRhgSN#@ntCGP_2rlcc7Y9+3p22DRvsHG<;(#c;fq4d2UCbu223%$iXQ;1
z9&jzj!N7GQ$WG86okh85->fhn7!o%jjX@)`&*>l=T+!c7%fo2n!uP{Ymbif9P8NuW
zkn%dI%To?$gos2hdj`uU4606kiK<sYEL9AIo{FnQD7#C~Y1LkTB{;yTkud3Ly`qN1
zH(1=kK>#~zfQ6@P3(y7Uml`+s*Q%*YT6r+^W41#pY?Sh;f^$<OhzFir>6{q}tJ@S*
zn<HaZQB_sF=0mJm86zh&(tvJe?Ac#?lZ~n9)F$uKru=oDB*tbG^8V`*ifbbdKNz4|
zemYb>tH)G9T7Z$?OvWe9-V9#d-gd*rF}5FQs%}TmN2eO%FhLvNF@<4x{WHN&mw%<l
zjF^e+raLQ<(xWfuGEI3Jq7v3@hXzf8D~~v}J2~$>m$>5j<3=Vt)W<vWCzMS{obV1X
zVPOdd;d4vp!)i6(eWG4^Fm_%xuww!ZZPN#f4XiE3@n;yfa5j+7nDDSixKxqNrXHUA
z05?$#Kn{`<mo~JK!ULn6a2ypp_cr!Q)k?5ilQRSbZIGrt8YUc%pX_31efM_Vc_#c;
z?q(f(qIPME9*SP<YNR{c^3Bl5v*x=SPzB>cL`f9Wc_8Is_W!f`qff83|F5UzU0<ql
z&))6`Z>j9{V~6cXr|g0UNT3!=Mxh}XZRY$rO+*~{q<wdb1G^RgAVL5kUD^=%I`^*@
z?+F_#IEI&6=D~tOJ((d7W5N-LWL12g(eC$Cy1rW&K{BakK`>;35HM$EA(ANC9|Obn
zzDXg`=x5*Xvfkl`i$50V6?d!c`Tdfg!?xYMEB|R^SuEhm!Pc@iDhWsdsK>U+l7fWg
zVvP(H4J<;%ep~sVHD+dIm@v^@e{3Jd{z5;LjS8k>ieI5<wDy<zE}-=g3=#wp_lXbs
zh01milj!cVMfMNUhCxdpNV5tT_D_f5$_LF^nF&nEwCp;?i&8sJjX^a9ML`f`P&x4@
zXLa~94t?1@f|Nlo#4)4vGl1|dR14Ga{y)R`eb)E?x7qOYWqBE^-vu?-UVHZA&zCNI
zm#PB}N(X5kFni#`-%1X&T^b~N<^AOWLlhw@6s#~ZzWkpl8%j`62V9ASDqk*SAJmXN
zHWCbwx{<;eAUKrKJpQd|P{<U>nN%yrM<fsUtT_q^Kz8OJP_%u70DdiC4HQ@4RUkT_
zaX<lbMFY|JakT>xKtc&12h@NbB{4;-c9=FlN|P&;7rKm>@AY~7u=swD&9_=2ZS~pn
z#>?zf9#)6iCFJ%`752h2t2W-gtD<eepYS{{x9DCg)6b`QjBmnnWkfT*{Y$L)Rk;00
zA|%c~3{@|i2g}*&?_}MozjXN9;i=$*tP>ofKEd_*VyU0E?H<nD!b0bR46VN*aFBiP
zz3IRE+`6qTt~w8*Z+AITa(A)gsSmnDieP~r$JddTc+~z9JtaXJc+SWOTLIBHDBSV!
z#eT7y#C(lK&nI-)O1JGob3<+Y7E;M{9S^P|t3yFmtV!Z;gW*|WAHwkm-x~fpyYIEl
zEJLEvXAjQk`r6Apw`xDPc-tzeVd1I^b8708bVada6&c620g!fTzNk~<qhEb#F3p!u
z<9BKn?rZc6ew%(@?9Jq`^nL%Hp2CpkJD45;Jp#r|8JO7)KPI;y9%(jcmK5SE2}HUR
z8-7OfLNme>$mGZd?*VTlO^rMKz0i(sIq>a{Z&zePIWfn!o8jAXrTsSNUdU`N_;z8~
zKI9lDB87%AbO?o8$o?+Q$iQs3J@w(2R4tcL)+_n-TKF!GaCrKww&`3D>!U~}Q&=oe
zu?vsSNmX`cH@XzL+bd(P6JVC7xepiNz4NTSCrBPi4fz42kn<wN7V5G)XvfL;u&Uq5
ztn6SbRu-?K=ED|+v8_6*F{(P=s3Bm~S9&}0Inilpel^hs+VJLbt#jI-p=Ep#^C9Q6
z5psZQsOIKv7LHfL(PO+tex9#2mdsySi}tAvFu5vUuiw4l1+iIMuIP#GToO}^9?bUX
z*sa55Ukw(9=|gjvXN&|Ps#%k-gG+L{tVM3N7ROPMV{lY<ZiW#?U(e9^r14dZ4e7sn
zTBm{RN{qj6WnKDAp2aC#!ynPFTn#SVF27IEm9e8<)7zW{y71AnL?kSWK?lmzHPV{Q
z#DiO|R%EiAD~>G;Fz@4`Oi!J?nXjaQ?<j-_pikqRWC!eo5I@5K`pJ0{a>b!sBX~<}
z2Sv(Kku4h1WFY?ivrz2>K@!Y^sRJU6jqWO%gNT8M1NVeMAq36nS^@kZ242qjI=ud(
zr{&jv^Yxc;8?vvIlw+LZYD7JdM}MEArA3*zx7_X3(EVZ(mwzbMJ$346)+=@QU3F#>
z6B1D-Z5dyU4+K_m#u&HD!u&&MZ>^Y&e$UbVHUd85x%Oc3TOrVXkF9z2mMK(q$1Bfs
zA9AusrS{vNu7hHTnAJhNVciU#XCxx*s(LqT9-R?LB&jM_I68&?Zg~gJdJ}#)LH&LD
zcoty^FpLd^0uVB`z66V5KeMAP?6?0Q2Ep}2-eu+!Ut3C1c4c5^XJ!{a-blTn8GHq#
ziZKaH@8?f>Mo}OJZ)=h}&mOB^O!`-U3M|Mn8tNP>p8u+synUH3zat>V0FneGfJCKa
zUye6l8<$Hr9C34O+o(=1Q(34S8)pXyhJ(~N<+YPP3f2ijr#khI-?#le{vEbOy{RYW
zEeSFK4TN*oqkTRmSm7{}2M@!V@T8!EUE@}ZwD~Q@!yODT7lD99EE%A6>S`fXG%lMq
zVMX(toJ827*1()wUVJfS6K!zCtKo3g<c>o}D%;Tw8V;d)lg6S42x+OqU&&2Tt2JOS
zKhQ^=#BpT7vYZY0Zn$AFGI=vCzK&Z$yJ(Qu*5i<%V5_h`LTxu_MhyZ(-;ca@c~_Di
zXMVpgXiLnj4NxqVlbokB=tY071c;wR;}4+xXXW=7kZeTl_&F(LJCEL*quJu$!@=Y3
zT?TfNq3X=B3>qq8C0U5+^x!hsI8dBNgyH4*I30GrQfoy~TaF}{6<~5*n)-_%rZ#nu
z&6Lz6bjhK*_ZY+GBvsx(xDk`;3=nW8EIUPO!|E1%q-*V<4e1SUaRx+cZyQs;PA)TX
z^OqyX(Ga&l7I2bINI>UvsH+~qks~`{Do=rI(=YXYUHzJ>&LvMcd4m;K9`1-RgW8JV
zuUFgl?PmUuyaFGFitO#Uy7hX>hwMwgzBg=dW9~sx>%DxC(<^*Dj_LPAVJ$>h`geOA
zB)7xIGmo-<Pp`H&tm|~-Cxl-wI*5#5+{^JLc>+*=Dq@vs6!8KOv(-VgDVN&6v5P9+
zwBmkU^6pA8=TuYFvlEYw_*P@$-l#YJA9NX8A6z0zc59y9A@_BuWUquge>bPZNCY>f
zDDN!MDA$Rr5aGiX^lZku{CcczGInUjA}U1I(AJSLA{dWR2lf>Dxb?(pV_)UPMZL|m
zXB_H`<3z1_8$ld%HnTh$#-R8?w#@i6tbKcgVYm$S46vAPso3uKzJF5Y)-qrlk8#^{
zL1rgb7@0KF3x{{KRRiK2v?@Hr^P*eypP=*n_PywoN)n7}ZN?@wEl8jJg_SX~GR9WK
zM(fOlim`KZ8fC>oqPUnDM#RcxF|?ym8*>J^o0TxO7PDq?IL;ijXAA_+VqMEyPBeFs
z;2vsZPLT>49f2e%iaw)r)#~Z)L8FuIZii8m&-dPR4vIrUE-Bm(Eg&OHWT?fAa|hxz
z;-B0M61yOuQ7GJEn8L*xeuXRm*ho*F^4XR|ejVC;-;Yl}$DVNor1}2;*ZaS+-*vyf
zSf2Qg{o*;gXh;$YRU9RQHWMLz6V>aGwbE_t12nL<l@8JutCyX1%cgjUznw=DA5b?L
z6u{COrgHDqj#c!ZMsDXfV>Ri~qgZ-zsA%IVqJ}9-Lj;J|8h)RuEcjrIaLh{v`>&A$
zrW(u$q3B*38vGdANMc64gc$VN38PYX5*n)LN|AeQ>cSv)^9e_Pi!OL}_j=u*!lI-`
z0q%XN+h4y2Bw|`=p``m%Sf1gQ8IacNv}dK{G&XJ-J`aIli-&<eMv8M0xiyG^2N{Qc
zC|`E$zUY&1z8ulHqz<_wX(dz|fSEhEr5y@uckG#t&t7-yykGG~B~Acz$CJlsCmNQf
zV995!M3ZG&t;UwRVTQ&~8AAv_D+vtnBvlM-f4}2tW@6p{q=NXM4VAH7b`a%#l#50%
zmFBbHU}gtL>_a8S&j?^VP{g?4@TC!;?(ZA&{SE=MS&p1L447%R*h{?D`=!N=ySdOz
z!w<{tdeqoyE`y^aH%JUbzWW3tFU-vh*Rz=PsKO4qW)a6gS=Kr!$~jEqj^Z#Egew=o
z<APyDasjWw%fJJ8Al|#k)uXqc>DlN*Q3Hph+N`IXt=p@YO}KGP4-e<*CV{=$A@oF<
z^?|Iizs3RJAq=wH#yZ0eQ<F(_5GP{;$oDXH<C^1LHpRVD^cZEuOzL_ZhWjHirHA14
z{^Od~d5v^tH$S4q;$@$5V}uPbbnZST2~;G?90;I92nSEutML8(V(;UB8$Y)O%v|&%
zT8^vcKymbYh8}MlZXRIXpJe06FK+ZdVl>gFRuc;Ze`nnv*3z}0?gNGvDhT;5rX%f9
z9`J<%HtUAEH@&bJe%J?uD#h)05ozoUqC>pa9&@fDl|LIqw^SGX$0ZYo4`sipaIH#-
zlLmO!8U73({!MD+xTB0Tz3QlFs|HtVTIA58B5-0g)G=86+f*pDAp|z~Qyio&n4T6&
z42B7*oLgmGeC85M3%%_Xp7Sy(Pnm<$jr}o9VcpU3Xg{vh7zhj{p~bV|2pHdnzv_<c
zLm%CPzu1dyVfc8U<3`tZK(*{(n@dwBIq!sF6+RJtw#QpA*ApZ-sG^WV!E?qCLwVbi
z+7>IRdy}jY6Hg%yC!#wyAte?4kq2YtDQ$-6P2$n~n~m`=BtY=C1jrEt59h6m{&#M_
z-^b5bSK;kbZsXS8nxK@E7LV2O!NMiVh%}oB`4-BP-p>WCbtCA%pIFnop&b;bL&G(u
zIr4L5D7HBHv_=nx@rLY;{$D?yT2_;xAo<pi+B1vea}jbIQ6H-bhXWl=q7fa^<snwZ
z$=ZQA1O+7bEtu5z^2Kvc{(Kqr@A!%7sgAMJibat9)a3)uRjXC!<o&xRH5^W8*4^OW
zwPac5*f=;h5yuoAR@Nm1A!Z#g5kTv`g|KZM*I|XPR4naSS#L|}ymCzJ7HkeG?J(1z
zP-l}+hAL368+FpLu-RP~4N<;~u6XFL46UR(`!KpzQUV|&)gZ$w5T2_rl3dUmR;d@P
zqXYv$HBh32{k53Tx4zgy?mbqogCPLJ35Uy-&PInsv&gt+bM~By0~6rMAlkR-p#B9c
zr|kUSqv-_xW@rKmgw%q+us^Pds)|4Ahasj5pcUFsoIuhr%Fr8$QCSfr%#}e+F#$vn
zF|j};px8tB8!?pSb4?8}VhAOog|Q25VuH4a*p#)3z(y*9f{F?VrGTV~6Ly-!WG1Gh
z0}z_Z$e<u9NNFV^Y9dtJhxp{)S~rj9fWl5>9N~^wF9a_-icsTx4dQ`1k9fOP1Il_)
zs3077;Wq?8?%9x(A&~%2H&<JX!8HTb^dB;O>H7#cgHVU&{YpZgb>Kg@{NGrMJ;D27
zgP?yb5Iuka^(y}TLsMU=9mn$n#Y{0$E+L@^FbKmycf8HopOH%kV>^`97;z{}tAmrl
z*msGz17Wc~WQZT82i4QK6r^HE9<MGOiQw~4;Qf(8V2{9g0n%)va0dQNLn(;}ff$Fy
z*a5@4kTfBPKocD<?+yWlVs%3r3QV=H1Np+FkWL`?7B}}vbUDP|3E&Vx5=AHaP=~<h
zrAkl=kCBuu%7_zq^LUnHkYH?4y8HqOL`B%I#}q8+ZeWzQ2aF_nlbU#Ls@5iHdi&>$
zBM6o$)Ly!SetFUaFz&Owz*|I+*7<R1>v3_gaQ{PGoq*-{*({t$N(9S~C<^tEHw4?*
zH&0-VS@JLtP;~~$#B4~+j-gASUuQwq%jF9Y;W$s-jzmRd;B4;jg#jSRqOV&?VKKyp
z3eYHBJca|@J}`0(bKnzj(7yB;3ZK(7sg~!eisdvQX*#NzMcncSiIM%@9FW1zfoUp`
zxfC)GGKsJr2=>^r%Lriw0G-N2I(s%SfZ5qy2NoXRU;45-ksmULhCtA_J47VFJqYYO
zfrvRb9D}>MZp-1=ft^FvCvz7-;;cu_N(XR1sRvU4)$2~kNDCOZAe;{Es*;LWYwWAS
zU?pdGyy7X>6<$CAVD3j@JzDP`G#3dUQgee_>;chGvph<$H-}8Y-iO-|8^jp_3EE?t
zPUppa{0Vd}X6S>^J46mBsmcx=W4g+9hwrri3iJ?18B)~K(LmUBt<W?uu=%-~2bM#G
zPX}{}0?(|zWz#P#Z;jy{1BP6Z&rmR2tH30C$0=4Ab%&Z8X!S-Ts}#|DQCt*5!ZHJy
z6*0v^kT4DbSm=~}km(ibUAx{vV4df_A%}6L&4J83%ID)ZnN6`_yF+D9VbXF)4;=z(
zhNC_zY*6TAPD8wo#UJe`fuT=S$sU|@j6wtA#O@+s^)DC~kv+$&Ky2=!jD$aZI0%8j
z@&n7ZfUSa*%he8K5U2uhA(v#>9YOK4sLd2h164dq9D|~BI}l)am$|)(!q!vTWWljv
z#ZIN5@;7wqn~a7Y%nnA*z{2MBC=)ez?`{mD!D8n<2YeG?xMxDzG~iDqx)A0=ka1JA
zz=6QwxF1=)_IPjNfsmcj8<OB2LrORW$QYc#if}U_vcDT1x5zzZkcsxZ;bG}LITd<E
zN#-4t=hY5Zsk8@Xi|oS-VDl~~MLG>DiHJB{z!~9g{RPp$?8qHdvYW4&o=D__lJjqj
zjD`lGN^$@XWKitb+=}=<ro7<9Jz)e#268odq+O792YR01&@!gvFnE#>+pykT2_BI&
z68geUbp198eVxB-0w_m;2scyk08vUrG&hBn(IRn9^MULj<XE851_Ty|6Zf9PJ3Hc@
zVAThS8&k{A&9x|adQJ*%C(H0ZTmJ#~{tACSEA7GWzrg(0fio;(VhMLj|9|*Nl_|A|
z>H2A`gY<+WY4n9FM5qCjlL9)K<Py*8-0kfL;DYHP6;Jj=+VyCcy$rQURe+3pgUBV^
zNIH7W&Y2+1smKlO+!+7OnzNKwmf;cik3dNT5dEy(eo@Ex{}1IakLoA+Ru<A#-6i*n
zExT-O6aDPuJM|)ElG_v4ne@6?(j15T|5*Hf@7)aP)J6zCojuc^-+}Th)11fZgOgo7
zUJ*3y)1oQo*nWY(NIIXdKC?@x9H4?=s)(6gd^z?0bGc8pd_O<vH@7N_gkQD%;q!di
zKSLkRWcZMUnwWR&KcXOXfJl~Zy8`aANCX&zlDXWFEWD4i1M`q@FmfkDf+drqz2)J)
zqf}Y4{=iEOi#L>dIdS86F0S~4sD7V8HhG)mgpiLTw7a*8QM@_^r4(dbZkNxG*?>|Q
z9vrVjk<W3G<QRt8p`v17SJIppwnj-OkKIrEtxbMc=}*zn{?z)9RQ$o~_~eq;A#&k@
zesaYrNYJGL$$oxtY8#9TE0dwkvZ<n_GOCfOs}%|<ZpEava=^(7QcQ>RIziaZDT;~M
zHUZc_L0~@bmKhu2GHza2=hqLi1w`*VO1u(pG7g9Ilt7e0ARmhTy2r7NTE`Ot3av+f
zFyTb5?Q-j7fRGyrIX%bRHGFgq!@KUCB^bUiQ%F!WRO<|n6c_=c`yEg^WCOwIA+eSr
zA-Usz2LiaY4WT1CE~E$?gwQr%9TTYi*65T_5PAL0FG>eub|+h_!m!MF*0V!QJSSl*
zZN&@1nCx{281BWCSl)Fn1Vx*fxT!f(meFw~WJHymVC9z6T)C43Mo?CB3NZ~{b0oQ8
zJfeAJJTE0$wGL=8B&eXE)Jco@k=Zo^e4?R2lr>yBx#AnnH(VhjBFQ7x7?|M3=1moD
z&f*4v8dy~*7UmroJx%IkqiAmy@d`QUlJ=1~trHURT2h`8l&&6S)DfiVusHHjj6}7h
z35L@En|3wXS6tqNgoLDbhhNLYeX*|3vaGi#s02i|0wjotyv$c9rHCLisXgJ$sR6Qa
zmCf!;IPucWRn;Ttzfc}%<EYe%P?sWarG2&vLzG0K4NmNTvjD(C4_6;@$cAo^HW#{}
z_M3^Zu*E}Jat#Gj--@9i2)6l-mFb2#lW2U9?Tx`hVOcz+`o6p9am>EwS7>yfA9?eP
z_SVv0mMR9Yv{(EFyH3>@kO6^S@?@>WPk20%_?(o&_;@h5fWf`gkm>|)lQ^Gw@Z&h3
z9_i+5j92ip8POf;CKx$b0}qfMCOgj<W2ap^Devn5))jLwz~W;?rPR4m3yXw(5evq{
z2`p2y-$x}Zy8t;QNF9itFpEL>WywsOB~cCilJwL}(eRkBKIC(>HwUUxh%3;`@vwMA
z-uDKYM1+bYGt52$Ou^}2Lv`?>@Vy9ZF%Ty!A*!JOla9#25jYV$duaG41vo_^A?Lzm
za#%pSR5Y~EHq9b!ubJXz1}^}h|CfCjK_oFJL=3s_M&}Pv5Yz}PK*{n&s)3X}$rsOt
zK3QIU5#Tq0D;JeOvFb{f1=y?XozXd-uDplEfNq+=dI8l714`1jY2%U@?F#8r%^}sn
z4N7h(WQz9!eKHuPnLBzmjHd516Ek4Y<xoWV044<K1oJ>dD7&gUcEs5>RNZBiLe$-q
za^N)+m>Qf<tM>Hws&+~0?UATS`*E8@`XgRCSV<#gQAHHB0HP<^1@dnM?)MU{7&43X
zcXgCQ)SkEDBjnBWsA^fXKrb%zj07~|4p2y>J}s-1&m-nRvqJ;r?mlV@KkG>{dt3VU
zM`#9VIf9v_0vyI@d-Zz3Fg2hGQ<I_B33BPE7SR<UfE3DY+21FOCx=E2n1iB*2(w)p
z$IKIo$m|F}UVu_RUs?&Fcs_8XP?21JXjK3`lzhy>j4=StM*<iq_Sskg6gspn{(NOT
z%TOu&Aw%e+7Ya6#C=h^oQB4>e5+5knyq_tgV|9YcWS;`4Uf)fjZXQ;G_1$nhV4Nvu
z0f?d~u>9)T2d|o%>L{bg*OpNgMyT5ptds$es^(N!m^j;p{QH~St7k14y=Ge0MpQhX
zRP{#Ay%MGcfiyKoJEt1JW)OtQnzpI<2n+&FAi9M<JU4`p3ZSE*<oSNuQ_o7(2?&)P
z6rmyYvx@haFgD!!2=&s#6EI66vhwNekBEwJB!&+x4J<-L6jBaA<WLPMKxdm5XiZ$v
zKxFW4B%yW8>BKB}pSL`h_fH}O-U{p~N+y=Fo%0DHdO4>d<dmgwq7hnwA~>6vabfI8
z^F&V+Bu%+S0p~Yf_@fstp-lmNx^%6#k<YQC&UR@*_(eLMBk{P2@*~HybNXjTRGcjf
zAVvg%5-@X4H4zaqL1ZRWCqlsi5O%eI+*Fnt;?dLHF=MG12b^44hO$O`>F+zg9VHYK
z=r<2OR5qSozlV?zMJ3P`9I`;E!_FPwCRp?Ify<UKkF~T`&-!(_H~g%%wMq%X{q`xF
z$R5zVO*1bhLSjW^pB`QtVj;b8GgwQB@}_9DHJAx$x=yg>NMKyrSSSVvK&MH=3>^Q6
zhVy1Ha+#f+4vrY}a*T<Www-Efbz+-F14^nBX=+Z%)y}!W>=iNUFLKkjT+@+GtqRI+
z=8tXxoIe!`$fKQRCt<TleQ-#2fsze6w)<@5w%TwoDq3EU+0OM1EU?OSFasx`2PA-Y
z*g)5E4^fc<DsP4N(*cTMB6gxDWWh{sTWE1k0nIV8bsglBNl@+C==1v1{h~V(kWDl)
zK>QFmY&q;5_DxiP9wG(i)yUlOo??1ARvu<*s;pf*PL&#}qLQsS2XPjlk2(&peE~fU
z8Sq_?#}{wEHal|XHN`lA-JDD8@Y3B$G|C{kVfCT-5UdC5F9BevgpnbP#>Qmeq*FtA
zx58)>3Nlx50uYQ-CCFk-jzN$*<ekN+i6aR<3QM_deDTK^cklChzLSB_f;jn{aj6d%
z&M4|ha$Fq;fSp4IK%v^JpC3NnB@N*R0S%P$9|>+vM_f5JU}O=PdbxbX8o|?vM8B^8
z-%?<tz_o?S*N2kyyCo@+Ecl^qXvlTiwRr~ReY1=(ZX-!w$6)KGqYyiqX@xv_xk`nM
zn|kn*+Xft)-JP<aCw#aqL3_cahi#Dsrb|v(k!WagDfC-0Ff!8s#Y~d}moFQ*>0Zg=
z?)UNV?j2s)L=gm5OcKUUn`psB^VNadmtp6_3DT`fXtYb)%-chi@W^7Ss;Z)>(gB2p
zVk2aVO>&^PQk78PiyN#Ez|()f<Z}0&XLv;FHVa}(Te49OUtVrEe%Z?=V^&8A%S}kz
zH;bk;i$x|hk^UqJ&4%M{FOFASgNt;=;^&70hGV6Wmaq4)bk9r};lm28!=eqcR>Vs)
zaF}jfc1W}~_Uj^64dFSYPB!gTb=c~K16(^X!*|$Wx*FQL=JL!?yFM65%tZEeMF;}Z
zX_)P2chzdpj;BHlY0c72Y?-iwY|Zb*h7m)*S?1(sO@uzUM2M`CN+@lRPBiN##om>o
zRlIF2Y{CI75w`Q$Dsb)$`@_c(r%%EuNP)NL+_Xa`d=AW7vb(byW-RMRLO9QEmBuqN
zXTxMzD+a=>CmZflqLNXD61<T}K5Dr>4v7^M`sYcl7smcIjbYb(!Aes*XT{*xCi&=-
z#gui!?o2~LE!rDtc_?>>jur|IP}KDr!?4QTg^KBPDDw4}Eh!KTEdgOMH%eou9grA{
zfh$I(+ey}4(h(`dwPVA?4EmVHLiySd;sZ-D+zJ#Qk{rG)9yCoN7DWheQ#NWq!zS%`
zqZM~x))$3RIU$9@!X$m1jjO@bPE&~{d#uIT!omdB$CHFFI6VZzxZ-2eo7mQ>PFsc7
z4(KlKJ86`zV$;dpTsO1T;aEH<Ac|ZaBs;ymz~pEeYr%!D14J3{Y=UgI<GO|b!mSbn
zL=uF^Qj4=60C@q~()0z!f`b5uBydS67>5Z1Di~#vh%wy5XsQV2is{mJhd<F8jD*1$
z=TeFh&)o(_5ep5BX+xC$Yvghdo$v6;PMeb;6Y{4UU*&X5f<1)SQTKZ@p`97vr;c1;
z^j?r{Fr|BMkI%ksYRs<a+QF)sfZmzfK{$>`IGq+!Fxx;h>=_X4n9A3^^_#dRp2eeE
z8|J-sn;42z03QV|q}d#o{QGZEG$0^$){+wVEgGrt9HjzT(Kqu_Hd(q%{v+ZTJ;5XN
z{0q9RL-iX0>N+RU{CdI#6s9Zlxmg7yO-UaK>EIye?SqZcJo36tnB83`*rqQD#=(0%
zSQ%9#NKg?98M~qDJ97i7Qa7`OA6Y1Q{EkE~U&q(rc;pjdkIQOx;3L_F$I-v)Kshj+
z7swnwuv5Fd?|RyS2DB(iZ3mOe^i*IMUSK6M7iEPt2oy3f111}AyNN#^YtE=q60kW0
z8%>ZI7!2!@CH{{_!w_jnE~Xe&5Edgtwq_{AMJjN>L@&Xk4bBo(8PM4md8rdng2E@r
zfE`b_yz&{bv;m^=h6{A1!1r<o<=#d&oYIYindBh|Dm+&H&^z;gQ9DhLva%jHRC)H~
z3x{OF+FthHaq(0ycqa7>!;op?l+hIB;?SKRUxbkQr^NW~(K8ISw54LXl*^7+D~>Wk
zK!hwmmj;(DwBumjs6C^}Kf1}=-_nX92#}ANH+WD(zZSX@Psr)Mt>@3iv4?!>&`+Mv
zA2mG877%#Sy&>X=!^-uW(|4^vq|!1qY><?IZ%m&khXB;v!)JU`WS?TN^4<`EBd^bP
z5)uc`u<Z8(l}r$PCQ(=4@|N2N>X#^^^<r)v3VlaLxD(3f1R7L62?8WZ<mECG836Tz
z(j~N@dg379FnkDyz@#euVF2Sr2@BHHW&OaGD7Ze)f9m*f`n}{|xARILZBG1ffIAlw
z3=qJaVG0oIB>>4t%uPT<kqk&Wfm|doBw3shu$K+7_k&0rFZiPCVJg{D6i6v)WJT5#
z`Ir_(gjQI>i~=b+X;8M+g}wi5>USV2We!wx!5wJ9fgs^A1BMJ=SaMiLP$zRdj-a53
zLMJ6U^w}nV4gZyO=K|DX9MMik2kF=wkO>k)!bqNe?X>Y&qF~dJ5l&de1lD3C7D1e|
z0al~=E=(7g87J!HsoP7uaLR_}IayeZN;9&tL-muaC5r=4tp1a$nh7bHl~}5^SOp5b
zs?3qC)CP=0tq>p+%AMbtkTtk|t2QTgQJc)eBaN{7H(Fsw_R$@QGn*4lE@G}O2N6<O
zoerfifj7h+EH{YXcEjbG3MLxxEGkudlh%fP%tI5f8s4L@()r=nN*Ejx9x(D=mO1Bs
z*2OMnBE=9zjl$y~eg+<2842T^=E?bgaQG5KAvw_XZ@QF0GL5O1?Mwv^6%O?2Lb6O*
z0D;L`2i2?r6-Fp~B2=R`6H`cg>?#O51CuByf?*3dU{IylE0k!%&~^?Zk6q{xbq&Bd
zSDxFGMD;V#IGIm<y&5a}aqrj@hzs#z5@+f2HT8P7wq4g~y<i7E!lGG<A%KZU35jZn
zI?a=c<e};hU)Sj&AWOI0PGp_@t3wM2IAhtLhSd}q7ilOWh^90Jk)<)`?KB`9p-QeG
zHdPD^2<WKcbODG)>Gm512q}ZG!M~}(DRGeD6Xrf6bRBX(SMmj6sft+zk$#d40#c<4
zz*!q*N+2*w)+-RvQImi~GniH)#5n~eDAF{<20)Y{NhqLi%=(&?U|7_%$kY)ALU~9!
zX!IY}?v@jBQNY5PV_0?4lwfiP1SHIw4ak9l38G0LVQ|xiT+KORr?&$%YJstk(G@}*
zz-77;d~R)->~YUtR2;Mq=i!TmL#|m_n%I4tR=H*o<})MD9==%whs!(5Q9pp;3{FH4
zkH~@e`+M(d0G^@@l@F>>go;3vfs#Q@0>F5}Y-TEbdNmdKL@*d3iY#0~ZA%3Bgf#T)
z?}lTaj`{+TJ=w&?H2eyku~<Ry@zY?BToc>tk`KvhtSm*~agZV$a8m6pw{UMi5-YDE
zgR2&rz}`<0zLJJw>chD^6q|O7;6N=U6smP9ebbtHs%m4^nU)m)B2g64X<clJtW;dI
zQl>d5ny89tB1niWSV>7vOtGd|nI%+IiVEW>R-&kc1i>;uLPT1?$eM<zii$OwHI!<|
zjo->*Qa=2z&k3bAPhrf3QE1Yh&Sxa_3J_lzBH5@!kWh)Td;7w*Tt7;EfcmhX%tUBd
zND(Mu5|ao417(piUzuGW03M)l3_Hvetk#byb7Cj54G!_6@p?8#pnE7eVk26FBtk(3
z6ucf!US@GSy4ahb10YC=-~L-Z6U&E$KIvF|;{Efz%8LLX0RmSrT$*8`RUDTn^Bf13
zk3OGNsM2&CE#lqo4H|4cKh}n7lb&8SdS=bbxa0{j2?>JOkTMPA_ebFNzRwM2dAkG;
zno1NYLy_ViG4hdnBP==17qsExb=7rAP(bz3>&zvHPRV{a93Y4`2y%CZk<W!8L?cBQ
zCE}~B`Rt1#ErY*PL)XnTGjbL13zjlHr-B9tU~o$wC0L}8DS~AshDibfl98w=ib@7j
zB82;|x@S}A-~fBs5c{6%5_{dEkqAH%voNqlO8IjdkVpuqh@wI7PnX>R(-SQ0Ph<JM
z4CgmyJ7x*)Phy<DjAX%V?|~roq|j3uL)`p2I3pD?A~;1X5iqJs$qSf<gR*t006Ce)
z=s$>VP&t~U5wLG6c{4Z@g)L&@<o64ro`lo5d}^k-RY&0=Vk(KRudw=y_ovhz^Rcus
z$|qXyAO}$psUaiqYQ6DMk(kkl=48T5W>GC+nM1G?lr13NEwVlTi+XKw%MOlBaqpjW
z@AgOC&f0A#fUDk5aecmGy-`BR#qxf9D<_a`df8C)3s##N)CN&eNN0!6d#$OD0VSTd
zbaw;aBaEe{h?yw_rqsl8LM3)F!O{jU0~x>KAEc7?pq~U4Ar))L8_r45<KS4ZCLo;f
zOh?2mBOt|`rN0yM)AkCRCqN)`hwA?~|37#9d4CW8e~<9}|HpaCPlzPl%|P<NUn>Yf
z2u|f7=Z+Vw!QmkZAdRzpICYboWi+U33aJ)NrH0%vixH4H5<ogd6Jzw7y*KU3*Tm^k
zXNScQzmaAA(+)M4a!?|guPxwd$(UtVElQV`e(D;jd;G`9Ts2l0G;ilfd@<XK|0twE
z>n^UJD&Ok)qq^wh(3P+|%8)`{%yda0qA?7>)@bwz2uEh4AG)1)A?h5a*4K>MK$in)
zS&M(Co8QBbhKz>gdea36zPK-wBGZ~|(qu$LeIJLp;o}qyZM(Q0gaODMpo6dAfDtt#
zN6qqQ5Y3S0pad2Vz&Rsd4NBnC<)r+S;#?%!!?m_dkg0_qlLG-tlT&ypi1}WCJJJSE
zzk!3{^kADHAAW6B$pG+xW+&qO+xofJo_mXZqwp1cue!vew|;Cj;-v=(-g;Hoq{^S_
z?KX;F5H1~Aj)NpTV-v?_ixgK_xq&|5;3}Jxx!Rgp<ZV3FL^h_G?Sq+Wk_2)1H^B7>
zXXei=xk6^8Y$-JGw<>~lNy(u}W-HKlN8ki?@|%Vi+If5|vZ&titNh7P7)11r{{8eA
zUFMLeOF2y;Eux7Sj1Io#J@Ld&{}KX*fQdk*2#Q|#B0_|NF;amMp<-GWQ@1xp1cT9)
zRGy+KMDv`z;)FQ7BdBkTOp=sg@cO$r7yNSq9a&}uJxF^4tjIb;nR0n}34nYcI&|rK
zft<9lJ)k64co8I170ePPukEnPT43r%lXiDe#EpXN+%HCqEknxDBd9S*14Q>p-c73E
zOcztaicQd`F)rE<O=by=G8SE?PP_x>p!@U3Y0_Z*;WuW8cdB}JUL338k-0%;CQWlS
z(mRMg4F?TL$R&l?$Wl9|2E?VzpcX+Wg(6LGV>qC4!*Ba2?tpy<w`Xc9kLXZYYvyKF
zK0c2@hmvvm#<|Ld1hTctUb7boy;MDBgvic35<teiThV%Q5bn=MRIC<y1n<R^lw$Z7
zvx}7hJ7zN(FvTpK!?!X(;;!}2P!TdR<TZDDW+$9xr&Th2o9*}6p|xl^xi?}ze+p$j
zlOcU=wwm`t%#Cl*-D{#19%3%0d8m|_qmXCqH5oh`;ojg>FI0^vp`$0A+`ZF?uHMYY
z!qC*GPGuG1Vh$~lP9`%3)Jja`u;RKih1ij1CkeM3Z+)g~Rl&@!Y_-HWO2WMy)N<q&
zN5NB{b<DA$t57OjFJ>QbTI~X`W?BX~h|5|S+elx5nJ$B7AjL8<K>Nih1G1Y4*DTx(
z4+F8Vt2DDo6%thSdzdg#+7gd;5u)HZO;rlVH3+1W;ZwE*tN`@<xFhtSe8Vu>V|yKH
z8lt9(_jAq#A;dF>kP+%12p1S&hLs6PK<@%TI}<_Ww0)+hzvbODhG&f*;El9mk`REh
zAefla1#t56p*dS-!;<koWEjFkr0&pl5<5J~Wm5DZY0{)Kj#L|)fE&P4Mk^wGqIO6G
zkRIe>W@_*KcEo-i?*lwa3doS;3Swtip{o#6LSqAJ3nmDP5IO<{pv_>J3qs&UYPE?m
zs}L$8MwD?foCjc__3wx}MI;D5A`BhW`RI{AZX|#Z$URX?K--rz{8i@%O?hq|umSTw
zf55{WUoIG=xfGO@kYCG*`u4!K#wGqc({Tp&Z;V2CU(p+cA<-O3x9R21r28_)9@Y@3
zvbWLWNO6%3n=mX1GqM_vU^V-Hq@m~DYicHukyex=^`15%tOl@lAY_kXs~ANEj{<l2
z9>NX;Bq1aop#xBN@BltT>=k$WS9ggc7j<aBIz;(9u8+aV-Z$Aer(47<yX=YRd`Ki=
zW?~4Ft`w<{GI9;H&@w>LK%RvpG8#dM`%<|JBy=i|BcFym_`@QKB+_gE{yI0kp(2?k
zK=glRs%8oXW5YMYs;YGa-lCXyVy5@4f?{xc{!;WZ72Q7D7l~1#0Dd$lF&+r9&SqP3
zwUDssB=nLVkZFC%uE>OfmP!?`>k9*5dk?ai--~&OV(OuB)M7QMNK{-#+@sNb|KTKZ
zF*JONMioRNQ#*+V*jy6Fze>BvgWNnGlgaG#;jb<X5zBz`RTV`N6AtcwXJxmykTPw;
z?x_N{{1oZw_5UP3(oo}sqlujUiqh<XPGFIP<I;PT_>dt>L=r}VfwCzO#U~&i5Og8j
zmk-Auh5G(m#PK#ikx%j|dbm0s_@}g<Y3_^FLIwcxpAd_;6*~RT(ANb%&&peU0jzre
zMYa=?`Xl<t@jE>oMi~?Bz;An{^2ziNbR`iFx}`$Imf1@5Qe2X?3r-2}{ZE%YFT?R?
zH}+%R?smNTv=}bY-@W2^@(9DuKQ`L>Fl+OW(k$RnCXuAyH)(ycJy~?ae1=yC-4u|z
zYb4grla@GQ658bYt}I}^YU-8^OS6<pv2uX(50_BwkHzwuI+8tK52HNl(tt2L!SL*R
zeLIg`_P)Lu1Fh83t%laYXj|6kRK%wyoZ%WK(z9p|20OPmR5s2<%@b|cuF{Q(l<W8@
z(MUY|6ZEfkKr;M>>Qjj4X{NUxn^q)&A%dP+Q;6`OPs6t}MXUqNB62$+uxNd&l*pZ&
z%=Xn>JkG(ynER{JJX^?u2q1k^zhW5&!3WmJpfj_TMQ!}4K(=zlo}Tl&rAUY}E1gJ;
z4QsOt=bB<M2QK2tStSw(<=<Q=PH9IleV`i%90!C=Wvq!3`*{lk7C@}Y@fd1I&_N~|
z)1)QVj5G^V5@-;H%5(YINT7|63|I<bXz6faxDk?j=~aM;q0>;*n3E}CK?^M;7zn!|
zY;Bcdq+}5~Y7=Yf_Z#&ccRUxlm>DC%$0b3<aK=|%%PNZjkOmV6yF%@Qx-}@?W>)8s
zg#Z{%43OwfNC&(LVgqjQeTq1wK!gP`4g)fF==119lYu7p5eQSev<wJgD3~yTc`Xt$
z3yFb~&Wp23Itg<eC@NH`U~Ig%4`dHa{V}L@deqnv@9&R!<a-$=lyY1eTxjDn3o2*P
zLo}gHDngG*XcMS=#(ZysAtD!3xjY1WBiq|zNB5d3^(R3RAQE@bwfy+_>}*-*Fb1Df
zo+SjFBZ#025&#u}>R#P#({N=}>CKVf(F3zCG{s@j2lTt~F)l*T>Pk=MxaP@FxXB<@
z)xyxaG!vJjwG{N8K)3CzLPhvei9|+~B}oKPBC3Rjr^F8Z5YP+-13)Q+1vGQ^r{qYc
zrY0KX0PLzARHfn|WV1^ON<s_<Cy9iz^WH0Oo*n>?nr{zQK#LuM0+kgrMGiX_%*Ds9
zyOI_srWce%{z+VTiLkt$iFRE?XF`&rfH)M$6J#t6GeD$C6bo%+Wr0%w0PNj{;wvGR
zGLQ-+1q)b!AThOwN>bEX<*>%kN`Ns`MPf)mVNzBUYYS@HR8c@kl_Z%5>HGJ$T669B
zx1Ao|x_>*-cn7#m_ln*&nOIO?92<n*4LhhznISkN*?d6h2#0!?tn4;O*$y9G^&a6f
zqExJL#~;wRl+h1)@HU89M3KB&N90F_#Iq1`;p^z&9S$wd(}~=HgAil3d6}}{bbDc*
z<)BF$3BiwpVdVL{P)}8<<d~HKM>>u#fz0a6Kud6eupxt%W5Lbh&9zJKn1i4=Z5d4j
zaS+;w$<ECmF?s1b@gxg&FtPj@fVO0f4Azvmr)*8>*Q4Xg?7@g%EMis$MuK3b8R#so
zXp$^D$a|^c@cKNA-S3~d<xGm4GeIViEc8rc7Y^9mONO3=>21f|yCQfpAaZ(yiXB4o
z<rSt|^0^p?siO-n&aJgEEe!x@lWu5O_Xl7dD}p+p7MlSf=k`@qWyn!EcOo2yCU|%$
z&Viy&*g+1=>Y8mzV-jOq!kOG7rd;Y3S;nLn43w*328_nZ9Tfc&dFrbAv9@W#0kyQJ
z;;)TVfK>ceS9b12pG@ypY1Jd_4+U^wNCu5^md8L_4_cH`Gd=UN*qf6{kwTQ<!rn@Q
zkGQew*wR|y=|Ex*^Y!nX7U?e2sGz0PIU$f+kg!J)1oYZ`)Zw%`+L*8pET*KIMle4s
z7lpEyGvtS*B|RB@Lf=2krCPChGC>HR3kTMbdX64C2DD<zpHG$y>!R_3L8X(xiG_pm
zsY<HE<U2*tDXy(Ww&d4R?U_^>deHX1g9NX(!u+SO$i%cl$qV3@*b}x3wOc6xJSf(R
z%+4`P&O=0dZHQ%j^$p<&HpzsCmL(xFly*CaVi=Nx2^=Hm-Sk~($2+PA=FC`o;=aj#
z59@~Z*|@<>vQ&pveKAs^7zI%kQ$|pB<AzyfrXs15U=(>*vLc+*+>OEM#P^fC9_2AR
zP}f#E!>%$9O~JcrrQ2ougxbx_KBNmlxm(3N%2#71ZR$#+3nEl#CMhv(NN6PprVAA4
zHK+=S9{e&U$e~h&w$LqXVOc>XvY?H=Y?NHKTWvlJz|zGJj@jaetc*Wi9;gyf>i{^b
z#-M2Y$4z$b4{W-s{B_87BlTwh=tZUP4-;eYgQ;^vlkzRyg12XSyY$@)l`wLKt>Q=&
z*z*u*cXtv(NRu|5Zxa`x$oGo1g+|hmS~6^ske#e2+{{ByKzx>;E;`RzXQ>E-qIP3A
zmS{}FWY#gu;gGgBqg}#N1k4uB7r6m7lw(WboX0rbPW_bD91Rda^^OrZW+=l;gf=Dc
z=s+fM^iTwd+dOVe1>7VRr132&Vh*Tk5<(JTBYwJj)_I3nB>NJ}n9~@-W+QoHD{fmO
z#IqSw)>|5T>5$gk#^w;oHv8=XJyuvqqO=y}%`x6Msf=7mvDa}{&N`N+LdIk~W~L4w
zYcA9<7E2Sxc&$L~YGPpJP>ZJ)!^1JPOoX77RV>FaT{|(A{h@ZiL3c$P9euH=JEx+;
zF3Txm?d<E~dD;%l8MBJ%ODQasl131dL<>u#0fZ1nU_3E{iDob{Df}i}eFErT4%R(!
zZ=157qM*Z?D{3*3!ZraQgi+)<*e)7rTWga-9obbw#1C~il9rR<CdG<n4$(to0l5OK
z!aABOa1$VI=IR+3AW&GKzzq{{SQaJ%6fpwO&@$}hUCu>%k;}S+lA0-s8-c|)BuBT$
z-dGVFbyJzvIP4+a1EkV)n51O3dhENfn2JS(8ryKSBIJP*jyE-|jBb>nv1&I<CZ`?j
zBE|S#86fX^QPrngttp8NVO(?vO%Rbt28iICgC{2}LL3NW5^y2LdQgQ#D9U~!l_G$J
zNK(?HsX~D_RHaaRWf0cm4eYS_P*FG}rCgfPK*ow9hd78*bT(Wfc9#+8xb<xbaJH5}
z$g)Uf7*iCXT7-&ayCiD0z_|mH{8zmL#v#3Qq)K2dL_AR6%}e~Wavg{Xj-K2f80tIE
zKf$-Sc&CwqV2PxlCMuAbiV9#-R{=D9v87F<9F*@FNf2P|iXsJ9Mu9?=QK0jKCa&^3
z?|Mx#8lrLt4d+63h0dpTG?!3MAgQC6WTe$4b_vr8WNLcfDM8>D6!hf><E8#1kxZY+
zR65^k0nJM7^&+nkRNW1sa4dutS>gbk0w2o&If!}T=aL>}GIdiuCu%={qzev_djs92
zzJq7;P*n0u`n<m3c66uYlgI%6g9>o`Y4hLN+w^zxHztALM?j01OO(i$9te}e*m=Zl
zJ81qSh0nZ?Pf<2UpvU%mFWzL5)F_^hTY-_odU@j}<euUrBY3VKS=;(^ApVqk4}nf8
zPPTFkibU-&(wN8^76$%{ID)U&BrD^QAH+wQ0otFIThEm9(Dr`1DyhfkE5eE@A1<KS
zWO)=HU876_#B3Z>$W#)UbR51cGD0Qvv5Hc#2o8)!kTm!#h7m7WC1`1(c3<d(QBy=s
z+$VOvDK?q|W#L1d6a+yORWb@`>G{2a2ee>z2b_Ds+^g?J0JHVQO%f=4Fq3Apv1mw1
zVmm<Tuja5kwoXH2LszB%(UE?VBtXAI1}-)2ZGi%gzwHO|pSv7W6;X&86=SRDE}5(_
zS4l(t5Xdr_Fh2NkhmsYD7-M%B9N#tsPQ>`o@E?d}Jy7cS$f+0r%VE%fBQC>JAFp<4
z@~5jP2e~a1e_=KY4jX$`*HwD3o@jN{hIEWH?QF(@so^YJ6Ay$ql^A9$myjJXuuVkF
zl#R|Ts&FTZqekYG1gTt0w1UI+fbiaQ9G#J19gyT<Cdtd?rar$Ve#3&Y2-c#Tz&{8s
z;CTj7Hcb+qiX!&zJ?RKZB=?`hwP)?Rg~Useq*PDC;ELN8peODU5l8wD={g@7^&hky
zr-MAJPbcu?E;TZiC@SqL`4fgZ7Rgc!Lja&_l0_t%lVm0Y)DJr<Lu8X$hw<+J@9mg@
ezwiD%Is@_~HSRlblT`=*;_gVN3K9#Kf=fV+qBXz(

literal 0
HcmV?d00001

diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig.patch b/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig.patch
new file mode 100644
index 0000000..52986e6
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig.patch
@@ -0,0 +1,471 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+enable standalone building of ldconfig
+
+---
+ cache.c        |   11 +-
+ chroot_canon.c |    7 +
+ dl-cache.c     |  235 ---------------------------------------------------------
+ dl-cache.h     |    3 
+ ldconfig.c     |   27 ++++--
+ readlib.c      |    7 +
+ xstrdup.c      |   11 --
+ 7 files changed, 45 insertions(+), 256 deletions(-)
+
+Index: ldconfig-native-2.12.1/cache.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/cache.c
++++ ldconfig-native-2.12.1/cache.c
+@@ -16,6 +16,9 @@
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
++#define _LARGEFILE64_SOURCE
++#define _GNU_SOURCE
++
+ #include <errno.h>
+ #include <error.h>
+ #include <dirent.h>
+@@ -31,8 +34,10 @@
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ 
+-#include <ldconfig.h>
+-#include <dl-cache.h>
++#include "ldconfig.h"
++#include "dl-cache.h"
++# define N_(msgid)  msgid
++#define _(msg) msg
+ 
+ struct cache_entry
+ {
+Index: ldconfig-native-2.12.1/chroot_canon.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/chroot_canon.c
++++ ldconfig-native-2.12.1/chroot_canon.c
+@@ -17,6 +17,9 @@
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
++#define _LARGEFILE64_SOURCE
++#define _GNU_SOURCE
++
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+@@ -27,7 +30,9 @@
+ #include <stddef.h>
+ #include <stdint.h>
+ 
+-#include <ldconfig.h>
++#include "ldconfig.h"
++
++#define __set_errno(Val) errno = (Val)
+ 
+ #ifndef PATH_MAX
+ #define PATH_MAX 1024
+Index: ldconfig-native-2.12.1/dl-cache.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/dl-cache.c
++++ ldconfig-native-2.12.1/dl-cache.c
+@@ -20,12 +20,12 @@
+ 
+ #include <assert.h>
+ #include <unistd.h>
+-#include <ldsodefs.h>
++//#include "ldsodefs.h"
+ #include <sys/mman.h>
+ #include <dl-cache.h>
+ #include <dl-procinfo.h>
+ 
+-#include <stdio-common/_itoa.h>
++//#include "_itoa.h"
+ 
+ #ifndef _DL_PLATFORMS_COUNT
+ # define _DL_PLATFORMS_COUNT 0
+@@ -39,103 +39,7 @@ static size_t cachesize;
+ /* 1 if cache_data + PTR points into the cache.  */
+ #define _dl_cache_verify_ptr(ptr) (ptr < cache_data_size)
+ 
+-#define SEARCH_CACHE(cache) \
+-/* We use binary search since the table is sorted in the cache file.	      \
+-   The first matching entry in the table is returned.			      \
+-   It is important to use the same algorithm as used while generating	      \
+-   the cache file.  */							      \
+-do									      \
+-  {									      \
+-    left = 0;								      \
+-    right = cache->nlibs - 1;						      \
+-									      \
+-    while (left <= right)						      \
+-      {									      \
+-	__typeof__ (cache->libs[0].key) key;				      \
+-									      \
+-	middle = (left + right) / 2;					      \
+-									      \
+-	key = cache->libs[middle].key;					      \
+-									      \
+-	/* Make sure string table indices are not bogus before using	      \
+-	   them.  */							      \
+-	if (! _dl_cache_verify_ptr (key))				      \
+-	  {								      \
+-	    cmpres = 1;							      \
+-	    break;							      \
+-	  }								      \
+-									      \
+-	/* Actually compare the entry with the key.  */			      \
+-	cmpres = _dl_cache_libcmp (name, cache_data + key);		      \
+-	if (__builtin_expect (cmpres == 0, 0))				      \
+-	  {								      \
+-	    /* Found it.  LEFT now marks the last entry for which we	      \
+-	       know the name is correct.  */				      \
+-	    left = middle;						      \
+-									      \
+-	    /* There might be entries with this name before the one we	      \
+-	       found.  So we have to find the beginning.  */		      \
+-	    while (middle > 0)						      \
+-	      {								      \
+-		__typeof__ (cache->libs[0].key) key;			      \
+-									      \
+-		key = cache->libs[middle - 1].key;			      \
+-		/* Make sure string table indices are not bogus before	      \
+-		   using them.  */					      \
+-		if (! _dl_cache_verify_ptr (key)			      \
+-		    /* Actually compare the entry.  */			      \
+-		    || _dl_cache_libcmp (name, cache_data + key) != 0)	      \
+-		  break;						      \
+-		--middle;						      \
+-	      }								      \
+-									      \
+-	    do								      \
+-	      {								      \
+-		int flags;						      \
+-		__typeof__ (cache->libs[0]) *lib = &cache->libs[middle];      \
+-									      \
+-		/* Only perform the name test if necessary.  */		      \
+-		if (middle > left					      \
+-		    /* We haven't seen this string so far.  Test whether the  \
+-		       index is ok and whether the name matches.  Otherwise   \
+-		       we are done.  */					      \
+-		    && (! _dl_cache_verify_ptr (lib->key)		      \
+-			|| (_dl_cache_libcmp (name, cache_data + lib->key)    \
+-			    != 0)))					      \
+-		  break;						      \
+-									      \
+-		flags = lib->flags;					      \
+-		if (_dl_cache_check_flags (flags)			      \
+-		    && _dl_cache_verify_ptr (lib->value))		      \
+-		  {							      \
+-		    if (best == NULL || flags == GLRO(dl_correct_cache_id))   \
+-		      {							      \
+-			HWCAP_CHECK;					      \
+-			best = cache_data + lib->value;			      \
+-									      \
+-			if (flags == GLRO(dl_correct_cache_id))		      \
+-			  /* We've found an exact match for the shared	      \
+-			     object and no general `ELF' release.  Stop	      \
+-			     searching.  */				      \
+-			  break;					      \
+-		      }							      \
+-		  }							      \
+-	      }								      \
+-	    while (++middle <= right);					      \
+-	    break;							      \
+-	}								      \
+-									      \
+-	if (cmpres < 0)							      \
+-	  left = middle + 1;						      \
+-	else								      \
+-	  right = middle - 1;						      \
+-      }									      \
+-  }									      \
+-while (0)
+-
+-
+ int
+-internal_function
+ _dl_cache_libcmp (const char *p1, const char *p2)
+ {
+   while (*p1 != '\0')
+@@ -172,139 +76,3 @@ _dl_cache_libcmp (const char *p1, const 
+     }
+   return *p1 - *p2;
+ }
+-
+-
+-/* Look up NAME in ld.so.cache and return the file name stored there,
+-   or null if none is found.  */
+-
+-const char *
+-internal_function
+-_dl_load_cache_lookup (const char *name)
+-{
+-  int left, right, middle;
+-  int cmpres;
+-  const char *cache_data;
+-  uint32_t cache_data_size;
+-  const char *best;
+-
+-  /* Print a message if the loading of libs is traced.  */
+-  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0))
+-    _dl_debug_printf (" search cache=%s\n", LD_SO_CACHE);
+-
+-  if (cache == NULL)
+-    {
+-      /* Read the contents of the file.  */
+-      void *file = _dl_sysdep_read_whole_file (LD_SO_CACHE, &cachesize,
+-					       PROT_READ);
+-
+-      /* We can handle three different cache file formats here:
+-	 - the old libc5/glibc2.0/2.1 format
+-	 - the old format with the new format in it
+-	 - only the new format
+-	 The following checks if the cache contains any of these formats.  */
+-      if (file != MAP_FAILED && cachesize > sizeof *cache
+-	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0)
+-	{
+-	  size_t offset;
+-	  /* Looks ok.  */
+-	  cache = file;
+-
+-	  /* Check for new version.  */
+-	  offset = ALIGN_CACHE (sizeof (struct cache_file)
+-				+ cache->nlibs * sizeof (struct file_entry));
+-
+-	  cache_new = (struct cache_file_new *) ((void *) cache + offset);
+-	  if (cachesize < (offset + sizeof (struct cache_file_new))
+-	      || memcmp (cache_new->magic, CACHEMAGIC_VERSION_NEW,
+-			 sizeof CACHEMAGIC_VERSION_NEW - 1) != 0)
+-	    cache_new = (void *) -1;
+-	}
+-      else if (file != MAP_FAILED && cachesize > sizeof *cache_new
+-	       && memcmp (file, CACHEMAGIC_VERSION_NEW,
+-			  sizeof CACHEMAGIC_VERSION_NEW - 1) == 0)
+-	{
+-	  cache_new = file;
+-	  cache = file;
+-	}
+-      else
+-	{
+-	  if (file != MAP_FAILED)
+-	    __munmap (file, cachesize);
+-	  cache = (void *) -1;
+-	}
+-
+-      assert (cache != NULL);
+-    }
+-
+-  if (cache == (void *) -1)
+-    /* Previously looked for the cache file and didn't find it.  */
+-    return NULL;
+-
+-  best = NULL;
+-
+-  if (cache_new != (void *) -1)
+-    {
+-      uint64_t platform;
+-
+-      /* This is where the strings start.  */
+-      cache_data = (const char *) cache_new;
+-
+-      /* Now we can compute how large the string table is.  */
+-      cache_data_size = (const char *) cache + cachesize - cache_data;
+-
+-      platform = _dl_string_platform (GLRO(dl_platform));
+-      if (platform != (uint64_t) -1)
+-	platform = 1ULL << platform;
+-
+-#define _DL_HWCAP_TLS_MASK (1LL << 63)
+-      uint64_t hwcap_exclude = ~((GLRO(dl_hwcap) & GLRO(dl_hwcap_mask))
+-				 | _DL_HWCAP_PLATFORM | _DL_HWCAP_TLS_MASK);
+-
+-      /* Only accept hwcap if it's for the right platform.  */
+-#define HWCAP_CHECK \
+-      if (lib->hwcap & hwcap_exclude)					      \
+-	continue;							      \
+-      if (GLRO(dl_osversion) && lib->osversion > GLRO(dl_osversion))	      \
+-	continue;							      \
+-      if (_DL_PLATFORMS_COUNT						      \
+-	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0			      \
+-	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform)		      \
+-	continue
+-      SEARCH_CACHE (cache_new);
+-    }
+-  else
+-    {
+-      /* This is where the strings start.  */
+-      cache_data = (const char *) &cache->libs[cache->nlibs];
+-
+-      /* Now we can compute how large the string table is.  */
+-      cache_data_size = (const char *) cache + cachesize - cache_data;
+-
+-#undef HWCAP_CHECK
+-#define HWCAP_CHECK do {} while (0)
+-      SEARCH_CACHE (cache);
+-    }
+-
+-  /* Print our result if wanted.  */
+-  if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_LIBS, 0)
+-      && best != NULL)
+-    _dl_debug_printf ("  trying file=%s\n", best);
+-
+-  return best;
+-}
+-
+-#ifndef MAP_COPY
+-/* If the system does not support MAP_COPY we cannot leave the file open
+-   all the time since this would create problems when the file is replaced.
+-   Therefore we provide this function to close the file and open it again
+-   once needed.  */
+-void
+-_dl_unload_cache (void)
+-{
+-  if (cache != NULL && cache != (struct cache_file *) -1)
+-    {
+-      __munmap (cache, cachesize);
+-      cache = NULL;
+-    }
+-}
+-#endif
+Index: ldconfig-native-2.12.1/dl-cache.h
+===================================================================
+--- ldconfig-native-2.12.1.orig/dl-cache.h
++++ ldconfig-native-2.12.1/dl-cache.h
+@@ -101,5 +101,4 @@ struct cache_file_new
+ (((addr) + __alignof__ (struct cache_file_new) -1)	\
+  & (~(__alignof__ (struct cache_file_new) - 1)))
+ 
+-extern int _dl_cache_libcmp (const char *p1, const char *p2)
+-     internal_function;
++extern int _dl_cache_libcmp (const char *p1, const char *p2);
+Index: ldconfig-native-2.12.1/ldconfig.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/ldconfig.c
++++ ldconfig-native-2.12.1/ldconfig.c
+@@ -16,6 +16,9 @@
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
++#define _LARGEFILE64_SOURCE
++#define _GNU_SOURCE
++
+ #define PROCINFO_CLASS static
+ #include <alloca.h>
+ #include <argp.h>
+@@ -39,10 +42,20 @@
+ #include <glob.h>
+ #include <libgen.h>
+ 
+-#include <ldconfig.h>
+-#include <dl-cache.h>
++#include "ldconfig.h"
++#include "dl-cache.h"
++
++#include "dl-procinfo.h"
++
++#include "argp.h"
++
++
++#define SYSCONFDIR "/etc"
++#define LIBDIR "/usr/lib"
++#define SLIBDIR "/lib"
++# define N_(msgid)  msgid
++#define _(msg) msg
+ 
+-#include <dl-procinfo.h>
+ 
+ #ifdef _DL_FIRST_PLATFORM
+ # define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
+@@ -55,7 +68,7 @@
+ #endif
+ 
+ /* Get libc version number.  */
+-#include <version.h>
++#include "version.h"
+ 
+ #define PACKAGE _libc_intl_domainname
+ 
+@@ -152,8 +165,8 @@ static const struct argp_option options[
+   { NULL, 0, NULL, 0, NULL, 0 }
+ };
+ 
+-#define PROCINFO_CLASS static
+-#include <dl-procinfo.c>
++//#define PROCINFO_CLASS static
++//#include <dl-procinfo.c>
+ 
+ /* Short description of program.  */
+ static const char doc[] = N_("Configure Dynamic Linker Run Time Bindings.");
+@@ -291,6 +304,7 @@ parse_opt (int key, char *arg, struct ar
+   return 0;
+ }
+ 
++#define REPORT_BUGS_TO "mailing list : poky@yoctoproject.org"
+ /* Print bug-reporting information in the help message.  */
+ static char *
+ more_help (int key, const char *text, void *input)
+@@ -315,7 +329,7 @@ For bug reporting instructions, please s
+ static void
+ print_version (FILE *stream, struct argp_state *state)
+ {
+-  fprintf (stream, "ldconfig %s%s\n", PKGVERSION, VERSION);
++  fprintf (stream, "ldconfig (Hacked Poky Version)\n");
+   fprintf (stream, gettext ("\
+ Copyright (C) %s Free Software Foundation, Inc.\n\
+ This is free software; see the source for copying conditions.  There is NO\n\
+@@ -1233,6 +1247,7 @@ set_hwcap (void)
+     hwcap_mask = strtoul (mask, NULL, 0);
+ }
+ 
++const char _libc_intl_domainname[] = "libc";
+ 
+ int
+ main (int argc, char **argv)
+Index: ldconfig-native-2.12.1/readlib.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/readlib.c
++++ ldconfig-native-2.12.1/readlib.c
+@@ -22,6 +22,9 @@
+    development version.  Besides the simplification, it has also been
+    modified to read some other file formats.  */
+ 
++#define _LARGEFILE64_SOURCE
++#define _GNU_SOURCE
++
+ #include <a.out.h>
+ #include <elf.h>
+ #include <error.h>
+@@ -35,7 +38,9 @@
+ #include <sys/stat.h>
+ #include <gnu/lib-names.h>
+ 
+-#include <ldconfig.h>
++#include "ldconfig.h"
++
++#define _(msg) msg
+ 
+ #define Elf32_CLASS ELFCLASS32
+ #define Elf64_CLASS ELFCLASS64
+Index: ldconfig-native-2.12.1/xstrdup.c
+===================================================================
+--- ldconfig-native-2.12.1.orig/xstrdup.c
++++ ldconfig-native-2.12.1/xstrdup.c
+@@ -16,15 +16,10 @@
+    along with this program; if not, write to the Free Software Foundation,
+    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
+-#ifdef HAVE_CONFIG_H
+-# include <config.h>
+-#endif
++#define _GNU_SOURCE
++
++#include <string.h>
+ 
+-#if defined STDC_HEADERS || defined HAVE_STRING_H || _LIBC
+-# include <string.h>
+-#else
+-# include <strings.h>
+-#endif
+ void *xmalloc (size_t n) __THROW;
+ char *xstrdup (char *string) __THROW;
+ 
diff --git a/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig_aux-cache_path_fix.patch b/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig_aux-cache_path_fix.patch
new file mode 100644
index 0000000..27bc411
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native-2.12.1/ldconfig_aux-cache_path_fix.patch
@@ -0,0 +1,36 @@
+Upstream-Status: Pending
+
+Coming from this bug: http://sourceware.org/bugzilla/show_bug.cgi?id=11149
+
+Nitin A Kamble <nitin.a.kamble@intel.com>2011/03/29
+
+--- ldconfig-native-2.12.1.orig/ldconfig.c	
++++ ldconfig-native-2.12.1/ldconfig.c	
+@@ -1359,14 +1359,9 @@ main (int argc, char **argv)
+ 
+   const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
+   if (opt_chroot)
+-    {
+-      aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
+-      if (aux_cache_file == NULL)
+-	error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
+-	       _PATH_LDCONFIG_AUX_CACHE);
+-    }
++    aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
+ 
+-  if (! opt_ignore_aux_cache)
++  if (! opt_ignore_aux_cache && aux_cache_file)
+     load_aux_cache (aux_cache_file);
+   else
+     init_aux_cache ();
+@@ -1376,7 +1371,8 @@ main (int argc, char **argv)
+   if (opt_build_cache)
+     {
+       save_cache (cache_file);
+-      save_aux_cache (aux_cache_file);
++      if (aux_cache_file)
++        save_aux_cache (aux_cache_file);
+     }
+ 
+   return 0;
+
diff --git a/recipes-core/glibc/ldconfig-native_2.12.1.bb b/recipes-core/glibc/ldconfig-native_2.12.1.bb
new file mode 100644
index 0000000..1debf8e
--- /dev/null
+++ b/recipes-core/glibc/ldconfig-native_2.12.1.bb
@@ -0,0 +1,33 @@
+SUMMARY = "A standalone native ldconfig build"
+
+LICENSE = "GPLv2+"
+
+LIC_FILES_CHKSUM = "file://${S}/ldconfig.c;endline=17;md5=1d15f20937c055cb5de2329a4c054399"
+
+SRC_URI = "file://ldconfig-native-2.12.1.tar.bz2 \
+           file://ldconfig.patch \
+           file://ldconfig_aux-cache_path_fix.patch \
+           file://32and64bit.patch \
+           file://endian-ness_handling.patch \
+           file://flag_fix.patch \
+           file://endianess-header.patch \
+           file://ldconfig-default-to-all-multilib-dirs.patch \
+           file://endian-ness_handling_fix.patch \
+"
+
+PR = "r2"
+
+FILESEXTRAPATHS =. "${FILE_DIRNAME}/${P}:"
+
+inherit native
+
+S = "${WORKDIR}/${PN}-${PV}"
+
+do_compile () {
+	$CC ldconfig.c -std=gnu99 chroot_canon.c xmalloc.c xstrdup.c cache.c readlib.c  -I. dl-cache.c -o ldconfig
+}
+
+do_install () {
+	install -d ${D}/${bindir}/
+	install ldconfig ${D}/${bindir}/
+}
diff --git a/recipes-core/glibc/site_config/funcs b/recipes-core/glibc/site_config/funcs
new file mode 100644
index 0000000..ccc8539
--- /dev/null
+++ b/recipes-core/glibc/site_config/funcs
@@ -0,0 +1,474 @@
+a64l
+abs
+access
+__adjtimex
+alarm
+alphasort
+argz_append
+__argz_count
+argz_create_sep
+argz_insert
+__argz_next
+argz_next
+__argz_stringify
+argz_stringify
+asprintf
+atexit
+atof
+atoi
+bcmp
+bcopy
+bindresvport
+bind_textdomain_codeset
+btowc
+bzero
+calloc
+canonicalize_file_name
+catgets
+cfgetospeed
+cfsetispeed
+cfsetspeed
+chmod
+chown
+chroot
+clock
+close
+closedir
+closelog
+confstr
+connect
+daemon
+dcgettext
+difftime
+dirfd
+dirname
+dngettext
+dup2
+ecvt
+endgrent
+endmntent
+endpwent
+endutent
+endutxent
+epoll_ctl
+err
+ether_hostton
+ether_ntohost
+euidaccess
+execv
+fchdir
+fchmod
+fchmodat
+fchown
+fchownat
+fcntl
+fcvt
+fdatasync
+fdopendir
+feof_unlocked
+fgets_unlocked
+fgetxattr
+finite
+flistxattr
+flock
+flockfile
+fnmatch
+fork
+fpathconf
+__fpending
+fprintf
+free
+freeaddrinfo
+freeifaddrs
+fseeko
+__fsetlocking
+fsetxattr
+fstat64
+fstat
+fstatfs
+fsync
+ftello
+ftime
+ftruncate
+funlockfile
+futimes
+futimesat
+gai_strerror
+gcvt
+getaddrinfo
+getc_unlocked
+getcwd
+getdelim
+getdomainname
+getdtablesize
+getegid
+getenv
+geteuid
+getgid
+getgrent
+getgrent_r
+getgrgid_r
+getgrnam
+getgrnam_r
+getgrouplist
+getgroups
+gethostbyaddr_r
+gethostbyname2
+gethostbyname
+gethostbyname_r
+gethostent
+gethostid
+gethostname
+getifaddrs
+getline
+getloadavg
+getmntent
+getmsg
+getnameinfo
+getnetbyaddr_r
+getnetgrent_r
+getopt
+getopt_long
+getopt_long_only
+getpagesize
+getpass
+getpeername
+getpgrp
+getpid
+getppid
+getprotoent_r
+getpwent
+getpwent_r
+getpwnam
+getpwnam_r
+getpwuid
+getpwuid_r
+getresuid
+getrlimit
+getrusage
+getservbyname
+getservbyname_r
+getservbyport_r
+getservent
+getservent_r
+getspnam
+getspnam_r
+gettimeofday
+getttyent
+getttynam
+getuid
+getusershell
+getutent
+getutid
+getutline
+getutmp
+getutmpx
+getutxent
+getutxid
+getutxline
+getwd
+getxattr
+glob
+gmtime
+gmtime_r
+grantpt
+group_member
+herror
+hstrerror
+iconv
+iconv_open
+if_freenameindex
+if_indextoname
+if_nameindex
+if_nametoindex
+index
+inet_addr
+inet_aton
+inet_ntoa
+inet_ntop
+inet_pton
+initgroups
+innetgr
+iruserok
+isascii
+isatty
+isblank
+isgraph
+isinf
+isnan
+isprint
+isspace
+iswalnum
+iswcntrl
+iswctype
+iswprint
+iswspace
+iswupper
+isxdigit
+kill
+killpg
+lchown
+lckpwdf
+lgetxattr
+link
+listxattr
+llistxattr
+localtime
+localtime_r
+lockf
+lrand48
+lsearch
+lseek64
+lsetxattr
+lstat
+mallinfo
+malloc
+mblen
+mbrlen
+mbrtowc
+mbsinit
+mbsrtowcs
+mbtowc
+memalign
+memchr
+memcmp
+memcpy
+memmove
+mempcpy
+memrchr
+memset
+mkdir
+mkdirat
+mkdtemp
+mkfifo
+mknod
+mkstemp64
+mkstemp
+mktime
+mlock
+mmap
+mtrace
+munlock
+munmap
+nanosleep
+nice
+nl_langinfo
+ntp_adjtime
+ntp_gettime
+_obstack_free
+on_exit
+open64
+open
+openat
+opendir
+openlog
+pathconf
+pipe
+poll
+popen
+posix_memalign
+prctl
+pread
+printf
+__progname
+pselect
+pthread_mutex_lock
+ptsname
+putenv
+putgrent
+putpwent
+putspent
+pututline
+pututxline
+putwc
+pwrite
+qsort
+raise
+rand
+random
+rand_r
+read
+readdir
+readdir_r
+readlink
+realloc
+realpath
+re_comp
+recvmsg
+re_exec
+regcomp
+regexec
+remove
+rename
+re_search
+rmdir
+rpmatch
+rresvport_af
+ruserok
+ruserok_af
+sbrk
+scandir
+sched_setscheduler
+sched_yield
+__secure_getenv
+select
+semctl
+semget
+sendmsg
+setbuf
+setbuffer
+setegid
+setenv
+seteuid
+setgid
+setgroups
+sethostname
+setitimer
+_setjmp
+setjmp
+setlinebuf
+setlocale
+setmntent
+setpgid
+setpgrp
+setpriority
+setregid
+setresgid
+setresuid
+setreuid
+setrlimit
+setsid
+setsockopt
+settimeofday
+setuid
+setutent
+setutxent
+setvbuf
+setxattr
+sgetspent
+shmat
+shmctl
+shmdt
+shmget
+shutdown
+sigaction
+sigaddset
+sigaltstack
+sigblock
+sigemptyset
+sighold
+siginterrupt
+signal
+sigprocmask
+sigset
+sigsetmask
+sigstack
+sigsuspend
+sigvec
+snprintf
+socket
+socketpair
+sprintf
+srand48
+srand
+srandom
+sscanf
+stat
+statfs
+statvfs
+stime
+stpcpy
+strcasecmp
+strcasestr
+strchr
+strchrnul
+strcmp
+strcspn
+strdup
+strerror
+strerror_r
+strftime
+strlen
+strncasecmp
+strncmp
+strndup
+strnlen
+strpbrk
+strptime
+strrchr
+strsep
+strsignal
+strspn
+strstr
+strtod
+strtoimax
+strtok_r
+strtol
+strtoll
+strtoul
+strtoull
+strtoumax
+strverscmp
+strxfrm
+symlink
+sync
+sysconf
+sysctl
+sysinfo
+syslog
+_sys_siglist
+sys_siglist
+system
+tcgetattr
+tcgetpgrp
+tcsetattr
+tcsetpgrp
+time
+timegm
+times
+timezone
+tmpnam
+towlower
+towupper
+truncate
+tsearch
+ttyname
+tzset
+ulimit
+umask
+uname
+unlink
+unsetenv
+unshare
+updwtmp
+updwtmpx
+usleep
+ustat
+utime
+utimes
+utmpname
+utmpxname
+valloc
+vasprintf
+verrx
+vfork
+vfprintf
+vfscanf
+vhangup
+vprintf
+vsnprintf
+vsprintf
+wait3
+wait4
+waitpid
+wcrtomb
+wcscoll
+wcsdup
+wcslen
+wctob
+wctomb
+wctype
+wcwidth
+wmemchr
+wmemcpy
+wmempcpy
diff --git a/recipes-core/glibc/site_config/headers b/recipes-core/glibc/site_config/headers
new file mode 100644
index 0000000..609ab53
--- /dev/null
+++ b/recipes-core/glibc/site_config/headers
@@ -0,0 +1,156 @@
+aio.h
+alloca.h
+argz.h
+arpa/inet.h
+arpa/nameser.h
+asm/byteorder.h
+asm/ioctls.h
+asm/page.h
+asm/types.h
+assert.h
+byteswap.h
+crypt.h
+ctype.h
+dirent.h
+dlfcn.h
+elf.h
+endian.h
+err.h
+errno.h
+execinfo.h
+fcntl.h
+features.h
+float.h
+fstab.h
+ftw.h
+getopt.h
+glob.h
+grp.h
+iconv.h
+ifaddrs.h
+inttypes.h
+langinfo.h
+lastlog.h
+libgen.h
+libintl.h
+limits.h
+linux/capability.h
+linux/fd.h
+linux/fs.h
+linux/hayesesp.h
+linux/hdreg.h
+linux/icmp.h
+linux/in6.h
+linux/joystick.h
+linux/ptrace.h
+linux/serial.h
+linux/sonypi.h
+linux/unistd.h
+linux/utsname.h
+linux/version.h
+locale.h
+malloc.h
+math.h
+mcheck.h
+memory.h
+mntent.h
+mqueue.h
+netdb.h
+net/if.h
+netinet/ether.h
+netinet/in.h
+netinet/ip6.h
+netinet/ip.h
+netinet/tcp.h
+netinet/udp.h
+netipx/ipx.h
+net/route.h
+paths.h
+poll.h
+pthread.h
+pty.h
+pwd.h
+regex.h
+resolv.h
+rpc/rpc.h
+rpc/types.h
+sched.h
+scsi/scsi.h
+search.h
+semaphore.h
+setjmp.h
+sgtty.h
+shadow.h
+signal.h
+stdarg.h
+stdbool.h
+stdc
+stddef.h
+stdint.h
+stdio.h
+stdlib.h
+string.h
+strings.h
+stropts.h
+sys/bitypes.h
+sys/cdefs.h
+sys/dir.h
+sys/epoll.h
+sysexits.h
+sys/fcntl.h
+sys/file.h
+sys/fsuid.h
+sys/ioctl.h
+sys/ipc.h
+syslog.h
+sys/mman.h
+sys/mount.h
+sys/mtio.h
+sys/param.h
+sys/poll.h
+sys/prctl.h
+sys/ptrace.h
+sys/queue.h
+sys/reg.h
+sys/resource.h
+sys/select.h
+sys/sem.h
+sys/shm.h
+sys/signal.h
+sys/socket.h
+sys/socketvar.h
+sys/soundcard.h
+sys/statfs.h
+sys/stat.h
+sys/statvfs.h
+sys/stropts.h
+sys/swap.h
+sys/sysctl.h
+sys/sysinfo.h
+sys/sysmacros.h
+sys/termios.h
+sys/timeb.h
+sys/time.h
+sys/times.h
+sys/timex.h
+sys/types.h
+sys/uio.h
+sys/un.h
+sys/unistd.h
+sys/user.h
+sys/utsname.h
+sys/vfs.h
+sys/wait.h
+termio.h
+termios.h
+time.h
+ttyent.h
+ulimit.h
+unistd.h
+ustat.h
+utime.h
+utmp.h
+utmpx.h
+values.h
+wchar.h
+wctype.h
diff --git a/recipes-core/glibc/site_config/types b/recipes-core/glibc/site_config/types
new file mode 100644
index 0000000..178bd85
--- /dev/null
+++ b/recipes-core/glibc/site_config/types
@@ -0,0 +1,21 @@
+char
+char *
+double
+float
+int
+long
+long double
+long int
+long long
+long long int
+short
+short int
+signed char
+unsigned char
+unsigned int
+unsigned long
+unsigned long int
+unsigned long long int
+unsigned short
+unsigned short int
+void *
-- 
1.9.0



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/18] e500v2.inc: add recipe
  2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
                   ` (16 preceding siblings ...)
  2017-12-28 10:05 ` [PATCH 09/18] glibc : add 2.20 version Chunrong Guo
@ 2018-01-04 14:33 ` Bob Cochran
  2018-01-05  2:58   ` Zhenhua Luo
  17 siblings, 1 reply; 22+ messages in thread
From: Bob Cochran @ 2018-01-04 14:33 UTC (permalink / raw)
  To: meta-freescale

On 12/28/2017 05:04 AM, Chunrong Guo wrote:
> From: Chunrong Guo <chunrong.guo@nxp.com>
>
> Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
> ---
>   conf/machine/include/e500v2.inc | 4 ++++
>   1 file changed, 4 insertions(+)
>   create mode 100644 conf/machine/include/e500v2.inc
>
> diff --git a/conf/machine/include/e500v2.inc b/conf/machine/include/e500v2.inc
> new file mode 100644
> index 0000000..420f034
> --- /dev/null
> +++ b/conf/machine/include/e500v2.inc
> @@ -0,0 +1,4 @@
> +require conf/machine/include/tune-ppce500v2.inc
> +
> +MACHINEOVERRIDES =. "e500v2:"
> +require conf/machine/include/qoriq-ppc.inc

Hi Chunrong,

Can you please explain what's going on with PPC and Yocto?  It was just 
a few months back when all PPC was removed from meta-freescale.

https://github.com/Freescale/meta-freescale/commit/86e2ed54cd60da4f9f427baf6dbefbc9911141e6

https://www.mail-archive.com/meta-freescale@yoctoproject.org/msg20572.html

Thank you,

Bob




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 01/18] e500v2.inc: add recipe
  2018-01-04 14:33 ` [PATCH 01/18] e500v2.inc: add recipe Bob Cochran
@ 2018-01-05  2:58   ` Zhenhua Luo
  0 siblings, 0 replies; 22+ messages in thread
From: Zhenhua Luo @ 2018-01-05  2:58 UTC (permalink / raw)
  To: Bob Cochran; +Cc: meta-freescale

Hi Bob, 

As you know, LSDK (Layerscape SDK) replaced the QSDK (QorIQ PPC, ARM SDK) in last June. In 17.06, 17.09 and 19.09-update releases, ARM targets are integrated continuously, PPC was not supported, to align with the scope of LSDK, we removed the PPC machines from Yocto. In recent LSDK 17.12 release, the PPC support was integrated, accordingly we add back the PPC machines in Yocto. 

Hope the clarification is helpful for your understanding. 


Best Regards, 

Zhenhua

> -----Original Message-----
> From: meta-freescale-bounces@yoctoproject.org [mailto:meta-freescale-
> bounces@yoctoproject.org] On Behalf Of Bob Cochran
> Sent: Thursday, January 04, 2018 10:34 PM
> To: meta-freescale@yoctoproject.org
> Subject: Re: [meta-freescale] [PATCH 01/18] e500v2.inc: add recipe
> 
> On 12/28/2017 05:04 AM, Chunrong Guo wrote:
> > From: Chunrong Guo <chunrong.guo@nxp.com>
> >
> > Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
> > ---
> >   conf/machine/include/e500v2.inc | 4 ++++
> >   1 file changed, 4 insertions(+)
> >   create mode 100644 conf/machine/include/e500v2.inc
> >
> > diff --git a/conf/machine/include/e500v2.inc
> > b/conf/machine/include/e500v2.inc new file mode 100644 index
> > 0000000..420f034
> > --- /dev/null
> > +++ b/conf/machine/include/e500v2.inc
> > @@ -0,0 +1,4 @@
> > +require conf/machine/include/tune-ppce500v2.inc
> > +
> > +MACHINEOVERRIDES =. "e500v2:"
> > +require conf/machine/include/qoriq-ppc.inc
> 
> Hi Chunrong,
> 
> Can you please explain what's going on with PPC and Yocto?  It was just a few
> months back when all PPC was removed from meta-freescale.
> 
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.
> com%2FFreescale%2Fmeta-
> freescale%2Fcommit%2F86e2ed54cd60da4f9f427baf6dbefbc9911141e6&data=
> 02%7C01%7Czhenhua.luo%40nxp.com%7Ca70e1d6b7af14890ddf608d55388061
> c%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63650676606203192
> 2&sdata=yQBXd5QneevJ9WviBcHVl8MUa%2Fqxlv3FxeU38s5WkQc%3D&reserve
> d=0
> 
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.
> mail-archive.com%2Fmeta-
> freescale%40yoctoproject.org%2Fmsg20572.html&data=02%7C01%7Czhenhua.
> luo%40nxp.com%7Ca70e1d6b7af14890ddf608d55388061c%7C686ea1d3bc2b4c
> 6fa92cd99c5c301635%7C0%7C0%7C636506766062031922&sdata=MbTvkYGFXy
> e8344kXUsEZytQgIyLeslteg6I8rFpBgk%3D&reserved=0
> 
> Thank you,
> 
> Bob
> 
> 
> --
> _______________________________________________
> meta-freescale mailing list
> meta-freescale@yoctoproject.org
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.yo
> ctoproject.org%2Flistinfo%2Fmeta-
> freescale&data=02%7C01%7Czhenhua.luo%40nxp.com%7Ca70e1d6b7af14890d
> df608d55388061c%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636
> 506766062031922&sdata=%2BCj52zbWWQv8gHyA5cRA8hAdORrZR6YORGKcHD
> lKpXA%3D&reserved=0

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 10/18] binutils: add 2.25 version
  2017-12-28 10:05 ` [PATCH 10/18] binutils: add 2.25 version Chunrong Guo
@ 2018-01-12 16:32   ` Otavio Salvador
  0 siblings, 0 replies; 22+ messages in thread
From: Otavio Salvador @ 2018-01-12 16:32 UTC (permalink / raw)
  To: Chunrong Guo; +Cc: meta-freescale, Chunrong Guo

On Thu, Dec 28, 2017 at 8:04 AM, Chunrong Guo <B40290@freescale.com> wrote:
> From: Chunrong Guo <chunrong.guo@nxp.com>
>
> *ppc machine only  support binutils 2.25 version
>
> Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>

We are not going to fork OE-Core and maintain a toolchain. You should
fix the build with the newer toolchain instead.

-- 
Otavio Salvador                             O.S. Systems
http://www.ossystems.com.br        http://code.ossystems.com.br
Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 02/18] qoriq-ppc.inc: add recipes
  2017-12-28 10:04 ` [PATCH 02/18] qoriq-ppc.inc: add recipes Chunrong Guo
@ 2018-01-12 16:39   ` Otavio Salvador
  0 siblings, 0 replies; 22+ messages in thread
From: Otavio Salvador @ 2018-01-12 16:39 UTC (permalink / raw)
  To: Chunrong Guo; +Cc: meta-freescale, Chunrong Guo

On Thu, Dec 28, 2017 at 8:04 AM, Chunrong Guo <B40290@freescale.com> wrote:
> From: Chunrong Guo <chunrong.guo@nxp.com>
>
> Signed-off-by: Chunrong Guo <chunrong.guo@nxp.com>
> ---
>  conf/machine/include/qoriq-ppc.inc | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>  create mode 100644 conf/machine/include/qoriq-ppc.inc
>
> diff --git a/conf/machine/include/qoriq-ppc.inc b/conf/machine/include/qoriq-ppc.inc
> new file mode 100644
> index 0000000..d2e4782
> --- /dev/null
> +++ b/conf/machine/include/qoriq-ppc.inc
> @@ -0,0 +1,15 @@
> +# Provides the common settings for QorIQ PPC
> +
> +KERNEL_IMAGETYPE ?= "uImage"
> +
> +SERIAL_CONSOLES ?= "115200;ttyS0 115200;ttyS1 115200;ttyEHV0"
> +SERIAL_CONSOLES_CHECK ?= "${SERIAL_CONSOLES}"
> +
> +MACHINEOVERRIDES =. "qoriq-ppc:"
> +
> +require conf/machine/include/qoriq-base.inc
> +
> +GCCVERSION_qoriq-ppc = "4.9.2"
> +BINUVERSION_qoriq-ppc = "2.25"
> +GLIBCVERSION_qoriq-ppc = "2.20"

The inclusion of PPC must be done using the current toolchain as this
is a BSP layer and not a OE-Core fork or a full bloat build system.

> +PREFERRED_VERSION_virtual/nativesdk-libiconv = "2.20"
> --
> 1.9.0
>
> --
> _______________________________________________
> meta-freescale mailing list
> meta-freescale@yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-freescale



-- 
Otavio Salvador                             O.S. Systems
http://www.ossystems.com.br        http://code.ossystems.com.br
Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2018-01-12 16:39 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-28 10:04 [PATCH 01/18] e500v2.inc: add recipe Chunrong Guo
2017-12-28 10:04 ` [PATCH 02/18] qoriq-ppc.inc: add recipes Chunrong Guo
2018-01-12 16:39   ` Otavio Salvador
2017-12-28 10:04 ` [PATCH 03/18] e5500.inc: " Chunrong Guo
2017-12-28 10:04 ` [PATCH 04/18] e5500-64b.inc: " Chunrong Guo
2017-12-28 10:04 ` [PATCH 05/18] mpc8548cds: add machine conf Chunrong Guo
2017-12-28 10:04 ` [PATCH 06/18] p2020rdb: " Chunrong Guo
2017-12-28 10:04 ` [PATCH 07/18] t1042d4rdb-64b: add machine config Chunrong Guo
2017-12-28 10:04 ` [PATCH 08/18] t1042d4rdb: " Chunrong Guo
2017-12-28 10:04 ` [PATCH 12/18] cloog: add recipes Chunrong Guo
2017-12-28 10:04 ` [PATCH 13/18] isl:add recipes Chunrong Guo
2017-12-28 10:04 ` [PATCH 14/18] testfloat: update recipes Chunrong Guo
2017-12-28 10:04 ` [PATCH 15/18] sysklogd: update e500v2 patch Chunrong Guo
2017-12-28 10:04 ` [PATCH 16/18] diffutils: remove improper patch for qoriq-ppc Chunrong Guo
2017-12-28 10:04 ` [PATCH 17/18] hyperrelay: skip ldflags check Chunrong Guo
2017-12-28 10:04 ` [PATCH 18/18] qe-ucode: support t1042 Chunrong Guo
2017-12-28 10:05 ` [PATCH 10/18] binutils: add 2.25 version Chunrong Guo
2018-01-12 16:32   ` Otavio Salvador
2017-12-28 10:05 ` [PATCH 11/18] gcc : add 4.9 version Chunrong Guo
2017-12-28 10:05 ` [PATCH 09/18] glibc : add 2.20 version Chunrong Guo
2018-01-04 14:33 ` [PATCH 01/18] e500v2.inc: add recipe Bob Cochran
2018-01-05  2:58   ` Zhenhua Luo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.