public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/ruby-scripts:master commit in: patchsets/patches-ee-1.8.7-2010.02-r1/
@ 2011-05-15  6:24 Hans de Graaff
  0 siblings, 0 replies; only message in thread
From: Hans de Graaff @ 2011-05-15  6:24 UTC (permalink / raw
  To: gentoo-commits

commit:     a0da514e1682ea6ad1bd1ebca9c4b95a8625f4e6
Author:     Hans de Graaff <hans <AT> degraaff <DOT> org>
AuthorDate: Sun May 15 06:24:04 2011 +0000
Commit:     Hans de Graaff <graaff <AT> gentoo <DOT> org>
CommitDate: Sun May 15 06:24:04 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/ruby-scripts.git;a=commit;h=a0da514e

Add missing patchset for ruby enterprise 2010.02-r1.

---
 .../001_memory_leak.patch                          |   59 +
 .../patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch |   16 +
 .../003_mkmf-parallel-install.patch                |   16 +
 .../004_configure-libdir.patch                     |   13 +
 .../005_mkconfig-libdir.patch                      |   15 +
 .../006_pathname_warning.patch                     |   16 +
 .../007_no-undefined-ext.patch                     |   13 +
 .../008_berkdb-5.0.patch                           |   13 +
 .../patches-ee-1.8.7-2010.02-r1/010_openssl1.patch | 2500 ++++++++++++++++++++
 .../012_webrick-CVE-2010-0541.patch                |   15 +
 .../999-fast-threading-NOAPPLY.diff                | 1320 +++++++++++
 patchsets/patches-ee-1.8.7-2010.02-r1/series       |   10 +
 12 files changed, 4006 insertions(+), 0 deletions(-)

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/001_memory_leak.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/001_memory_leak.patch
new file mode 100644
index 0000000..25853be
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/001_memory_leak.patch
@@ -0,0 +1,59 @@
+Index: source/ext/dl/handle.c
+===================================================================
+--- source.orig/ext/dl/handle.c
++++ source/ext/dl/handle.c
+@@ -10,9 +10,12 @@ VALUE rb_cDLHandle;
+ void
+ dlhandle_free(struct dl_handle *dlhandle)
+ {
++  if (!dlhandle)
++    return;
+   if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) {
+     dlclose(dlhandle->ptr);
+   }
++  dlfree(dlhandle);
+ }
+ 
+ VALUE
+Index: source/ext/dl/ptr.c
+===================================================================
+--- source.orig/ext/dl/ptr.c
++++ source/ext/dl/ptr.c
+@@ -45,6 +45,8 @@ rb_dlmem_aref(void *ptr)
+ void
+ dlptr_free(struct ptr_data *data)
+ {
++  if (!data)
++    return;
+   if (data->ptr) {
+     DEBUG_CODE({
+       printf("dlptr_free(): removing the pointer `0x%x' from the MemorySpace\n",
+@@ -61,6 +63,7 @@ dlptr_free(struct ptr_data *data)
+   if (data->stype) dlfree(data->stype);
+   if (data->ssize) dlfree(data->ssize);
+   if (data->ids) dlfree(data->ids);
++  dlfree(data);
+ }
+ 
+ void
+Index: source/ext/dl/sym.c
+===================================================================
+--- source.orig/ext/dl/sym.c
++++ source/ext/dl/sym.c
+@@ -57,6 +57,8 @@ char2type(int ch)
+ void
+ dlsym_free(struct sym_data *data)
+ {
++  if(!data)
++    return;
+   if( data->name ){
+     DEBUG_CODE({
+       printf("dlsym_free(): free(data->name:%s)\n",data->name);
+@@ -69,6 +71,7 @@ dlsym_free(struct sym_data *data)
+     });
+     free(data->type);
+   }
++  dlfree(data);
+ }
+ 
+ VALUE

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch
new file mode 100644
index 0000000..6574925
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/002_mkconfig.patch
@@ -0,0 +1,16 @@
+Fix for mkconfig to be able to handle empty continued lines.
+Patch from [ruby-core:20420] via bug 234877.
+
+Index: source/mkconfig.rb
+===================================================================
+--- source.orig/mkconfig.rb
++++ source/mkconfig.rb
+@@ -55,7 +55,7 @@ File.foreach "config.status" do |line|
+       continued_name = name
+       next
+     end
+-  when /^"(.+)"\s*(\\)?$/
++  when /^"(.*)"\s*(\\)?$/
+     if continued_line
+       continued_line <<  $1
+       unless $2

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/003_mkmf-parallel-install.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/003_mkmf-parallel-install.patch
new file mode 100644
index 0000000..41bf2bc
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/003_mkmf-parallel-install.patch
@@ -0,0 +1,16 @@
+ Patch for bug 239101 by Matsuu Takuto, via Redmine issue 1337 (yes, really).
+ Backported for 1.8.* by Alex Legler.
+
+Index: source/lib/mkmf.rb
+===================================================================
+--- source.orig/lib/mkmf.rb
++++ source/lib/mkmf.rb
+@@ -1523,7 +1523,7 @@ static:		$(STATIC_LIB)#{$extout ? " inst
+     dest = "#{dir}/#{f}"
+     mfile.puts dir, "install-so: #{dest}"
+     unless $extout
+-      mfile.print "#{dest}: #{f}\n"
++      mfile.print "#{dest}: #{dir} #{f}\n"
+       if (sep = config_string('BUILD_FILE_SEPARATOR'))
+         f.gsub!("/", sep)
+         dir.gsub!("/", sep)

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/004_configure-libdir.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/004_configure-libdir.patch
new file mode 100644
index 0000000..b7f17fa
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/004_configure-libdir.patch
@@ -0,0 +1,13 @@
+Index: source/configure.in
+===================================================================
+--- source.orig/configure.in
++++ source/configure.in
+@@ -1730,7 +1730,7 @@ case "$target_os" in
+     rubyw_install_name="$RUBYW_INSTALL_NAME"
+     ;;
+ esac
+-RUBY_LIB_PREFIX=`eval echo \\"${libdir}/ruby\\"`
++RUBY_LIB_PREFIX=`eval echo \\"${libdir}/rubyee\\"`
+ 
+ AC_ARG_WITH(sitedir,
+ 	    [  --with-sitedir=DIR      site libraries in DIR [[LIBDIR/ruby/site_ruby]]],

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/005_mkconfig-libdir.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/005_mkconfig-libdir.patch
new file mode 100644
index 0000000..932a4e3
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/005_mkconfig-libdir.patch
@@ -0,0 +1,15 @@
+Evil hack fiddling with the ruby libdir
+
+Index: source/mkconfig.rb
+===================================================================
+--- source.orig/mkconfig.rb
++++ source/mkconfig.rb
+@@ -141,7 +141,7 @@ print(*v_fast)
+ print(*v_others)
+ print <<EOS
+   CONFIG["ruby_version"] = "$(MAJOR).$(MINOR)"
+-  CONFIG["rubylibdir"] = "$(libdir)/ruby/$(ruby_version)"
++  CONFIG["rubylibdir"] = "$(libdir)/rubyee/$(ruby_version)"
+   CONFIG["archdir"] = "$(rubylibdir)/$(arch)"
+   CONFIG["sitelibdir"] = "$(sitedir)/$(ruby_version)"
+   CONFIG["sitearchdir"] = "$(sitelibdir)/$(sitearch)"

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/006_pathname_warning.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/006_pathname_warning.patch
new file mode 100644
index 0000000..ed051d3
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/006_pathname_warning.patch
@@ -0,0 +1,16 @@
+Fix a warning shown in Pathname#sub. Asked upstream for inclusion in redmine
+issue 2538 -a3li
+
+Index: source/lib/pathname.rb
+===================================================================
+--- source.orig/lib/pathname.rb
++++ source/lib/pathname.rb
+@@ -260,7 +260,7 @@ class Pathname
+         ensure
+           Thread.current[:pathname_sub_matchdata] = old
+         end
+-        yield *args
++        yield(*args)
+       }
+     else
+       path = @path.sub(pattern, *rest)

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/007_no-undefined-ext.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/007_no-undefined-ext.patch
new file mode 100644
index 0000000..a122561
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/007_no-undefined-ext.patch
@@ -0,0 +1,13 @@
+Index: source/configure.in
+===================================================================
+--- source.orig/configure.in
++++ source/configure.in
+@@ -1201,7 +1201,7 @@ if test "$with_dln_a_out" != yes; then
+ 	linux* | gnu* | k*bsd*-gnu | netbsd* | bsdi*)
+ 			: ${LDSHARED='${CC} -shared'}
+ 			if test "$rb_cv_binary_elf" = yes; then
+-			    LDFLAGS="$LDFLAGS -Wl,-export-dynamic"
++			    LDFLAGS="$LDFLAGS -Wl,-export-dynamic -Wl,--no-undefined"
+ 			fi
+ 			rb_cv_dlopen=yes ;;
+ 	interix*) 	: ${LDSHARED="$CC -shared"}

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/008_berkdb-5.0.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/008_berkdb-5.0.patch
new file mode 100644
index 0000000..096a1bf
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/008_berkdb-5.0.patch
@@ -0,0 +1,13 @@
+Index: ruby-1.8.7-p249/ext/dbm/extconf.rb
+===================================================================
+--- ruby-1.8.7-p249.orig/ext/dbm/extconf.rb
++++ ruby-1.8.7-p249/ext/dbm/extconf.rb
+@@ -26,7 +26,7 @@ def headers.db_check(db)
+   case db
+   when /^db2?$/
+     db_prefix = "__db_n"
+-    hsearch = "-DDB_DBM_HSEARCH "
++    hsearch = "-DDB_DBM_HSEARCH -DHAVE_DBM "
+   when "gdbm"
+     have_gdbm = true
+   when "gdbm_compat"

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/010_openssl1.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/010_openssl1.patch
new file mode 100644
index 0000000..bdec751
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/010_openssl1.patch
@@ -0,0 +1,2500 @@
+Sync OpenSSL module to the 1.8.7_p299 version. Backport by a3li@g.o
+Upstream: reported, but not yet fixed
+Gentoo bug 326633
+
+diff -Naur source.old/ext/openssl/extconf.rb source/ext/openssl/extconf.rb
+--- source.old/ext/openssl/extconf.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/extconf.rb	2010-08-06 12:43:44.802276474 +0200
+@@ -11,7 +11,7 @@
+   (See the file 'LICENCE'.)
+ 
+ = Version
+-  $Id$
++  $Id: extconf.rb 28367 2010-06-21 09:18:59Z shyouhei $
+ =end
+ 
+ require "mkmf"
+@@ -91,12 +91,13 @@
+ have_func("X509_CRL_set_issuer_name")
+ have_func("X509_CRL_set_version")
+ have_func("X509_CRL_sort")
++have_func("X509_NAME_hash_old")
+ have_func("X509_STORE_get_ex_data")
+ have_func("X509_STORE_set_ex_data")
+ have_func("OBJ_NAME_do_all_sorted")
+ have_func("SSL_SESSION_get_id")
+ have_func("OPENSSL_cleanse")
+-if try_compile("#define FOO(a, ...) foo(a, ##__VA_ARGS__)\n int x(){FOO(1);FOO(1,2);FOO(1,2,3);}\n")
++if try_compile("#define FOO(...) foo(__VA_ARGS__)\n int x(){FOO(1);FOO(1,2);FOO(1,2,3);}\n")
+   $defs.push("-DHAVE_VA_ARGS_MACRO")
+ end
+ if have_header("openssl/engine.h")
+@@ -106,6 +107,14 @@
+   have_func("ENGINE_get_digest")
+   have_func("ENGINE_get_cipher")
+   have_func("ENGINE_cleanup")
++  have_func("ENGINE_load_4758cca")
++  have_func("ENGINE_load_aep")
++  have_func("ENGINE_load_atalla")
++  have_func("ENGINE_load_chil")
++  have_func("ENGINE_load_cswift")
++  have_func("ENGINE_load_nuron")
++  have_func("ENGINE_load_sureware")
++  have_func("ENGINE_load_ubsec")
+ end
+ if try_compile(<<SRC)
+ #include <openssl/opensslv.h>
+diff -Naur source.old/ext/openssl/lib/net/ftptls.rb source/ext/openssl/lib/net/ftptls.rb
+--- source.old/ext/openssl/lib/net/ftptls.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/net/ftptls.rb	2010-08-06 12:43:44.802276474 +0200
+@@ -13,7 +13,7 @@
+ = Requirements
+ 
+ = Version
+-  $Id$
++  $Id: ftptls.rb 13657 2007-10-08 11:16:54Z gotoyuzo $
+   
+ = Notes
+   Tested on FreeBSD 5-CURRENT and 4-STABLE
+diff -Naur source.old/ext/openssl/lib/net/telnets.rb source/ext/openssl/lib/net/telnets.rb
+--- source.old/ext/openssl/lib/net/telnets.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/net/telnets.rb	2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+   (See the file 'LICENCE'.)
+ 
+ = Version
+-  $Id$
++  $Id: telnets.rb 13657 2007-10-08 11:16:54Z gotoyuzo $
+   
+   2001/11/06: Contiributed to Ruby/OpenSSL project.
+ 
+diff -Naur source.old/ext/openssl/lib/openssl/bn.rb source/ext/openssl/lib/openssl/bn.rb
+--- source.old/ext/openssl/lib/openssl/bn.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/bn.rb	2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+   (See the file 'LICENCE'.)
+ 
+ = Version
+-  $Id$
++  $Id: bn.rb 11708 2007-02-12 23:01:19Z shyouhei $
+ =end
+ 
+ ##
+diff -Naur source.old/ext/openssl/lib/openssl/buffering.rb source/ext/openssl/lib/openssl/buffering.rb
+--- source.old/ext/openssl/lib/openssl/buffering.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/buffering.rb	2010-08-06 12:43:44.814276754 +0200
+@@ -11,9 +11,10 @@
+   (See the file 'LICENCE'.)
+ 
+ = Version
+-  $Id$
++  $Id: buffering.rb 28004 2010-05-24 23:58:49Z shyouhei $
+ =end
+ 
++module OpenSSL
+ module Buffering
+   include Enumerable
+   attr_accessor :sync
+@@ -237,3 +238,4 @@
+     sysclose
+   end
+ end
++end
+diff -Naur source.old/ext/openssl/lib/openssl/cipher.rb source/ext/openssl/lib/openssl/cipher.rb
+--- source.old/ext/openssl/lib/openssl/cipher.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/cipher.rb	2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+   (See the file 'LICENCE'.)
+ 
+ = Version
+-  $Id$
++  $Id: cipher.rb 12496 2007-06-08 15:02:04Z technorama $
+ =end
+ 
+ ##
+diff -Naur source.old/ext/openssl/lib/openssl/digest.rb source/ext/openssl/lib/openssl/digest.rb
+--- source.old/ext/openssl/lib/openssl/digest.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/digest.rb	2010-08-06 12:43:44.814276754 +0200
+@@ -11,7 +11,7 @@
+   (See the file 'LICENCE'.)
+ 
+ = Version
+-  $Id$
++  $Id: digest.rb 28004 2010-05-24 23:58:49Z shyouhei $
+ =end
+ 
+ ##
+@@ -40,7 +40,7 @@
+           super(name, data.first)
+         }
+       }
+-      singleton = (class <<klass; self; end)
++      singleton = (class << klass; self; end)
+       singleton.class_eval{
+         define_method(:digest){|data| Digest.digest(name, data) }
+         define_method(:hexdigest){|data| Digest.hexdigest(name, data) }
+diff -Naur source.old/ext/openssl/lib/openssl/ssl-internal.rb source/ext/openssl/lib/openssl/ssl-internal.rb
+--- source.old/ext/openssl/lib/openssl/ssl-internal.rb	1970-01-01 01:00:00.000000000 +0100
++++ source/ext/openssl/lib/openssl/ssl-internal.rb	2010-08-06 12:43:44.814276754 +0200
+@@ -0,0 +1,179 @@
++=begin
++= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL
++
++= Info
++  'OpenSSL for Ruby 2' project
++  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
++  All rights reserved.
++
++= Licence
++  This program is licenced under the same licence as Ruby.
++  (See the file 'LICENCE'.)
++
++= Version
++  $Id$
++=end
++
++require "openssl/buffering"
++require "fcntl"
++
++module OpenSSL
++  module SSL
++    class SSLContext
++      DEFAULT_PARAMS = {
++        :ssl_version => "SSLv23",
++        :verify_mode => OpenSSL::SSL::VERIFY_PEER,
++        :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
++        :options => OpenSSL::SSL::OP_ALL,
++      }
++
++      DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
++      DEFAULT_CERT_STORE.set_default_paths
++      if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
++        DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
++      end
++
++      def set_params(params={})
++        params = DEFAULT_PARAMS.merge(params)
++        # ssl_version need to be set at first.
++        self.ssl_version = params.delete(:ssl_version)
++        params.each{|name, value| self.__send__("#{name}=", value) }
++        if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
++          unless self.ca_file or self.ca_path or self.cert_store
++            self.cert_store = DEFAULT_CERT_STORE
++          end
++        end
++        return params
++      end
++    end
++
++    module SocketForwarder
++      def addr
++        to_io.addr
++      end
++
++      def peeraddr
++        to_io.peeraddr
++      end
++
++      def setsockopt(level, optname, optval)
++        to_io.setsockopt(level, optname, optval)
++      end
++
++      def getsockopt(level, optname)
++        to_io.getsockopt(level, optname)
++      end
++
++      def fcntl(*args)
++        to_io.fcntl(*args)
++      end
++
++      def closed?
++        to_io.closed?
++      end
++
++      def do_not_reverse_lookup=(flag)
++        to_io.do_not_reverse_lookup = flag
++      end
++    end
++
++    module Nonblock
++      def initialize(*args)
++        flag = File::NONBLOCK
++        flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
++        @io.fcntl(Fcntl::F_SETFL, flag)
++        super
++      end
++    end
++
++    def verify_certificate_identity(cert, hostname)
++      should_verify_common_name = true
++      cert.extensions.each{|ext|
++        next if ext.oid != "subjectAltName"
++        ext.value.split(/,\s+/).each{|general_name|
++          if /\ADNS:(.*)/ =~ general_name
++            should_verify_common_name = false
++            reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
++            return true if /\A#{reg}\z/i =~ hostname
++          elsif /\AIP Address:(.*)/ =~ general_name
++            should_verify_common_name = false
++            return true if $1 == hostname
++          end
++        }
++      }
++      if should_verify_common_name
++        cert.subject.to_a.each{|oid, value|
++          if oid == "CN"
++            reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
++            return true if /\A#{reg}\z/i =~ hostname
++          end
++        }
++      end
++      return false
++    end
++    module_function :verify_certificate_identity
++
++    class SSLSocket
++      include Buffering
++      include SocketForwarder
++      include Nonblock
++
++      def post_connection_check(hostname)
++        unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
++          raise SSLError, "hostname was not match with the server certificate"
++        end
++        return true
++      end
++
++      def session
++        SSL::Session.new(self)
++      rescue SSL::Session::SessionError
++        nil
++      end
++    end
++
++    class SSLServer
++      include SocketForwarder
++      attr_accessor :start_immediately
++
++      def initialize(svr, ctx)
++        @svr = svr
++        @ctx = ctx
++        unless ctx.session_id_context
++          session_id = OpenSSL::Digest::MD5.hexdigest($0)
++          @ctx.session_id_context = session_id
++        end
++        @start_immediately = true
++      end
++
++      def to_io
++        @svr
++      end
++
++      def listen(backlog=5)
++        @svr.listen(backlog)
++      end
++
++      def shutdown(how=Socket::SHUT_RDWR)
++        @svr.shutdown(how)
++      end
++
++      def accept
++        sock = @svr.accept
++        begin
++          ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
++          ssl.sync_close = true
++          ssl.accept if @start_immediately
++          ssl
++        rescue SSLError => ex
++          sock.close
++          raise ex
++        end
++      end
++
++      def close
++        @svr.close
++      end
++    end
++  end
++end
+diff -Naur source.old/ext/openssl/lib/openssl/ssl.rb source/ext/openssl/lib/openssl/ssl.rb
+--- source.old/ext/openssl/lib/openssl/ssl.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/ssl.rb	2010-08-06 12:43:44.814276754 +0200
+@@ -1,179 +1 @@
+-=begin
+-= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL
+-
+-= Info
+-  'OpenSSL for Ruby 2' project
+-  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
+-  All rights reserved.
+-
+-= Licence
+-  This program is licenced under the same licence as Ruby.
+-  (See the file 'LICENCE'.)
+-
+-= Version
+-  $Id$
+-=end
+-
+-require "openssl"
+-require "openssl/buffering"
+-require "fcntl"
+-
+-module OpenSSL
+-  module SSL
+-    class SSLContext
+-      DEFAULT_PARAMS = {
+-        :ssl_version => "SSLv23",
+-        :verify_mode => OpenSSL::SSL::VERIFY_PEER,
+-        :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
+-        :options => OpenSSL::SSL::OP_ALL,
+-      }
+-
+-      DEFAULT_CERT_STORE = OpenSSL::X509::Store.new
+-      DEFAULT_CERT_STORE.set_default_paths
+-      if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)
+-        DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
+-      end
+-
+-      def set_params(params={})
+-        params = DEFAULT_PARAMS.merge(params)
+-        self.ssl_version = params.delete(:ssl_version)
+-        params.each{|name, value| self.__send__("#{name}=", value) }
+-        if self.verify_mode != OpenSSL::SSL::VERIFY_NONE
+-          unless self.ca_file or self.ca_path or self.cert_store
+-            self.cert_store = DEFAULT_CERT_STORE
+-          end
+-        end
+-        return params
+-      end
+-    end
+-
+-    module SocketForwarder
+-      def addr
+-        to_io.addr
+-      end
+-
+-      def peeraddr
+-        to_io.peeraddr
+-      end
+-
+-      def setsockopt(level, optname, optval)
+-        to_io.setsockopt(level, optname, optval)
+-      end
+-
+-      def getsockopt(level, optname)
+-        to_io.getsockopt(level, optname)
+-      end
+-
+-      def fcntl(*args)
+-        to_io.fcntl(*args)
+-      end
+-
+-      def closed?
+-        to_io.closed?
+-      end
+-
+-      def do_not_reverse_lookup=(flag)
+-        to_io.do_not_reverse_lookup = flag
+-      end
+-    end
+-
+-    module Nonblock
+-      def initialize(*args)
+-        flag = File::NONBLOCK
+-        flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)
+-        @io.fcntl(Fcntl::F_SETFL, flag)
+-        super
+-      end
+-    end
+-
+-    def verify_certificate_identity(cert, hostname)
+-      should_verify_common_name = true
+-      cert.extensions.each{|ext|
+-        next if ext.oid != "subjectAltName"
+-        ext.value.split(/,\s+/).each{|general_name|
+-          if /\ADNS:(.*)/ =~ general_name
+-            should_verify_common_name = false
+-            reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
+-            return true if /\A#{reg}\z/i =~ hostname
+-          elsif /\AIP Address:(.*)/ =~ general_name
+-            should_verify_common_name = false
+-            return true if $1 == hostname
+-          end
+-        }
+-      }
+-      if should_verify_common_name
+-        cert.subject.to_a.each{|oid, value|
+-          if oid == "CN"
+-            reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
+-            return true if /\A#{reg}\z/i =~ hostname
+-          end
+-        }
+-      end
+-      return false
+-    end
+-    module_function :verify_certificate_identity
+-
+-    class SSLSocket
+-      include Buffering
+-      include SocketForwarder
+-      include Nonblock
+-
+-      def post_connection_check(hostname)
+-        unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
+-          raise SSLError, "hostname was not match with the server certificate"
+-        end
+-        return true
+-      end
+-
+-      def session
+-        SSL::Session.new(self)
+-      rescue SSL::Session::SessionError
+-        nil
+-      end
+-    end
+-
+-    class SSLServer
+-      include SocketForwarder
+-      attr_accessor :start_immediately
+-
+-      def initialize(svr, ctx)
+-        @svr = svr
+-        @ctx = ctx
+-        unless ctx.session_id_context
+-          session_id = OpenSSL::Digest::MD5.hexdigest($0)
+-          @ctx.session_id_context = session_id
+-        end
+-        @start_immediately = true
+-      end
+-
+-      def to_io
+-        @svr
+-      end
+-
+-      def listen(backlog=5)
+-        @svr.listen(backlog)
+-      end
+-
+-      def shutdown(how=Socket::SHUT_RDWR)
+-        @svr.shutdown(how)
+-      end
+-
+-      def accept
+-        sock = @svr.accept
+-        begin
+-          ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
+-          ssl.sync_close = true
+-          ssl.accept if @start_immediately
+-          ssl
+-        rescue SSLError => ex
+-          sock.close
+-          raise ex
+-        end
+-      end
+-
+-      def close
+-        @svr.close
+-      end
+-    end
+-  end
+-end
++require 'openssl'
+diff -Naur source.old/ext/openssl/lib/openssl/x509-internal.rb source/ext/openssl/lib/openssl/x509-internal.rb
+--- source.old/ext/openssl/lib/openssl/x509-internal.rb	1970-01-01 01:00:00.000000000 +0100
++++ source/ext/openssl/lib/openssl/x509-internal.rb	2010-08-06 12:43:44.818276265 +0200
+@@ -0,0 +1,153 @@
++=begin
++= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses
++
++= Info
++  'OpenSSL for Ruby 2' project
++  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
++  All rights reserved.
++
++= Licence
++  This program is licenced under the same licence as Ruby.
++  (See the file 'LICENCE'.)
++
++= Version
++  $Id$
++=end
++
++module OpenSSL
++  module X509
++    class ExtensionFactory
++      def create_extension(*arg)
++        if arg.size > 1
++          create_ext(*arg)
++        else
++          send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
++        end
++      end
++
++      def create_ext_from_array(ary)
++        raise ExtensionError, "unexpected array form" if ary.size > 3
++        create_ext(ary[0], ary[1], ary[2])
++      end
++
++      def create_ext_from_string(str) # "oid = critical, value"
++        oid, value = str.split(/=/, 2)
++        oid.strip!
++        value.strip!
++        create_ext(oid, value)
++      end
++
++      def create_ext_from_hash(hash)
++        create_ext(hash["oid"], hash["value"], hash["critical"])
++      end
++    end
++
++    class Extension
++      def to_s # "oid = critical, value"
++        str = self.oid
++        str << " = "
++        str << "critical, " if self.critical?
++        str << self.value.gsub(/\n/, ", ")
++      end
++
++      def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
++        {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
++      end
++
++      def to_a
++        [ self.oid, self.value, self.critical? ]
++      end
++    end
++
++    class Name
++      module RFC2253DN
++        Special = ',=+<>#;'
++        HexChar = /[0-9a-fA-F]/
++        HexPair = /#{HexChar}#{HexChar}/
++        HexString = /#{HexPair}+/
++        Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
++        StringChar = /[^#{Special}\\"]/
++        QuoteChar = /[^\\"]/
++        AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
++        AttributeValue = /
++          (?!["#])((?:#{StringChar}|#{Pair})*)|
++          \#(#{HexString})|
++          "((?:#{QuoteChar}|#{Pair})*)"
++        /x
++        TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
++
++        module_function
++
++        def expand_pair(str)
++          return nil unless str
++          return str.gsub(Pair){
++            pair = $&
++            case pair.size
++            when 2 then pair[1,1]
++            when 3 then Integer("0x#{pair[1,2]}").chr
++            else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
++            end
++          }
++        end
++
++        def expand_hexstring(str)
++          return nil unless str
++          der = str.gsub(HexPair){$&.to_i(16).chr }
++          a1 = OpenSSL::ASN1.decode(der)
++          return a1.value, a1.tag
++        end
++
++        def expand_value(str1, str2, str3)
++          value = expand_pair(str1)
++          value, tag = expand_hexstring(str2) unless value
++          value = expand_pair(str3) unless value
++          return value, tag
++        end
++
++        def scan(dn)
++          str = dn
++          ary = []
++          while true
++            if md = TypeAndValue.match(str)
++              matched = md.to_s
++              remain = md.post_match
++              type = md[1]
++              value, tag = expand_value(md[2], md[3], md[4]) rescue nil
++              if value
++                type_and_value = [type, value]
++                type_and_value.push(tag) if tag
++                ary.unshift(type_and_value)
++                if remain.length > 2 && remain[0] == ?,
++                  str = remain[1..-1]
++                  next
++                elsif remain.length > 2 && remain[0] == ?+
++                  raise OpenSSL::X509::NameError,
++                    "multi-valued RDN is not supported: #{dn}"
++                elsif remain.empty?
++                  break
++                end
++              end
++            end
++            msg_dn = dn[0, dn.length - str.length] + " =>" + str
++            raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
++          end
++          return ary
++        end
++      end
++
++      class <<self
++        def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
++          ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
++          self.new(ary, template)
++        end
++
++        def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
++          ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
++          self.new(ary, template)
++        end
++
++        alias parse parse_openssl
++      end
++    end
++  end
++end
+diff -Naur source.old/ext/openssl/lib/openssl/x509.rb source/ext/openssl/lib/openssl/x509.rb
+--- source.old/ext/openssl/lib/openssl/x509.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl/x509.rb	2010-08-06 12:43:44.818276265 +0200
+@@ -1,154 +1 @@
+-=begin
+-= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses
+-
+-= Info
+-  'OpenSSL for Ruby 2' project
+-  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
+-  All rights reserved.
+-
+-= Licence
+-  This program is licenced under the same licence as Ruby.
+-  (See the file 'LICENCE'.)
+-
+-= Version
+-  $Id$
+-=end
+-
+-require "openssl"
+-
+-module OpenSSL
+-  module X509
+-    class ExtensionFactory
+-      def create_extension(*arg)
+-        if arg.size > 1
+-          create_ext(*arg)
+-        else
+-          send("create_ext_from_"+arg[0].class.name.downcase, arg[0])
+-        end
+-      end
+-
+-      def create_ext_from_array(ary)
+-        raise ExtensionError, "unexpected array form" if ary.size > 3 
+-        create_ext(ary[0], ary[1], ary[2])
+-      end
+-
+-      def create_ext_from_string(str) # "oid = critical, value"
+-        oid, value = str.split(/=/, 2)
+-        oid.strip!
+-        value.strip!
+-        create_ext(oid, value)
+-      end
+-      
+-      def create_ext_from_hash(hash)
+-        create_ext(hash["oid"], hash["value"], hash["critical"])
+-      end
+-    end
+-    
+-    class Extension
+-      def to_s # "oid = critical, value"
+-        str = self.oid
+-        str << " = "
+-        str << "critical, " if self.critical?
+-        str << self.value.gsub(/\n/, ", ")
+-      end
+-        
+-      def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false}
+-        {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?}
+-      end
+-
+-      def to_a
+-        [ self.oid, self.value, self.critical? ]
+-      end
+-    end
+-
+-    class Name
+-      module RFC2253DN
+-        Special = ',=+<>#;'
+-        HexChar = /[0-9a-fA-F]/
+-        HexPair = /#{HexChar}#{HexChar}/
+-        HexString = /#{HexPair}+/
+-        Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/
+-        StringChar = /[^#{Special}\\"]/
+-        QuoteChar = /[^\\"]/
+-        AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/
+-        AttributeValue = /
+-          (?!["#])((?:#{StringChar}|#{Pair})*)|
+-          \#(#{HexString})|
+-          "((?:#{QuoteChar}|#{Pair})*)"
+-        /x
+-        TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/
+-
+-        module_function
+-
+-        def expand_pair(str)
+-          return nil unless str
+-          return str.gsub(Pair){|pair|
+-            case pair.size
+-            when 2 then pair[1,1]
+-            when 3 then Integer("0x#{pair[1,2]}").chr
+-            else raise OpenSSL::X509::NameError, "invalid pair: #{str}"
+-            end
+-          }
+-        end
+-
+-        def expand_hexstring(str)
+-          return nil unless str
+-          der = str.gsub(HexPair){|hex| Integer("0x#{hex}").chr }
+-          a1 = OpenSSL::ASN1.decode(der)
+-          return a1.value, a1.tag
+-        end
+-
+-        def expand_value(str1, str2, str3)
+-          value = expand_pair(str1)
+-          value, tag = expand_hexstring(str2) unless value
+-          value = expand_pair(str3) unless value
+-          return value, tag
+-        end
+-
+-        def scan(dn)
+-          str = dn
+-          ary = []
+-          while true
+-            if md = TypeAndValue.match(str)
+-              matched = md.to_s
+-              remain = md.post_match
+-              type = md[1]
+-              value, tag = expand_value(md[2], md[3], md[4]) rescue nil
+-              if value
+-                type_and_value = [type, value]
+-                type_and_value.push(tag) if tag
+-                ary.unshift(type_and_value)
+-                if remain.length > 2 && remain[0] == ?,
+-                  str = remain[1..-1]
+-                  next
+-                elsif remain.length > 2 && remain[0] == ?+
+-                  raise OpenSSL::X509::NameError,
+-                    "multi-valued RDN is not supported: #{dn}"
+-                elsif remain.empty?
+-                  break
+-                end
+-              end
+-            end
+-            msg_dn = dn[0, dn.length - str.length] + " =>" + str
+-            raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}"
+-          end
+-          return ary
+-        end
+-      end
+-
+-      class <<self
+-        def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)
+-          ary = OpenSSL::X509::Name::RFC2253DN.scan(str)
+-          self.new(ary, template)
+-        end
+-
+-        def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
+-          ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
+-          self.new(ary, template)
+-        end
+-
+-        alias parse parse_openssl
+-      end
+-    end
+-  end
+-end
++require 'openssl'
+diff -Naur source.old/ext/openssl/lib/openssl.rb source/ext/openssl/lib/openssl.rb
+--- source.old/ext/openssl/lib/openssl.rb	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/lib/openssl.rb	2010-08-06 12:43:44.818276265 +0200
+@@ -11,7 +11,7 @@
+   (See the file 'LICENCE'.)
+ 
+ = Version
+-  $Id$
++  $Id: openssl.rb 28004 2010-05-24 23:58:49Z shyouhei $
+ =end
+ 
+ require 'openssl.so'
+@@ -20,6 +20,6 @@
+ require 'openssl/cipher'
+ require 'openssl/digest'
+ require 'openssl/pkcs7'
+-require 'openssl/ssl'
+-require 'openssl/x509'
++require 'openssl/ssl-internal'
++require 'openssl/x509-internal'
+ 
+diff -Naur source.old/ext/openssl/openssl_missing.c source/ext/openssl/openssl_missing.c
+--- source.old/ext/openssl/openssl_missing.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/openssl_missing.c	2010-08-06 12:43:44.818276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: openssl_missing.c 16467 2008-05-19 03:00:52Z knu $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/openssl_missing.h source/ext/openssl/openssl_missing.h
+--- source.old/ext/openssl/openssl_missing.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/openssl_missing.h	2010-08-06 12:43:44.818276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: openssl_missing.h 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -18,6 +18,9 @@
+ #ifndef TYPEDEF_D2I_OF
+ typedef char *d2i_of_void();
+ #endif
++#ifndef TYPEDEF_I2D_OF
++typedef int i2d_of_void();
++#endif
+ 
+ /*
+  * These functions are not included in headers of OPENSSL <= 0.9.6b
+@@ -30,33 +33,33 @@
+ 
+ #if !defined(PEM_write_bio_DSAPublicKey)
+ # define PEM_write_bio_DSAPublicKey(bp,x) \
+-	PEM_ASN1_write_bio((int (*)())i2d_DSAPublicKey,\
++	PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPublicKey,\
+ 		PEM_STRING_DSA_PUBLIC,\
+ 		bp,(char *)x, NULL, NULL, 0, NULL, NULL)
+ #endif
+ 
+ #if !defined(DSAPrivateKey_dup)
+-# define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((int (*)())i2d_DSAPrivateKey, \
++# define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, \
+ 	(char *(*)())d2i_DSAPrivateKey,(char *)dsa)
+ #endif
+ 
+ #if !defined(DSAPublicKey_dup)
+-# define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((int (*)())i2d_DSAPublicKey, \
++# define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPublicKey, \
+ 	(char *(*)())d2i_DSAPublicKey,(char *)dsa)
+ #endif
+ 
+ #if !defined(X509_REVOKED_dup)
+-# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((int (*)())i2d_X509_REVOKED, \
++# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \
+ 	(char *(*)())d2i_X509_REVOKED, (char *)rev)
+ #endif
+ 
+ #if !defined(PKCS7_SIGNER_INFO_dup)
+-#  define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((int (*)())i2d_PKCS7_SIGNER_INFO, \
++#  define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, \
+ 	(char *(*)())d2i_PKCS7_SIGNER_INFO, (char *)si)
+ #endif
+ 
+ #if !defined(PKCS7_RECIP_INFO_dup)
+-#  define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((int (*)())i2d_PKCS7_RECIP_INFO, \
++#  define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, \
+ 	(char *(*)())d2i_PKCS7_RECIP_INFO, (char *)ri)
+ #endif
+ 
+diff -Naur source.old/ext/openssl/ossl_asn1.c source/ext/openssl/ossl_asn1.c
+--- source.old/ext/openssl/ossl_asn1.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_asn1.c	2010-08-06 12:43:44.818276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_asn1.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' team members
+  * Copyright (C) 2003
+  * All rights reserved.
+@@ -304,23 +304,23 @@
+  * DER to Ruby converters
+  */
+ static VALUE
+-decode_bool(OSSL_MORE_CONST unsigned char* der, int length)
++decode_bool(unsigned char* der, int length)
+ {
+-    int bool;
+-    OSSL_MORE_CONST unsigned char *p;
++    int val;
++    unsigned char *p;
+ 
+     p = der;
+-    if((bool = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)
++    if((val = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)
+ 	ossl_raise(eASN1Error, NULL);
+ 
+-    return bool ? Qtrue : Qfalse;
++    return val ? Qtrue : Qfalse;
+ }
+ 
+ static VALUE
+-decode_int(OSSL_MORE_CONST unsigned char* der, int length)
++decode_int(unsigned char* der, int length)
+ {
+     ASN1_INTEGER *ai;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     VALUE ret; 
+     int status = 0;
+ 
+@@ -336,11 +336,10 @@
+ }
+ 
+ static VALUE
+-decode_bstr(OSSL_MORE_CONST unsigned char* der, int length, long *unused_bits)
++decode_bstr(unsigned char* der, int length, long *unused_bits)
+ {
+     ASN1_BIT_STRING *bstr;
+-    OSSL_MORE_CONST unsigned char *p;
+-    unsigned char *buf;
++    const unsigned char *p;
+     long len;
+     VALUE ret;
+ 
+@@ -348,25 +347,20 @@
+     if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
+ 	ossl_raise(eASN1Error, NULL);
+     len = bstr->length;
+-    if(!(buf = OPENSSL_malloc(len))){
+-	ASN1_BIT_STRING_free(bstr);
+-	ossl_raise(eASN1Error, NULL);
+-    }
+     *unused_bits = 0;
+     if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
+ 	*unused_bits = bstr->flags & 0x07;
+-    memcpy(buf, bstr->data, len);
++    ret = rb_str_new((const char *)bstr->data, len);
+     ASN1_BIT_STRING_free(bstr);
+-    ret = ossl_buf2str(buf, len);
+ 
+     return ret;
+ }
+ 
+ static VALUE
+-decode_enum(OSSL_MORE_CONST unsigned char* der, int length)
++decode_enum(unsigned char* der, int length)
+ {
+     ASN1_ENUMERATED *ai;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     VALUE ret; 
+     int status = 0;
+ 
+@@ -382,10 +376,10 @@
+ }
+ 
+ static VALUE
+-decode_null(OSSL_MORE_CONST unsigned char* der, int length)
++decode_null(unsigned char* der, int length)
+ {
+     ASN1_NULL *null;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+ 
+     p = der;
+     if(!(null = d2i_ASN1_NULL(NULL, &p, length)))
+@@ -396,10 +390,10 @@
+ }
+ 
+ static VALUE
+-decode_obj(OSSL_MORE_CONST unsigned char* der, int length)
++decode_obj(unsigned char* der, int length)
+ {
+     ASN1_OBJECT *obj;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     VALUE ret;
+     int nid;
+     BIO *bio;
+@@ -425,10 +419,10 @@
+ }
+ 
+ static VALUE
+-decode_time(OSSL_MORE_CONST unsigned char* der, int length)
++decode_time(unsigned char* der, int length)
+ {
+     ASN1_TIME *time;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     VALUE ret;
+     int status = 0;
+ 
+@@ -501,7 +495,7 @@
+     value = ossl_asn1_get_value(obj);
+     switch(tag){
+     case V_ASN1_BOOLEAN:
+-	ptr = (void*)obj_to_asn1bool(value);
++	ptr = (void*)(VALUE)obj_to_asn1bool(value);
+ 	free_func = NULL;
+ 	break;
+     case V_ASN1_INTEGER:         /* FALLTHROUGH */
+@@ -713,10 +707,10 @@
+ }
+ 
+ static VALUE
+-ossl_asn1_decode0(OSSL_MORE_CONST unsigned char **pp, long length,
+-		  long *offset, long depth, int once, int yield)
++ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
++		  int once, int yield)
+ {
+-    OSSL_MORE_CONST unsigned char *start, *p;
++    unsigned char *start, *p;
+     long len, off = *offset;
+     int hlen, tag, tc, j;
+     VALUE ary, asn1data, value, tag_class;
+@@ -819,7 +813,7 @@
+ static VALUE
+ ossl_asn1_traverse(VALUE self, VALUE obj)
+ {
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     long offset = 0;
+     volatile VALUE tmp;
+ 
+@@ -835,7 +829,7 @@
+ ossl_asn1_decode(VALUE self, VALUE obj)
+ {
+     VALUE ret, ary;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     long offset = 0;
+     volatile VALUE tmp;
+ 
+@@ -852,7 +846,7 @@
+ ossl_asn1_decode_all(VALUE self, VALUE obj)
+ {
+     VALUE ret;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     long offset = 0;
+     volatile VALUE tmp;
+ 
+@@ -926,7 +920,7 @@
+ {
+     ASN1_TYPE *asn1;
+     int tn, tc, explicit;
+-    long length, reallen;
++    long len, reallen;
+     unsigned char *buf, *p;
+     VALUE str;
+ 
+@@ -935,26 +929,24 @@
+     explicit = ossl_asn1_is_explicit(self);
+     asn1 = ossl_asn1_get_asn1type(self);
+ 
+-    length = ASN1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
+-    if(!(buf = OPENSSL_malloc(length))){
++    len = ASN1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);
++    if(!(buf = OPENSSL_malloc(len))){
+ 	ossl_ASN1_TYPE_free(asn1);
+ 	ossl_raise(eASN1Error, "cannot alloc buffer");
+     }
+     p = buf;
+-    if(tc == V_ASN1_UNIVERSAL) ossl_i2d_ASN1_TYPE(asn1, &p);
+-    else{
+-	if(explicit){
+-	    ASN1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
+-	    ossl_i2d_ASN1_TYPE(asn1, &p);
+-	}
+-	else{
+-	    ossl_i2d_ASN1_TYPE(asn1, &p);
+-	    *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
+-	}
++    if (tc == V_ASN1_UNIVERSAL) {
++        ossl_i2d_ASN1_TYPE(asn1, &p);
++    } else if (explicit) {
++        ASN1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);
++        ossl_i2d_ASN1_TYPE(asn1, &p);
++    } else {
++        ossl_i2d_ASN1_TYPE(asn1, &p);
++        *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
+     }
+     ossl_ASN1_TYPE_free(asn1);
+     reallen = p - buf;
+-    assert(reallen <= length);
++    assert(reallen <= len);
+     str = ossl_buf2str(buf, reallen); /* buf will be free in ossl_buf2str */
+ 
+     return str;
+diff -Naur source.old/ext/openssl/ossl_asn1.h source/ext/openssl/ossl_asn1.h
+--- source.old/ext/openssl/ossl_asn1.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_asn1.h	2010-08-06 12:43:44.822276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_asn1.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' team members
+  * Copyright (C) 2003
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_bio.c source/ext/openssl/ossl_bio.c
+--- source.old/ext/openssl/ossl_bio.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bio.c	2010-08-06 12:43:44.822276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bio.c 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' team members
+  * Copyright (C) 2003
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_bio.h source/ext/openssl/ossl_bio.h
+--- source.old/ext/openssl/ossl_bio.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bio.h	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bio.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' team members
+  * Copyright (C) 2003
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_bn.c source/ext/openssl/ossl_bn.c
+--- source.old/ext/openssl/ossl_bn.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bn.c	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bn.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Technorama team <oss-ruby@technorama.net>
+  * All rights reserved.
+@@ -151,7 +151,7 @@
+ 	}
+ 	break;
+     default:
+-	ossl_raise(rb_eArgError, "illegal radix %d", base);
++	ossl_raise(rb_eArgError, "invalid radix %d", base);
+     }
+     return self;
+ }
+@@ -203,7 +203,7 @@
+ 	str = ossl_buf2str(buf, strlen(buf));
+ 	break;
+     default:
+-	ossl_raise(rb_eArgError, "illegal radix %d", base);
++	ossl_raise(rb_eArgError, "invalid radix %d", base);
+     }
+ 
+     return str;
+@@ -272,9 +272,9 @@
+ 	}						\
+ 	return Qfalse;					\
+     }
+-BIGNUM_BOOL1(is_zero);
+-BIGNUM_BOOL1(is_one);
+-BIGNUM_BOOL1(is_odd);
++BIGNUM_BOOL1(is_zero)
++BIGNUM_BOOL1(is_one)
++BIGNUM_BOOL1(is_odd)
+ 
+ #define BIGNUM_1c(func)					\
+     /*							\
+@@ -298,7 +298,7 @@
+ 	WrapBN(CLASS_OF(self), obj, result);		\
+ 	return obj;					\
+     }
+-BIGNUM_1c(sqr);
++BIGNUM_1c(sqr)
+ 
+ #define BIGNUM_2(func)					\
+     /*							\
+@@ -322,8 +322,8 @@
+ 	WrapBN(CLASS_OF(self), obj, result);		\
+ 	return obj;					\
+     }
+-BIGNUM_2(add);
+-BIGNUM_2(sub);
++BIGNUM_2(add)
++BIGNUM_2(sub)
+ 
+ #define BIGNUM_2c(func)						\
+     /*								\
+@@ -347,12 +347,12 @@
+ 	WrapBN(CLASS_OF(self), obj, result);			\
+ 	return obj;						\
+     }
+-BIGNUM_2c(mul);
+-BIGNUM_2c(mod);
+-BIGNUM_2c(exp);
+-BIGNUM_2c(gcd);
+-BIGNUM_2c(mod_sqr);
+-BIGNUM_2c(mod_inverse);
++BIGNUM_2c(mul)
++BIGNUM_2c(mod)
++BIGNUM_2c(exp)
++BIGNUM_2c(gcd)
++BIGNUM_2c(mod_sqr)
++BIGNUM_2c(mod_inverse)
+ 
+ /*
+  * call-seq:
+@@ -407,10 +407,10 @@
+ 	WrapBN(CLASS_OF(self), obj, result);			\
+ 	return obj;						\
+     }
+-BIGNUM_3c(mod_add);
+-BIGNUM_3c(mod_sub);
+-BIGNUM_3c(mod_mul);
+-BIGNUM_3c(mod_exp);
++BIGNUM_3c(mod_add)
++BIGNUM_3c(mod_sub)
++BIGNUM_3c(mod_mul)
++BIGNUM_3c(mod_exp)
+ 
+ #define BIGNUM_BIT(func)				\
+     /*							\
+@@ -428,9 +428,9 @@
+ 	}						\
+ 	return self;					\
+     }
+-BIGNUM_BIT(set_bit);
+-BIGNUM_BIT(clear_bit);
+-BIGNUM_BIT(mask_bits);
++BIGNUM_BIT(set_bit)
++BIGNUM_BIT(clear_bit)
++BIGNUM_BIT(mask_bits)
+ 
+ /*
+  * call-seq:
+@@ -474,8 +474,8 @@
+ 	WrapBN(CLASS_OF(self), obj, result);		\
+ 	return obj;					\
+     }
+-BIGNUM_SHIFT(lshift);
+-BIGNUM_SHIFT(rshift);
++BIGNUM_SHIFT(lshift)
++BIGNUM_SHIFT(rshift)
+ 
+ #define BIGNUM_SELF_SHIFT(func)				\
+     /*							\
+@@ -494,8 +494,8 @@
+ 		ossl_raise(eBNError, NULL);		\
+ 	return self;					\
+     }
+-BIGNUM_SELF_SHIFT(lshift);
+-BIGNUM_SELF_SHIFT(rshift);
++BIGNUM_SELF_SHIFT(lshift)
++BIGNUM_SELF_SHIFT(rshift)
+ 
+ #define BIGNUM_RAND(func)					\
+     /*								\
+@@ -528,8 +528,8 @@
+ 	WrapBN(klass, obj, result);				\
+ 	return obj;						\
+     }
+-BIGNUM_RAND(rand);
+-BIGNUM_RAND(pseudo_rand);
++BIGNUM_RAND(rand)
++BIGNUM_RAND(pseudo_rand)
+ 
+ #define BIGNUM_RAND_RANGE(func)					\
+     /*								\
+@@ -552,8 +552,8 @@
+ 	WrapBN(klass, obj, result);				\
+ 	return obj;						\
+     }
+-BIGNUM_RAND_RANGE(rand);
+-BIGNUM_RAND_RANGE(pseudo_rand);
++BIGNUM_RAND_RANGE(rand)
++BIGNUM_RAND_RANGE(pseudo_rand)
+ 
+ /*
+  * call-seq:
+@@ -608,8 +608,8 @@
+ 	GetBN(self, bn);			\
+ 	return INT2FIX(BN_##func(bn));		\
+     }
+-BIGNUM_NUM(num_bytes);
+-BIGNUM_NUM(num_bits);
++BIGNUM_NUM(num_bytes)
++BIGNUM_NUM(num_bits)
+ 
+ static VALUE
+ ossl_bn_copy(VALUE self, VALUE other)
+@@ -642,8 +642,8 @@
+ 	GetBN(self, bn1);				\
+ 	return INT2FIX(BN_##func(bn1, bn2));		\
+     }
+-BIGNUM_CMP(cmp);
+-BIGNUM_CMP(ucmp);
++BIGNUM_CMP(cmp)
++BIGNUM_CMP(ucmp)
+ 
+ static VALUE
+ ossl_bn_eql(VALUE self, VALUE other)
+diff -Naur source.old/ext/openssl/ossl_bn.h source/ext/openssl/ossl_bn.h
+--- source.old/ext/openssl/ossl_bn.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_bn.h	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_bn.h 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl.c source/ext/openssl/ossl.c
+--- source.old/ext/openssl/ossl.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl.c	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -272,10 +272,9 @@
+ /*
+  * Errors
+  */
+-void
+-ossl_raise(VALUE exc, const char *fmt, ...)
++static VALUE
++ossl_make_error(VALUE exc, const char *fmt, va_list args)
+ {
+-    va_list args;
+     char buf[BUFSIZ];
+     const char *msg;
+     long e;
+@@ -287,17 +286,14 @@
+     e = ERR_peek_error();
+ #endif
+     if (fmt) {
+-	va_start(args, fmt);
+ 	len = vsnprintf(buf, BUFSIZ, fmt, args);
+-	va_end(args);
+     }
+     if (len < BUFSIZ && e) {
+ 	if (dOSSL == Qtrue) /* FULL INFO */
+ 	    msg = ERR_error_string(e, NULL);
+ 	else
+ 	    msg = ERR_reason_error_string(e);
+-	fmt = len ? ": %s" : "%s";
+-	len += snprintf(buf+len, BUFSIZ-len, fmt, msg);
++	len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg);
+     }
+     if (dOSSL == Qtrue){ /* show all errors on the stack */
+ 	while ((e = ERR_get_error()) != 0){
+@@ -307,7 +303,29 @@
+     ERR_clear_error();
+ 
+     if(len > BUFSIZ) len = strlen(buf);
+-    rb_exc_raise(rb_exc_new(exc, buf, len));
++    return rb_exc_new(exc, buf, len);
++}
++
++void
++ossl_raise(VALUE exc, const char *fmt, ...)
++{
++    va_list args;
++    VALUE err;
++    va_start(args, fmt);
++    err = ossl_make_error(exc, fmt, args);
++    va_end(args);
++    rb_exc_raise(err);
++}
++
++VALUE
++ossl_exc_new(VALUE exc, const char *fmt, ...)
++{
++    va_list args;
++    VALUE err;
++    va_start(args, fmt);
++    err = ossl_make_error(exc, fmt, args);
++    va_end(args);
++    return err;
+ }
+ 
+ /*
+diff -Naur source.old/ext/openssl/ossl_cipher.c source/ext/openssl/ossl_cipher.c
+--- source.old/ext/openssl/ossl_cipher.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_cipher.c	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_cipher.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -67,7 +67,7 @@
+ {
+     if (ctx) {
+ 	EVP_CIPHER_CTX_cleanup(ctx);
+-	free(ctx);
++        ruby_xfree(ctx);
+     }
+ }
+ 
+@@ -124,12 +124,14 @@
+     return self;
+ }
+ 
++#ifdef HAVE_OBJ_NAME_DO_ALL_SORTED
+ static void*
+ add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary)
+ {
+     rb_ary_push(ary, rb_str_new2(name->name));
+     return NULL;
+ }
++#endif
+ 
+ /*
+  *  call-seq:
+@@ -186,7 +188,7 @@
+ 	 * We deprecated the arguments for this method, but we decided
+ 	 * keeping this behaviour for backward compatibility.
+ 	 */
+-	const char *cname  = rb_class2name(rb_obj_class(self));
++	char *cname  = rb_class2name(rb_obj_class(self));
+ 	rb_warn("argumtents for %s#encrypt and %s#decrypt were deprecated; "
+                 "use %s#pkcs5_keyivgen to derive key and IV",
+                 cname, cname, cname);
+@@ -307,7 +309,7 @@
+ static VALUE
+ ossl_cipher_update_deprecated(VALUE self, VALUE data)
+ {
+-    const char *cname;
++    char *cname;
+ 
+     cname = rb_class2name(rb_obj_class(self));
+     rb_warning("%s#<< is deprecated; use %s#update instead", cname, cname);
+diff -Naur source.old/ext/openssl/ossl_cipher.h source/ext/openssl/ossl_cipher.h
+--- source.old/ext/openssl/ossl_cipher.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_cipher.h	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_cipher.h 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_config.c source/ext/openssl/ossl_config.c
+--- source.old/ext/openssl/ossl_config.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_config.c	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_config.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -158,14 +158,6 @@
+     return self;
+ }
+ 
+-static void
+-rb_ossl_config_modify_check(VALUE config)
+-{
+-    if (OBJ_FROZEN(config)) rb_error_frozen("OpenSSL::Config");
+-    if (!OBJ_TAINTED(config) && rb_safe_level() >= 4)
+-	rb_raise(rb_eSecurityError, "Insecure: can't modify OpenSSL config");
+-}
+-
+ static VALUE
+ ossl_config_add_value(VALUE self, VALUE section, VALUE name, VALUE value)
+ {
+@@ -175,7 +167,6 @@
+     CONF *conf;
+     CONF_VALUE *sv, *cv;
+ 
+-    rb_ossl_config_modify_check(self);
+     StringValue(section);
+     StringValue(name);
+     StringValue(value);
+@@ -201,6 +192,25 @@
+ #endif
+ }
+ 
++static void
++rb_ossl_config_modify_check(VALUE config)
++{
++    if (OBJ_FROZEN(config)) rb_error_frozen("OpenSSL::Config");
++    if (!OBJ_TAINTED(config) && rb_safe_level() >= 4)
++	rb_raise(rb_eSecurityError, "Insecure: can't modify OpenSSL config");
++}
++
++static VALUE
++ossl_config_add_value_m(VALUE self, VALUE section, VALUE name, VALUE value)
++{
++#if defined(OSSL_NO_CONF_API)
++    rb_notimplement();
++#else
++    rb_ossl_config_modify_check(self);
++    return ossl_config_add_value(self, section, name, value);
++#endif
++}
++
+ static VALUE
+ ossl_config_get_value(VALUE self, VALUE section, VALUE name)
+ {
+@@ -303,6 +313,12 @@
+ }
+ 
+ #ifdef IMPLEMENT_LHASH_DOALL_ARG_FN
++#define IMPLEMENT_LHASH_DOALL_ARG_FN_098(f_name,o_type,a_type) \
++            void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
++		                o_type a = (o_type)arg1; \
++		                a_type b = (a_type)arg2; \
++		                f_name(a,b); }
++
+ static void
+ get_conf_section(CONF_VALUE *cv, VALUE ary)
+ {
+@@ -310,7 +326,7 @@
+     rb_ary_push(ary, rb_str_new2(cv->section));
+ }
+ 
+-static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE*, VALUE);
++static IMPLEMENT_LHASH_DOALL_ARG_FN_098(get_conf_section, CONF_VALUE*, VALUE)
+ 
+ static VALUE
+ ossl_config_get_sections(VALUE self)
+@@ -348,7 +364,7 @@
+     rb_str_cat2(str, "\n");
+ }
+ 
+-static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE*, VALUE);
++static IMPLEMENT_LHASH_DOALL_ARG_FN_098(dump_conf_value, CONF_VALUE*, VALUE)
+ 
+ static VALUE
+ dump_conf(CONF *conf)
+@@ -392,13 +408,15 @@
+     }
+ }
+ 
+-static IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE*, void*);
++static IMPLEMENT_LHASH_DOALL_ARG_FN_098(each_conf_value, CONF_VALUE*, void*)
+ 
+ static VALUE
+ ossl_config_each(VALUE self)
+ {
+     CONF *conf;
+ 
++    RETURN_ENUMERATOR(self, 0, 0);
++
+     GetConfig(self, conf);
+     lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(each_conf_value), (void*)NULL);
+ 
+@@ -448,11 +466,14 @@
+ void
+ Init_ossl_config()
+ {
++    char *default_config_file;
+     eConfigError = rb_define_class_under(mOSSL, "ConfigError", eOSSLError);
+     cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject);
+ 
++    default_config_file = CONF_get1_default_config_file();
+     rb_define_const(cConfig, "DEFAULT_CONFIG_FILE",
+-		    rb_str_new2(CONF_get1_default_config_file()));
++		    rb_str_new2(default_config_file));
++    OPENSSL_free(default_config_file);
+     rb_include_module(cConfig, rb_mEnumerable);
+     rb_define_singleton_method(cConfig, "parse", ossl_config_s_parse, 1);
+     rb_define_alias(CLASS_OF(cConfig), "load", "new");
+@@ -461,7 +482,7 @@
+     rb_define_method(cConfig, "initialize", ossl_config_initialize, -1);
+     rb_define_method(cConfig, "get_value", ossl_config_get_value, 2);
+     rb_define_method(cConfig, "value", ossl_config_get_value_old, -1);
+-    rb_define_method(cConfig, "add_value", ossl_config_add_value, 3);
++    rb_define_method(cConfig, "add_value", ossl_config_add_value_m, 3);
+     rb_define_method(cConfig, "[]", ossl_config_get_section, 1);
+     rb_define_method(cConfig, "section", ossl_config_get_section_old, 1);
+     rb_define_method(cConfig, "[]=", ossl_config_set_section, 2);
+diff -Naur source.old/ext/openssl/ossl_config.h source/ext/openssl/ossl_config.h
+--- source.old/ext/openssl/ossl_config.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_config.h	2010-08-06 12:43:44.830276265 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_config.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_digest.c source/ext/openssl/ossl_digest.c
+--- source.old/ext/openssl/ossl_digest.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_digest.c	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_digest.c 15600 2008-02-25 08:48:57Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_digest.h source/ext/openssl/ossl_digest.h
+--- source.old/ext/openssl/ossl_digest.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_digest.h	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_digest.h 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_engine.c source/ext/openssl/ossl_engine.c
+--- source.old/ext/openssl/ossl_engine.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_engine.c	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_engine.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>
+  * All rights reserved.
+@@ -61,16 +61,34 @@
+     }
+     StringValue(name);
+ #ifndef OPENSSL_NO_STATIC_ENGINE
++#if HAVE_ENGINE_LOAD_DYNAMIC
+     OSSL_ENGINE_LOAD_IF_MATCH(dynamic);
++#endif
++#if HAVE_ENGINE_LOAD_CSWIFT
+     OSSL_ENGINE_LOAD_IF_MATCH(cswift);
++#endif
++#if HAVE_ENGINE_LOAD_CHIL
+     OSSL_ENGINE_LOAD_IF_MATCH(chil);
++#endif
++#if HAVE_ENGINE_LOAD_ATALLA
+     OSSL_ENGINE_LOAD_IF_MATCH(atalla);
++#endif
++#if HAVE_ENGINE_LOAD_NURON
+     OSSL_ENGINE_LOAD_IF_MATCH(nuron);
++#endif
++#if HAVE_ENGINE_LOAD_UBSEC
+     OSSL_ENGINE_LOAD_IF_MATCH(ubsec);
++#endif
++#if HAVE_ENGINE_LOAD_AEP
+     OSSL_ENGINE_LOAD_IF_MATCH(aep);
++#endif
++#if HAVE_ENGINE_LOAD_SUREWARE
+     OSSL_ENGINE_LOAD_IF_MATCH(sureware);
++#endif
++#if HAVE_ENGINE_LOAD_4758CCA
+     OSSL_ENGINE_LOAD_IF_MATCH(4758cca);
+ #endif
++#endif
+ #ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
+     OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);
+ #endif
+@@ -119,7 +137,7 @@
+     if(!ENGINE_init(e))
+ 	ossl_raise(eEngineError, NULL);
+     ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK,
+-		0, NULL, (void(*)())ossl_pem_passwd_cb);
++                0, NULL, (void(*)(void))ossl_pem_passwd_cb);
+     ERR_clear_error();
+ 
+     return obj;
+diff -Naur source.old/ext/openssl/ossl_engine.h source/ext/openssl/ossl_engine.h
+--- source.old/ext/openssl/ossl_engine.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_engine.h	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_engine.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>
+  * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>
+diff -Naur source.old/ext/openssl/ossl.h source/ext/openssl/ossl.h
+--- source.old/ext/openssl/ossl.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl.h	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl.h 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -111,10 +111,7 @@
+  * Compatibility
+  */
+ #if OPENSSL_VERSION_NUMBER >= 0x10000000L
+-#define OSSL_MORE_CONST const
+ #define STACK _STACK
+-#else
+-#define OSSL_MORE_CONST
+ #endif
+ 
+ /*
+@@ -149,6 +146,7 @@
+  */
+ #define OSSL_ErrMsg() ERR_reason_error_string(ERR_get_error())
+ NORETURN(void ossl_raise(VALUE, const char *, ...));
++VALUE ossl_exc_new(VALUE, const char *, ...);
+ 
+ /*
+  * Verify callback
+@@ -177,10 +175,10 @@
+ extern VALUE dOSSL;
+ 
+ #if defined(HAVE_VA_ARGS_MACRO)
+-#define OSSL_Debug(fmt, ...) do { \
++#define OSSL_Debug(...) do { \
+   if (dOSSL == Qtrue) { \
+     fprintf(stderr, "OSSL_DEBUG: "); \
+-    fprintf(stderr, fmt, ##__VA_ARGS__); \
++    fprintf(stderr, __VA_ARGS__); \
+     fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \
+   } \
+ } while (0)
+diff -Naur source.old/ext/openssl/ossl_hmac.c source/ext/openssl/ossl_hmac.c
+--- source.old/ext/openssl/ossl_hmac.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_hmac.c	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_hmac.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -42,7 +42,7 @@
+ ossl_hmac_free(HMAC_CTX *ctx)
+ {
+     HMAC_CTX_cleanup(ctx);
+-    free(ctx);
++    ruby_xfree(ctx);
+ }
+ 
+ static VALUE
+diff -Naur source.old/ext/openssl/ossl_hmac.h source/ext/openssl/ossl_hmac.h
+--- source.old/ext/openssl/ossl_hmac.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_hmac.h	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_hmac.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ns_spki.c source/ext/openssl/ossl_ns_spki.c
+--- source.old/ext/openssl/ossl_ns_spki.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ns_spki.c	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ns_spki.c 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ns_spki.h source/ext/openssl/ossl_ns_spki.h
+--- source.old/ext/openssl/ossl_ns_spki.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ns_spki.h	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ns_spki.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ocsp.c source/ext/openssl/ossl_ocsp.c
+--- source.old/ext/openssl/ossl_ocsp.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ocsp.c	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ocsp.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>
+  * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>
+@@ -378,7 +378,7 @@
+ 	ossl_raise(eOCSPError, NULL);
+     str = rb_str_new(0, len);
+     p = RSTRING_PTR(str);
+-    if(i2d_OCSP_RESPONSE(res, NULL) <= 0)
++    if(i2d_OCSP_RESPONSE(res, &p) <= 0)
+ 	ossl_raise(eOCSPError, NULL);
+     ossl_str_adjust(str, p);
+ 
+diff -Naur source.old/ext/openssl/ossl_ocsp.h source/ext/openssl/ossl_ocsp.h
+--- source.old/ext/openssl/ossl_ocsp.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ocsp.h	2010-08-06 12:43:44.834275985 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ocsp.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>
+  * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>
+diff -Naur source.old/ext/openssl/ossl_pkcs12.c source/ext/openssl/ossl_pkcs12.c
+--- source.old/ext/openssl/ossl_pkcs12.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs12.c	2010-08-06 12:43:44.834275985 +0200
+@@ -1,7 +1,7 @@
+ /*
+  * This program is licenced under the same licence as Ruby.
+  * (See the file 'LICENCE'.)
+- * $Id$
++ * $Id: ossl_pkcs12.c 12496 2007-06-08 15:02:04Z technorama $
+  */
+ #include "ossl.h"
+ 
+diff -Naur source.old/ext/openssl/ossl_pkcs12.h source/ext/openssl/ossl_pkcs12.h
+--- source.old/ext/openssl/ossl_pkcs12.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs12.h	2010-08-06 12:43:44.834275985 +0200
+@@ -1,7 +1,7 @@
+ /*
+  * This program is licenced under the same licence as Ruby.
+  * (See the file 'LICENCE'.)
+- * $Id$
++ * $Id: ossl_pkcs12.h 12496 2007-06-08 15:02:04Z technorama $
+  */
+ #if !defined(_OSSL_PKCS12_H_)
+ #define _OSSL_PKCS12_H_
+diff -Naur source.old/ext/openssl/ossl_pkcs5.c source/ext/openssl/ossl_pkcs5.c
+--- source.old/ext/openssl/ossl_pkcs5.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs5.c	2010-08-06 12:43:44.834275985 +0200
+@@ -29,14 +29,17 @@
+     VALUE str;
+     const EVP_MD *md;
+     int len = NUM2INT(keylen);
++    unsigned char* salt_p;
++    unsigned char* str_p;
+ 
+     StringValue(pass);
+     StringValue(salt);
+     md = GetDigestPtr(digest);
+-
+     str = rb_str_new(0, len);
++    salt_p = (unsigned char*)RSTRING_PTR(salt);
++    str_p = (unsigned char*)RSTRING_PTR(str);
+ 
+-    if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LEN(pass), RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2INT(iter), md, len, RSTRING_PTR(str)) != 1)
++    if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LEN(pass), salt_p, RSTRING_LEN(salt), NUM2INT(iter), md, len, str_p) != 1)
+         ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");
+ 
+     return str;
+diff -Naur source.old/ext/openssl/ossl_pkcs7.c source/ext/openssl/ossl_pkcs7.c
+--- source.old/ext/openssl/ossl_pkcs7.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs7.c	2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkcs7.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_pkcs7.h source/ext/openssl/ossl_pkcs7.h
+--- source.old/ext/openssl/ossl_pkcs7.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkcs7.h	2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkcs7.h 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_pkey.c source/ext/openssl/ossl_pkey.c
+--- source.old/ext/openssl/ossl_pkey.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey.c	2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -177,7 +177,7 @@
+     str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
+     if (!EVP_SignFinal(&ctx, RSTRING_PTR(str), &buf_len, pkey))
+ 	ossl_raise(ePKeyError, NULL);
+-    assert(buf_len <= RSTRING_LEN(str));
++    assert((long)buf_len <= RSTRING_LEN(str));
+     rb_str_set_len(str, buf_len);
+ 
+     return str;
+diff -Naur source.old/ext/openssl/ossl_pkey_dh.c source/ext/openssl/ossl_pkey_dh.c
+--- source.old/ext/openssl/ossl_pkey_dh.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_dh.c	2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey_dh.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -415,10 +415,10 @@
+     return str;
+ }
+ 
+-OSSL_PKEY_BN(dh, p);
+-OSSL_PKEY_BN(dh, g);
+-OSSL_PKEY_BN(dh, pub_key);
+-OSSL_PKEY_BN(dh, priv_key);
++OSSL_PKEY_BN(dh, p)
++OSSL_PKEY_BN(dh, g)
++OSSL_PKEY_BN(dh, pub_key)
++OSSL_PKEY_BN(dh, priv_key)
+ 
+ /*
+  * -----BEGIN DH PARAMETERS-----
+diff -Naur source.old/ext/openssl/ossl_pkey_dsa.c source/ext/openssl/ossl_pkey_dsa.c
+--- source.old/ext/openssl/ossl_pkey_dsa.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_dsa.c	2010-08-06 12:43:44.838276125 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey_dsa.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -432,11 +432,11 @@
+     return Qfalse;
+ }
+ 
+-OSSL_PKEY_BN(dsa, p);
+-OSSL_PKEY_BN(dsa, q);
+-OSSL_PKEY_BN(dsa, g);
+-OSSL_PKEY_BN(dsa, pub_key);
+-OSSL_PKEY_BN(dsa, priv_key);
++OSSL_PKEY_BN(dsa, p)
++OSSL_PKEY_BN(dsa, q)
++OSSL_PKEY_BN(dsa, g)
++OSSL_PKEY_BN(dsa, pub_key)
++OSSL_PKEY_BN(dsa, priv_key)
+ 
+ /*
+  * INIT
+diff -Naur source.old/ext/openssl/ossl_pkey_ec.c source/ext/openssl/ossl_pkey_ec.c
+--- source.old/ext/openssl/ossl_pkey_ec.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_ec.c	2010-08-06 12:43:44.838276125 +0200
+@@ -463,8 +463,10 @@
+     BIO *out;
+     int i = -1;
+     int private = 0;
++#if 0  /* unused now */
+     EVP_CIPHER *cipher = NULL;
+     char *password = NULL;
++#endif
+     VALUE str;
+ 
+     Require_EC_KEY(self, ec);
+@@ -484,13 +486,18 @@
+     switch(format) {
+     case EXPORT_PEM:
+     	if (private) {
++#if 0  /* unused now */
+     	    if (cipher || password)
+ /* BUG: finish cipher/password key export */
+     	        rb_notimplement();
+             i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
++#endif
++            i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL);
+     	} else {
++#if 0  /* unused now */
+     	    if (cipher || password)
+                 rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
++#endif
+ 
+             i = PEM_write_bio_EC_PUBKEY(out, ec);
+         }
+@@ -498,13 +505,17 @@
+     	break;
+     case EXPORT_DER:
+         if (private) {
++#if 0  /* unused now */
+     	    if (cipher || password)
+                 rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
++#endif
+ 
+             i = i2d_ECPrivateKey_bio(out, ec);
+         } else {
++#if 0  /* unused now */
+     	    if (cipher || password)
+                 rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
++#endif
+ 
+             i = i2d_EC_PUBKEY_bio(out, ec);
+         }
+@@ -670,7 +681,7 @@
+ 
+ /*
+  *  call-seq:
+- *     key.dsa_verify(data, sig)   => true or false
++ *     key.dsa_verify_asn1(data, sig)   => true or false
+  *
+  *  See the OpenSSL documentation for ECDSA_verify()
+  */
+@@ -695,7 +706,7 @@
+ {
+     if (!ec_group->dont_free && ec_group->group)
+         EC_GROUP_clear_free(ec_group->group);
+-    free(ec_group);
++    ruby_xfree(ec_group);
+ }
+ 
+ static VALUE ossl_ec_group_alloc(VALUE klass)
+@@ -1201,7 +1212,7 @@
+ {
+     if (!ec_point->dont_free && ec_point->point)
+         EC_POINT_clear_free(ec_point->point);
+-    free(ec_point);
++    ruby_xfree(ec_point);
+ }
+ 
+ static VALUE ossl_ec_point_alloc(VALUE klass)
+diff -Naur source.old/ext/openssl/ossl_pkey.h source/ext/openssl/ossl_pkey.h
+--- source.old/ext/openssl/ossl_pkey.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey.h	2010-08-06 12:43:44.842276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey.h 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_pkey_rsa.c source/ext/openssl/ossl_pkey_rsa.c
+--- source.old/ext/openssl/ossl_pkey_rsa.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_pkey_rsa.c	2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_pkey_rsa.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -519,14 +519,14 @@
+ }
+  */
+ 
+-OSSL_PKEY_BN(rsa, n);
+-OSSL_PKEY_BN(rsa, e);
+-OSSL_PKEY_BN(rsa, d);
+-OSSL_PKEY_BN(rsa, p);
+-OSSL_PKEY_BN(rsa, q);
+-OSSL_PKEY_BN(rsa, dmp1);
+-OSSL_PKEY_BN(rsa, dmq1);
+-OSSL_PKEY_BN(rsa, iqmp);
++OSSL_PKEY_BN(rsa, n)
++OSSL_PKEY_BN(rsa, e)
++OSSL_PKEY_BN(rsa, d)
++OSSL_PKEY_BN(rsa, p)
++OSSL_PKEY_BN(rsa, q)
++OSSL_PKEY_BN(rsa, dmp1)
++OSSL_PKEY_BN(rsa, dmq1)
++OSSL_PKEY_BN(rsa, iqmp)
+ 
+ /*
+  * INIT
+diff -Naur source.old/ext/openssl/ossl_rand.c source/ext/openssl/ossl_rand.c
+--- source.old/ext/openssl/ossl_rand.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_rand.c	2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_rand.c 16692 2008-05-29 18:15:50Z knu $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_rand.h source/ext/openssl/ossl_rand.h
+--- source.old/ext/openssl/ossl_rand.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_rand.h	2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_rand.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ssl.c source/ext/openssl/ossl_ssl.c
+--- source.old/ext/openssl/ossl_ssl.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ssl.c	2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ssl.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2000-2002  GOTOU Yuuzou <gotoyuzo@notwork.org>
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+@@ -95,7 +95,7 @@
+  */
+ struct {
+     const char *name;
+-    OSSL_MORE_CONST SSL_METHOD *(*func)(void);
++    SSL_METHOD *(*func)(void);
+ } ossl_ssl_method_tab[] = {
+ #define OSSL_SSL_METHOD_ENTRY(name) { #name, name##_method }
+     OSSL_SSL_METHOD_ENTRY(TLSv1),
+@@ -144,7 +144,7 @@
+ static VALUE
+ ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
+ {
+-    OSSL_MORE_CONST SSL_METHOD *method = NULL;
++    SSL_METHOD *method = NULL;
+     const char *s;
+     int i;
+ 
+@@ -585,7 +585,7 @@
+ }
+ 
+ static VALUE
+-ossl_ssl_cipher_to_ary(OSSL_MORE_CONST SSL_CIPHER *cipher)
++ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
+ {
+     VALUE ary;
+     int bits, alg_bits;
+@@ -829,7 +829,7 @@
+         rb_raise(rb_eArgError, "arg must be Time or nil");
+     }
+ 
+-    SSL_CTX_flush_sessions(ctx, tm);
++    SSL_CTX_flush_sessions(ctx, (long)tm);
+ 
+     return self;
+ }
+@@ -1199,7 +1199,7 @@
+     num = sk_X509_num(chain);
+     ary = rb_ary_new2(num);
+     for (i = 0; i < num; i++){
+-	cert = (X509*)sk_X509_value(chain, i);
++	cert = sk_X509_value(chain, i);
+ 	rb_ary_push(ary, ossl_x509_new(cert));
+     }
+ 
+@@ -1214,7 +1214,7 @@
+ ossl_ssl_get_cipher(VALUE self)
+ {
+     SSL *ssl;
+-    OSSL_MORE_CONST SSL_CIPHER *cipher;
++    SSL_CIPHER *cipher;
+ 
+     Data_Get_Struct(self, SSL, ssl);
+     if (!ssl) {
+diff -Naur source.old/ext/openssl/ossl_ssl.h source/ext/openssl/ossl_ssl.h
+--- source.old/ext/openssl/ossl_ssl.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ssl.h	2010-08-06 12:43:44.846276474 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_ssl.h 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_ssl_session.c source/ext/openssl/ossl_ssl_session.c
+--- source.old/ext/openssl/ossl_ssl_session.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_ssl_session.c	2010-08-06 12:43:44.846276474 +0200
+@@ -86,9 +86,18 @@
+ 	GetSSLSession(val1, ctx1);
+ 	SafeGetSSLSession(val2, ctx2);
+ 
+-	switch (SSL_SESSION_cmp(ctx1, ctx2)) {
+-	case 0:		return Qtrue;
+-	default:	return Qfalse;
++	/*
++	 * OpenSSL 1.0.0betas do not have non-static SSL_SESSION_cmp.
++	 * ssl_session_cmp (was SSL_SESSION_cmp in 0.9.8) is for lhash
++	 * comparing so we should not depend on it.  Just compare sessions
++	 * by version and id.
++	 */
++	if ((ctx1->ssl_version == ctx2->ssl_version) &&
++	    (ctx1->session_id_length == ctx2->session_id_length) &&
++	    (memcmp(ctx1->session_id, ctx2->session_id, ctx1->session_id_length) == 0)) {
++	    return Qtrue;
++	} else {
++	    return Qfalse;
+ 	}
+ }
+ 
+@@ -100,7 +109,7 @@
+ static VALUE ossl_ssl_session_get_time(VALUE self)
+ {
+ 	SSL_SESSION *ctx;
+-	time_t t;
++	long t;
+ 
+ 	GetSSLSession(self, ctx);
+ 
+@@ -122,20 +131,20 @@
+ static VALUE ossl_ssl_session_get_timeout(VALUE self)
+ {
+ 	SSL_SESSION *ctx;
+-	time_t t;
++	long t;
+ 
+ 	GetSSLSession(self, ctx);
+ 
+ 	t = SSL_SESSION_get_timeout(ctx);
+ 
+-	return ULONG2NUM(t);
++	return LONG2NUM(t);
+ }
+ 
+ #define SSLSESSION_SET_TIME(func)						\
+ 	static VALUE ossl_ssl_session_set_##func(VALUE self, VALUE time_v)	\
+ 	{									\
+ 		SSL_SESSION *ctx;						\
+-		time_t t;							\
++		long t;								\
+ 										\
+ 		GetSSLSession(self, ctx);					\
+ 										\
+@@ -147,7 +156,7 @@
+ 			rb_raise(rb_eArgError, "unknown type");			\
+ 		}								\
+ 										\
+-		t = NUM2ULONG(time_v);						\
++		t = NUM2LONG(time_v);						\
+ 										\
+ 		SSL_SESSION_set_##func(ctx, t);					\
+ 										\
+diff -Naur source.old/ext/openssl/ossl_version.h source/ext/openssl/ossl_version.h
+--- source.old/ext/openssl/ossl_version.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_version.h	2010-08-06 12:43:44.850276055 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_version.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509attr.c source/ext/openssl/ossl_x509attr.c
+--- source.old/ext/openssl/ossl_x509attr.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509attr.c	2010-08-06 12:43:44.850276055 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509attr.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -93,7 +93,7 @@
+ {
+     VALUE oid, value;
+     X509_ATTRIBUTE *attr;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+ 
+     GetX509Attr(self, attr);
+     if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
+diff -Naur source.old/ext/openssl/ossl_x509.c source/ext/openssl/ossl_x509.c
+--- source.old/ext/openssl/ossl_x509.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509.c 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509cert.c source/ext/openssl/ossl_x509cert.c
+--- source.old/ext/openssl/ossl_x509cert.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509cert.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509cert.c 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509crl.c source/ext/openssl/ossl_x509crl.c
+--- source.old/ext/openssl/ossl_x509crl.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509crl.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509crl.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -262,7 +262,7 @@
+     VALUE ary, revoked;
+ 
+     GetX509CRL(self, crl);
+-    num = sk_X509_CRL_num(X509_CRL_get_REVOKED(crl));
++    num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
+     if (num < 0) {
+ 	OSSL_Debug("num < 0???");
+ 	return rb_ary_new();
+@@ -270,7 +270,7 @@
+     ary = rb_ary_new2(num);
+     for(i=0; i<num; i++) {
+ 	/* NO DUP - don't free! */
+-	rev = (X509_REVOKED *)sk_X509_CRL_value(X509_CRL_get_REVOKED(crl), i);
++	rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
+ 	revoked = ossl_x509revoked_new(rev);
+ 	rb_ary_push(ary, revoked);
+     }
+diff -Naur source.old/ext/openssl/ossl_x509ext.c source/ext/openssl/ossl_x509ext.c
+--- source.old/ext/openssl/ossl_x509ext.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509ext.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509ext.c 28004 2010-05-24 23:58:49Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -198,6 +198,7 @@
+ 	ossl_x509extfactory_set_subject_req(self, subject_req);
+     if (!NIL_P(crl))
+ 	ossl_x509extfactory_set_crl(self, crl);
++    rb_iv_set(self, "@config", Qnil);
+ 
+     return self;
+ }
+@@ -220,7 +221,6 @@
+ #ifdef HAVE_X509V3_EXT_NCONF_NID
+     VALUE rconf;
+     CONF *conf;
+-    ID i_config;
+ #else
+     static LHASH *empty_lhash;
+ #endif
+@@ -237,11 +237,7 @@
+     rb_str_append(valstr, value);
+     GetX509ExtFactory(self, ctx);
+ #ifdef HAVE_X509V3_EXT_NCONF_NID
+-    i_config = rb_intern("@config");
+-    if (rb_ivar_defined(self, i_config))
+-	rconf = rb_ivar_get(self, i_config);
+-    else
+-	rconf = Qnil;
++    rconf = rb_iv_get(self, "@config");
+     conf = NIL_P(rconf) ? NULL : GetConfigPtr(rconf);
+     ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
+ #else
+@@ -278,7 +274,7 @@
+ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)
+ {
+     VALUE oid, value, critical;
+-    OSSL_MORE_CONST unsigned char *p;
++    unsigned char *p;
+     X509_EXTENSION *ext;
+ 
+     GetX509Ext(self, ext);
+@@ -328,14 +324,15 @@
+ 	ossl_raise(eX509ExtError, "malloc error");
+     memcpy(s, RSTRING_PTR(data), RSTRING_LEN(data));
+     if(!(asn1s = ASN1_OCTET_STRING_new())){
+-	free(s);
++        OPENSSL_free(s);
+ 	ossl_raise(eX509ExtError, NULL);
+     }
+     if(!M_ASN1_OCTET_STRING_set(asn1s, s, RSTRING_LEN(data))){
+-	free(s);
++        OPENSSL_free(s);
+ 	ASN1_OCTET_STRING_free(asn1s);
+ 	ossl_raise(eX509ExtError, NULL);
+     }
++    OPENSSL_free(s);
+     GetX509Ext(self, ext);
+     X509_EXTENSION_set_data(ext, asn1s);
+ 
+diff -Naur source.old/ext/openssl/ossl_x509.h source/ext/openssl/ossl_x509.h
+--- source.old/ext/openssl/ossl_x509.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509.h	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509.h 11708 2007-02-12 23:01:19Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509name.c source/ext/openssl/ossl_x509name.c
+--- source.old/ext/openssl/ossl_x509name.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509name.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509name.c 28367 2010-06-21 09:18:59Z shyouhei $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+@@ -137,9 +137,12 @@
+ 	else{
+ 	    unsigned char *p;
+ 	    VALUE str = ossl_to_der_if_possible(arg);
++	    X509_NAME *x;
+ 	    StringValue(str);
+-	    p = RSTRING_PTR(str);
+-	    if(!d2i_X509_NAME((X509_NAME**)&DATA_PTR(self), &p, RSTRING_LEN(str))){
++	    p = (unsigned char *)RSTRING_PTR(str);
++	    x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str));
++	    DATA_PTR(self) = name;
++	    if(!x){
+ 		ossl_raise(eX509NameError, NULL);
+ 	    }
+ 	}
+@@ -303,6 +306,27 @@
+     return ULONG2NUM(hash);
+ }
+ 
++#ifdef HAVE_X509_NAME_HASH_OLD
++/*
++ * call-seq:
++ *    name.hash_old => integer
++ *
++ * hash_old returns MD5 based hash used in OpenSSL 0.9.X.
++ */
++static VALUE
++ossl_x509name_hash_old(VALUE self)
++{
++    X509_NAME *name;
++    unsigned long hash;
++
++    GetX509Name(self, name);
++
++    hash = X509_NAME_hash_old(name);
++
++    return ULONG2NUM(hash);
++}
++#endif
++
+ /*
+  * call-seq:
+  *    name.to_der => string
+@@ -348,6 +372,9 @@
+     rb_define_alias(cX509Name, "<=>", "cmp");
+     rb_define_method(cX509Name, "eql?", ossl_x509name_eql, 1);
+     rb_define_method(cX509Name, "hash", ossl_x509name_hash, 0);
++#ifdef HAVE_X509_NAME_HASH_OLD
++    rb_define_method(cX509Name, "hash_old", ossl_x509name_hash_old, 0);
++#endif
+     rb_define_method(cX509Name, "to_der", ossl_x509name_to_der, 0);
+ 
+     utf8str = INT2NUM(V_ASN1_UTF8STRING);
+diff -Naur source.old/ext/openssl/ossl_x509req.c source/ext/openssl/ossl_x509req.c
+--- source.old/ext/openssl/ossl_x509req.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509req.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509req.c 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509revoked.c source/ext/openssl/ossl_x509revoked.c
+--- source.old/ext/openssl/ossl_x509revoked.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509revoked.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509revoked.c 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ossl_x509store.c source/ext/openssl/ossl_x509store.c
+--- source.old/ext/openssl/ossl_x509store.c	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ossl_x509store.c	2010-08-06 12:43:44.858276335 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ossl_x509store.c 16691 2008-05-29 17:45:47Z knu $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.
+diff -Naur source.old/ext/openssl/ruby_missing.h source/ext/openssl/ruby_missing.h
+--- source.old/ext/openssl/ruby_missing.h	2010-06-03 11:01:09.000000000 +0200
++++ source/ext/openssl/ruby_missing.h	2010-08-06 12:43:44.862276614 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * $Id$
++ * $Id: ruby_missing.h 12496 2007-06-08 15:02:04Z technorama $
+  * 'OpenSSL for Ruby' project
+  * Copyright (C) 2001-2003  Michal Rokos <m.rokos@sh.cvut.cz>
+  * All rights reserved.

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/012_webrick-CVE-2010-0541.patch b/patchsets/patches-ee-1.8.7-2010.02-r1/012_webrick-CVE-2010-0541.patch
new file mode 100644
index 0000000..5ae9cba
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/012_webrick-CVE-2010-0541.patch
@@ -0,0 +1,15 @@
+Patch for CVE-2010-0541
+
+Index: httpresponse.rb
+===================================================================
+--- lib/webrick/httpresponse.rb	(revision 28759)
++++ lib/webrick/httpresponse.rb	(working copy)
+@@ -208,7 +208,7 @@
+         @keep_alive = false
+         self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR
+       end
+-      @header['content-type'] = "text/html"
++      @header['content-type'] = "text/html; charset=ISO-8859-1"
+ 
+       if respond_to?(:create_error_page)
+         create_error_page()

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/999-fast-threading-NOAPPLY.diff b/patchsets/patches-ee-1.8.7-2010.02-r1/999-fast-threading-NOAPPLY.diff
new file mode 100644
index 0000000..9ffb0de
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/999-fast-threading-NOAPPLY.diff
@@ -0,0 +1,1320 @@
+Phusion ship their code with this patch enabled. bug 335569.
+Using this to revert the changes. DON'T REMOVE the NOAPPLY from the name. -a3li
+
+diff --git a/eval.c b/eval.c
+index 77121fe..b6ef5b6 100644
+--- a/eval.c
++++ b/eval.c
+@@ -73,6 +73,7 @@ char *strrchr _((const char*,const char));
+ #endif
+ 
+ #include <time.h>
++#include <sys/mman.h>
+ 
+ #if defined(HAVE_FCNTL_H) || defined(_WIN32)
+ #include <fcntl.h>
+@@ -1058,7 +1059,7 @@ static struct tag *prot_tag;
+     _tag.blkid = 0;			\
+     prot_tag = &_tag
+ 
+-#define PROT_NONE   Qfalse	/* 0 */
++#define PROT_EMPTY   Qfalse	/* 0 */
+ #define PROT_THREAD Qtrue	/* 2 */
+ #define PROT_FUNC   INT2FIX(0)	/* 1 */
+ #define PROT_LOOP   INT2FIX(1)	/* 3 */
+@@ -1280,7 +1281,7 @@ error_print()
+ 
+     if (NIL_P(ruby_errinfo)) return;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     errat = EXEC_TAG() ? Qnil : get_backtrace(ruby_errinfo);
+     if (EXEC_TAG()) goto error;
+     if (NIL_P(errat)){
+@@ -1436,7 +1437,7 @@ ruby_init()
+     /* default visibility is private at toplevel */
+     SCOPE_SET(SCOPE_PRIVATE);
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+ 	rb_call_inits();
+ 	ruby_class = rb_cObject;
+@@ -1570,7 +1571,7 @@ ruby_options(argc, argv)
+     int state;
+ 
+     Init_stack((void*)&state);
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+ 	ruby_process_options(argc, argv);
+     }
+@@ -1587,7 +1588,7 @@ void rb_exec_end_proc _((void));
+ static void
+ ruby_finalize_0()
+ {
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if (EXEC_TAG() == 0) {
+ 	rb_trap_exit();
+     }
+@@ -1626,7 +1627,7 @@ ruby_cleanup(exArg)
+     Init_stack((void *)&state);
+     ruby_finalize_0();
+     errs[0] = ruby_errinfo;
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     PUSH_ITER(ITER_NOT);
+     if ((state = EXEC_TAG()) == 0) {
+ 	rb_thread_cleanup();
+@@ -1677,7 +1678,7 @@ ruby_exec_internal()
+ {
+     int state;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     PUSH_ITER(ITER_NOT);
+     /* default visibility is private at toplevel */
+     SCOPE_SET(SCOPE_PRIVATE);
+@@ -1899,7 +1900,7 @@ rb_eval_cmd(cmd, arg, level)
+     }
+     if (TYPE(cmd) != T_STRING) {
+ 	PUSH_ITER(ITER_NOT);
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	ruby_safe_level = level;
+ 	if ((state = EXEC_TAG()) == 0) {
+ 	    val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr);
+@@ -1921,7 +1922,7 @@ rb_eval_cmd(cmd, arg, level)
+ 
+     ruby_safe_level = level;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     val = (state = EXEC_TAG()) ? Qnil : eval(ruby_top_self, cmd, Qnil, 0, 0);
+     if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
+ 	scope_dup(saved_scope);
+@@ -2433,7 +2434,7 @@ is_defined(self, node, buf)
+ 	val = self;
+ 	if (node->nd_recv == (NODE *)1) goto check_bound;
+       case NODE_CALL:
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	if ((state = EXEC_TAG()) == 0) {
+ 	    val = rb_eval(self, node->nd_recv);
+ 	}
+@@ -2535,7 +2536,7 @@ is_defined(self, node, buf)
+ 	break;
+ 
+       case NODE_COLON2:
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	if ((state = EXEC_TAG()) == 0) {
+ 	    val = rb_eval(self, node->nd_head);
+ 	}
+@@ -2584,7 +2585,7 @@ is_defined(self, node, buf)
+ 	goto again;
+ 
+       default:
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	if ((state = EXEC_TAG()) == 0) {
+ 	    rb_eval(self, node);
+ 	}
+@@ -2789,7 +2790,7 @@ call_trace_func(event, node, self, id, klass)
+ 	    klass = rb_iv_get(klass, "__attached__");
+ 	}
+     }
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     raised = rb_thread_reset_raised(th);
+     if ((state = EXEC_TAG()) == 0) {
+ 	srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
+@@ -3231,7 +3232,7 @@ eval_node_volatile(rescue, VALUE)
+     int state;
+     VALUE result;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+       retry_entry:
+ 	result = rb_eval(self, node->nd_head);
+@@ -3286,7 +3287,7 @@ eval_node_volatile(ensure, VALUE)
+   int state;
+   VALUE result;
+ 
+-  PUSH_TAG(PROT_NONE);
++  PUSH_TAG(PROT_EMPTY);
+   if ((state = EXEC_TAG()) == 0) {
+       result = rb_eval(self, node->nd_head);
+   }
+@@ -3453,7 +3454,7 @@ eval_node_volatile(scope, VALUE)
+   ruby_frame = &frame;
+ 
+   PUSH_SCOPE();
+-  PUSH_TAG(PROT_NONE);
++  PUSH_TAG(PROT_EMPTY);
+   if (node->nd_rval) {
+       saved_cref = ruby_cref;
+       ruby_cref = (NODE*)node->nd_rval;
+@@ -4351,7 +4352,7 @@ module_setup(module, n)
+     }
+ 
+     PUSH_CREF(module);
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+ 	EXEC_EVENT_HOOK(RUBY_EVENT_CLASS, n, ruby_cbase,
+ 			ruby_frame->last_func, ruby_frame->last_class);
+@@ -4758,7 +4759,7 @@ rb_longjmp(tag, mesg)
+ 	VALUE e = ruby_errinfo;
+ 	int status;
+ 
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	if ((status = EXEC_TAG()) == 0) {
+ 	    StringValue(e);
+ 	    warn_printf("Exception `%s' at %s:%d - %s\n",
+@@ -5136,7 +5137,7 @@ rb_yield_0(val, self, klass, flags, avalue)
+     var = block->var;
+ 
+     if (var) {
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	if ((state = EXEC_TAG()) == 0) {
+ 	    NODE *bvar = NULL;
+ 	  block_var:
+@@ -5209,7 +5210,7 @@ rb_yield_0(val, self, klass, flags, avalue)
+     ruby_current_node = node;
+ 
+     PUSH_ITER(block->iter);
+-    PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD);
++    PUSH_TAG(lambda ? PROT_EMPTY : PROT_YIELD);
+     switch (state = EXEC_TAG()) {
+       case TAG_REDO:
+ 	state = 0;
+@@ -5614,7 +5615,7 @@ rb_rescue2(b_proc, data1, r_proc, data2, va_alist)
+     VALUE eclass;
+     va_list args;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     switch (state = EXEC_TAG()) {
+       case TAG_RETRY:
+ 	if (!handle) break;
+@@ -5672,7 +5673,7 @@ rb_protect(proc, data, state)
+     VALUE result;
+     int status;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     cont_protect = (VALUE)rb_node_newnode(NODE_MEMO, cont_protect, 0, 0);
+     if ((status = EXEC_TAG()) == 0) {
+ 	result = (*proc)(data);
+@@ -5696,7 +5697,7 @@ rb_ensure(b_proc, data1, e_proc, data2)
+     VALUE result;
+     VALUE retval;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+ 	result = (*b_proc)(data1);
+     }
+@@ -5723,7 +5724,7 @@ rb_with_disable_interrupt(proc, data)
+ 	int thr_critical = rb_thread_critical;
+ 
+ 	rb_thread_critical = Qtrue;
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	if ((status = EXEC_TAG()) == 0) {
+ 	    result = (*proc)(data);
+ 	}
+@@ -6419,7 +6420,7 @@ rb_funcall_rescue(recv, mid, n, va_alist)
+ 
+     va_init_list(ar, n);
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((status = EXEC_TAG()) == 0) {
+ 	result = vafuncall(recv, mid, n, &ar);
+     }
+@@ -6695,7 +6696,7 @@ eval(self, src, scope, file, line)
+     if (TYPE(ruby_class) == T_ICLASS) {
+ 	ruby_class = RBASIC(ruby_class)->klass;
+     }
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+ 	NODE *node;
+ 
+@@ -6863,7 +6864,7 @@ exec_under(func, under, cbase, args)
+ 
+     mode = scope_vmode;
+     SCOPE_SET(SCOPE_PUBLIC);
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+ 	val = (*func)(args);
+     }
+@@ -7174,7 +7175,7 @@ rb_load(fname, wrap)
+     PUSH_SCOPE();
+     /* default visibility is private at loading toplevel */
+     SCOPE_SET(SCOPE_PRIVATE);
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     state = EXEC_TAG();
+     last_func = ruby_frame->last_func;
+     last_node = ruby_current_node;
+@@ -7233,7 +7234,7 @@ rb_load_protect(fname, wrap, state)
+ {
+     int status;
+ 
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((status = EXEC_TAG()) == 0) {
+ 	rb_load(fname, wrap);
+     }
+@@ -7554,7 +7555,7 @@ rb_require_safe(fname, safe)
+     saved.node = ruby_current_node;
+     saved.func = ruby_frame->last_func;
+     saved.safe = ruby_safe_level;
+-    PUSH_TAG(PROT_NONE);
++    PUSH_TAG(PROT_EMPTY);
+     if ((state = EXEC_TAG()) == 0) {
+ 	VALUE feature, path;
+ 	long handle;
+@@ -8263,7 +8264,7 @@ rb_exec_end_proc()
+ 	tmp_end_procs = link = ephemeral_end_procs;
+ 	ephemeral_end_procs = 0;
+ 	while (link) {
+-	    PUSH_TAG(PROT_NONE);
++	    PUSH_TAG(PROT_EMPTY);
+ 	    if ((status = EXEC_TAG()) == 0) {
+ 		ruby_safe_level = link->safe;
+ 		(*link->func)(link->data);
+@@ -8281,7 +8282,7 @@ rb_exec_end_proc()
+ 	tmp_end_procs = link = end_procs;
+ 	end_procs = 0;
+ 	while (link) {
+-	    PUSH_TAG(PROT_NONE);
++	    PUSH_TAG(PROT_EMPTY);
+ 	    if ((status = EXEC_TAG()) == 0) {
+ 		ruby_safe_level = link->safe;
+ 		(*link->func)(link->data);
+@@ -9020,7 +9021,7 @@ proc_invoke(proc, args, self, klass)
+     ruby_block = &_block;
+     PUSH_ITER(ITER_CUR);
+     ruby_frame->iter = ITER_CUR;
+-    PUSH_TAG(pcall ? PROT_LAMBDA : PROT_NONE);
++    PUSH_TAG(pcall ? PROT_LAMBDA : PROT_EMPTY);
+     state = EXEC_TAG();
+     if (state == 0) {
+ 	proc_set_safe_level(proc);
+@@ -10464,6 +10465,7 @@ win32_set_exception_list(p)
+ int rb_thread_pending = 0;
+ 
+ VALUE rb_cThread;
++static unsigned int rb_thread_stack_size;
+ 
+ extern VALUE rb_last_status;
+ 
+@@ -10679,33 +10681,33 @@ timeofday()
+     return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
+ }
+ 
+-extern VALUE *rb_gc_stack_start;
+-#ifdef __ia64
+-extern VALUE *rb_gc_register_stack_start;
+-#endif
+-
+-#define ADJ(addr) \
+-   if ((size_t)((void *)addr - stkBase) < stkSize) addr=(void *)addr + stkShift
++#define STACK(addr) (th->stk_pos<(VALUE*)(addr) && (VALUE*)(addr)<th->stk_pos+th->stk_len)
++#define ADJ(addr) (void*)(STACK(addr)?(((VALUE*)(addr)-th->stk_pos)+th->stk_ptr):(VALUE*)(addr))
+ static void
+ thread_mark(th)
+     rb_thread_t th;
+ {
+     struct FRAME *frame;
+     struct BLOCK *block;
+-    void *stkBase;
+-    ptrdiff_t stkShift;
+-    size_t stkSize;
+-    
++
+     rb_gc_mark(th->result);
+     rb_gc_mark(th->thread);
+     if (th->join) rb_gc_mark(th->join->thread);
+ 
+-    rb_gc_mark(th->klass);
+-    rb_gc_mark(th->wrapper);
+-    rb_gc_mark((VALUE)th->cref);
++    if (curr_thread == th) {
++      rb_gc_mark(ruby_class);
++      rb_gc_mark(ruby_wrapper);
++      rb_gc_mark((VALUE)ruby_cref);
++      rb_gc_mark((VALUE)ruby_scope);
++      rb_gc_mark((VALUE)ruby_dyna_vars);
++    } else {
++      rb_gc_mark(th->klass);
++      rb_gc_mark(th->wrapper);
++      rb_gc_mark((VALUE)th->cref);
++      rb_gc_mark((VALUE)th->scope);
++      rb_gc_mark((VALUE)th->dyna_vars);
++    }
+ 
+-    rb_gc_mark((VALUE)th->scope);
+-    rb_gc_mark((VALUE)th->dyna_vars);
+     rb_gc_mark(th->errinfo);
+     rb_gc_mark(th->last_status);
+     rb_gc_mark(th->last_line);
+@@ -10715,11 +10717,11 @@ thread_mark(th)
+     rb_gc_mark_maybe(th->sandbox);
+ 
+     /* mark data in copied stack */
+-    if (th == curr_thread) return;
++    if (th == main_thread) return;
+     if (th->status == THREAD_KILLED) return;
+     if (th->stk_len == 0) return;  /* stack not active, no need to mark. */
+-    if (th->stk_ptr) {
+-	rb_gc_mark_locations(th->stk_ptr, th->stk_ptr+th->stk_len);
++    if (th->stk_ptr && th != curr_thread) {
++      rb_gc_mark_locations(th->stk_pos, th->stk_base);
+ #if defined(THINK_C) || defined(__human68k__)
+ 	rb_gc_mark_locations(th->stk_ptr+2, th->stk_ptr+th->stk_len+2);
+ #endif
+@@ -10729,35 +10731,30 @@ thread_mark(th)
+ 	}
+ #endif
+     }
+-    
+-    stkBase = (void *)rb_gc_stack_start;
+-    stkSize = th->stk_len * sizeof(VALUE);
+-#if STACK_GROW_DIRECTION == 0
+-    if ((VALUE *)&th < rb_gc_stack_start)
+-#endif
+-#if STACK_GROW_DIRECTION <= 0
+-      stkBase -= stkSize;
+-#endif
+-    stkShift = (void *)th->stk_ptr - stkBase;
+-    
+-    frame = th->frame;
++
++    if (curr_thread == th)
++      frame = ruby_frame;
++    else
++      frame = th->frame;
++
+     while (frame && frame != top_frame) {
+-	ADJ(frame);
+ 	rb_gc_mark_frame(frame);
+ 	if (frame->tmp) {
+ 	    struct FRAME *tmp = frame->tmp;
+-
+ 	    while (tmp && tmp != top_frame) {
+-		ADJ(tmp);
+ 		rb_gc_mark_frame(tmp);
+ 		tmp = tmp->prev;
+ 	    }
+ 	}
+ 	frame = frame->prev;
+     }
+-    block = th->block;
++
++    if (curr_thread == th)
++      block = ruby_block;
++    else
++      block = th->block;
++
+     while (block) {
+-	ADJ(block);
+ 	rb_gc_mark_frame(&block->frame);
+ 	block = block->prev;
+     }
+@@ -10821,7 +10818,7 @@ stack_free(th)
+     rb_thread_t th;
+ {
+     if (th->stk_ptr) {
+-      free(th->stk_ptr);
++      munmap(th->stk_ptr, th->stk_size);
+       th->stk_ptr = 0;
+     }
+ #ifdef __ia64
+@@ -10873,6 +10870,11 @@ static int   th_sig, th_safe;
+ #define RESTORE_SIGNAL		6
+ #define RESTORE_EXIT		7
+ 
++extern VALUE *rb_gc_stack_start;
++#ifdef __ia64
++extern VALUE *rb_gc_register_stack_start;
++#endif
++
+ static void
+ rb_thread_save_context(th)
+     rb_thread_t th;
+@@ -10882,35 +10884,8 @@ rb_thread_save_context(th)
+     static VALUE tval;
+ 
+     len = ruby_stack_length(&pos);
+-    th->stk_len = 0;
+-    th->stk_pos = pos;
+-    if (len > th->stk_max) {
+-	VALUE *ptr = realloc(th->stk_ptr, sizeof(VALUE) * len);
+-	if (!ptr) rb_memerror();
+-	th->stk_ptr = ptr;
+-	th->stk_max = len;
+-    }
+     th->stk_len = len;
+-    FLUSH_REGISTER_WINDOWS;
+-    MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len);
+-#ifdef __ia64
+-    th->bstr_pos = rb_gc_register_stack_start;
+-    len = (VALUE*)rb_ia64_bsp() - th->bstr_pos;
+-    th->bstr_len = 0;
+-    if (len > th->bstr_max) {
+-        VALUE *ptr = realloc(th->bstr_ptr, sizeof(VALUE) * len);
+-        if (!ptr) rb_memerror();
+-        th->bstr_ptr = ptr;
+-        th->bstr_max = len;
+-    }
+-    th->bstr_len = len;
+-    rb_ia64_flushrs();
+-    MEMCPY(th->bstr_ptr, th->bstr_pos, VALUE, th->bstr_len);
+-#endif
+-#ifdef SAVE_WIN32_EXCEPTION_LIST
+-    th->win32_exception_list = win32_get_exception_list();
+-#endif
+-
++    th->stk_pos = pos;
+     th->frame = ruby_frame;
+     th->scope = ruby_scope;
+     ruby_scope->flags |= SCOPE_DONT_RECYCLE;
+@@ -11023,11 +10998,6 @@ rb_thread_restore_context_0(rb_thread_t th, int exit)
+ #endif
+     tmp = th;
+     ex = exit;
+-    FLUSH_REGISTER_WINDOWS;
+-    MEMCPY(tmp->stk_pos, tmp->stk_ptr, VALUE, tmp->stk_len);
+-#ifdef __ia64
+-    MEMCPY(tmp->bstr_pos, tmp->bstr_ptr, VALUE, tmp->bstr_len);
+-#endif
+ 
+     tval = rb_lastline_get();
+     rb_lastline_set(tmp->last_line);
+@@ -11119,8 +11089,8 @@ rb_thread_restore_context(th, exit)
+     rb_thread_t th;
+     int exit;
+ {
+-    if (!th->stk_ptr) rb_bug("unsaved context");
+-    stack_extend(th, exit);
++    if (!th->stk_ptr && th != main_thread) rb_bug("unsaved context");
++    rb_thread_restore_context_0(th, exit);
+ }
+ 
+ static void
+@@ -11139,7 +11109,6 @@ rb_thread_die(th)
+ {
+     th->thgroup = 0;
+     th->status = THREAD_KILLED;
+-    stack_free(th);
+ }
+ 
+ static void
+@@ -12468,8 +12437,10 @@ rb_thread_group(thread)
+ \
+     th->stk_ptr = 0;\
+     th->stk_len = 0;\
++    th->stk_size = 0;\
+     th->stk_max = 0;\
+     th->wait_for = 0;\
++    th->gc_stack_end = (VALUE *) STACK_GROW_DIRECTION;\
+     IA64_INIT(th->bstr_ptr = 0);\
+     IA64_INIT(th->bstr_len = 0);\
+     IA64_INIT(th->bstr_max = 0);\
+@@ -12515,6 +12486,48 @@ rb_thread_alloc(klass)
+     THREAD_ALLOC(th);
+     th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th);
+ 
++    /* if main_thread != NULL, then this is NOT the main thread, so
++     * we create a heap-stack
++     */
++    if (main_thread) {
++      /* Allocate stack, don't forget to add 1 extra word because of the MATH below */
++      unsigned int pagesize = getpagesize();
++      unsigned int total_size = rb_thread_stack_size + pagesize + sizeof(int);
++      void *stack_area = NULL;
++
++      stack_area = mmap(NULL, total_size, PROT_READ | PROT_WRITE | PROT_EXEC,
++			MAP_PRIVATE | MAP_ANON, -1, 0);
++
++      if (stack_area == MAP_FAILED) {
++	fprintf(stderr, "Thread stack allocation failed!\n");
++	rb_memerror();
++      }
++
++      th->stk_ptr = th->stk_pos = stack_area;
++      th->stk_size = total_size;
++
++      if (mprotect(th->stk_ptr, pagesize, PROT_NONE) == -1) {
++	fprintf(stderr, "Failed to create thread guard region: %s\n", strerror(errno));
++	rb_memerror();
++      }
++
++      th->guard = th->stk_ptr + (pagesize/sizeof(VALUE *));
++
++      /* point stk_base at the top of the stack */
++      /* ASSUMPTIONS:
++       * 1.) The address returned by malloc is "suitably aligned" for anything on this system
++       * 2.) Adding a value that is "aligned" for this platform should not unalign the address
++       *     returned from malloc.
++       * 3.) Don't push anything on to the stack, otherwise it'll get unaligned.
++       * 4.) x86_64 ABI says aligned AFTER arguments have been pushed. You *must* then do a call[lq]
++       *     or push[lq] something else on to the stack if you inted to do a ret.
++       */
++      th->stk_base = th->stk_ptr + ((total_size - sizeof(int))/sizeof(VALUE *));
++      th->stk_len = rb_thread_stack_size;
++    } else {
++      th->stk_ptr = th->stk_pos = rb_gc_stack_start;
++    }
++
+     for (vars = th->dyna_vars; vars; vars = vars->next) {
+ 	if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
+ 	FL_SET(vars, DVAR_DONT_RECYCLE);
+@@ -12681,6 +12694,15 @@ rb_thread_stop_timer()
+ int rb_thread_tick = THREAD_TICK;
+ #endif
+ 
++struct thread_start_args {
++  VALUE (*fn)();
++  void *arg;
++  rb_thread_t th;
++} new_th;
++
++static VALUE
++rb_thread_start_2();
++
+ #if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)
+ #define START_TIMER() (thread_init ? (void)0 : rb_thread_start_timer())
+ #define STOP_TIMER() (rb_thread_stop_timer())
+@@ -12695,11 +12717,7 @@ rb_thread_start_0(fn, arg, th)
+     void *arg;
+     rb_thread_t th;
+ {
+-    volatile rb_thread_t th_save = th;
+     volatile VALUE thread = th->thread;
+-    struct BLOCK *volatile saved_block = 0;
+-    enum rb_thread_status status;
+-    int state;
+ 
+     if (OBJ_FROZEN(curr_thread->thgroup)) {
+ 	rb_raise(rb_eThreadError,
+@@ -12710,16 +12728,41 @@ rb_thread_start_0(fn, arg, th)
+ 	return thread;
+     }
+ 
+-    if (ruby_block) {		/* should nail down higher blocks */
+-	struct BLOCK dummy;
++    new_th.fn = fn;
++    new_th.arg = arg;
++    new_th.th = th;
++
++#if defined(__i386__)
++    __asm__ __volatile__ ("movl %0, %%esp\n\t"
++                          "calll *%1\n"
++                          :: "r" (th->stk_base),
++                             "r" (rb_thread_start_2));
++#elif defined(__x86_64__)
++    __asm__ __volatile__ ("movq %0, %%rsp\n\t"
++                          "callq *%1\n"
++                          :: "r" (th->stk_base),
++                             "r" (rb_thread_start_2));
++#else
++    #error unsupported architecture!
++#endif
++    /* NOTREACHED */
++    return 0;
++}
+ 
+-	dummy.prev = ruby_block;
+-	blk_copy_prev(&dummy);
+-	saved_block = ruby_block = dummy.prev;
+-    }
+-    scope_dup(ruby_scope);
++static VALUE
++rb_thread_start_2()
++{
++   volatile rb_thread_t th = new_th.th;
++   volatile rb_thread_t th_save = th;
++   volatile VALUE thread = th->thread;
++   struct BLOCK *volatile saved_block = 0;
++   enum rb_thread_status status;
++   int state;
++   struct tag *tag, *new_tag, *prev_tag;
++   struct RVarmap *vars;
++   struct FRAME dummy_frame;
+ 
+-    if (!th->next) {
++   if (!th->next) {
+ 	/* merge in thread list */
+ 	th->prev = curr_thread;
+ 	curr_thread->next->prev = th;
+@@ -12727,14 +12770,42 @@ rb_thread_start_0(fn, arg, th)
+ 	curr_thread->next = th;
+ 	th->priority = curr_thread->priority;
+ 	th->thgroup = curr_thread->thgroup;
++   }
++   curr_thread = th;
++
++   dummy_frame = *ruby_frame;
++   dummy_frame.prev = top_frame;
++   ruby_frame = &dummy_frame;
++
++   if (ruby_block) {		/* should nail down higher blocks */
++	struct BLOCK dummy;
++
++	dummy.prev = ruby_block;
++	blk_copy_prev(&dummy);
++	saved_block = ruby_block = dummy.prev;
+     }
+     START_TIMER();
+ 
++    scope_dup(ruby_scope);
++    prev_tag = NULL;
++    tag = prot_tag;
++    while (tag) {
++	new_tag = alloca(sizeof(struct tag));
++	memcpy(new_tag, tag, sizeof(struct tag));
++	
++	if (prev_tag)
++	    prev_tag->prev = new_tag;
++	else
++	    prot_tag = new_tag;
++	
++	prev_tag = new_tag;
++	tag = tag->prev;
++    }
++
+     PUSH_TAG(PROT_THREAD);
+     if ((state = EXEC_TAG()) == 0) {
+ 	if (THREAD_SAVE_CONTEXT(th) == 0) {
+-	    curr_thread = th;
+-	    th->result = (*fn)(arg, th);
++	    th->result = (*new_th.fn)(new_th.arg, th);
+ 	}
+ 	th = th_save;
+     }
+@@ -13071,6 +13142,43 @@ rb_thread_cleanup()
+     END_FOREACH_FROM(curr, th);
+ }
+ 
++/*
++ * call-seq:
++ *    Thread.stack_size    => fixnum
++ *
++ * Returns the thread stack size in bytes
++ */
++static VALUE
++rb_thread_stacksize_get()
++{
++  return INT2FIX(rb_thread_stack_size);
++}
++
++/*
++ * call-seq:
++ *    Thread.stack_size= fixnum => Qnil
++ *
++ * Sets the global thread stacksize and returns Qnil.
++ */
++static VALUE
++rb_thread_stacksize_set(obj, val)
++     VALUE obj;
++     VALUE val;
++{
++
++  unsigned int size = FIX2UINT(val);
++
++  /* 16byte alignment works for both x86 and x86_64 */
++  if (size & (~0xf)) {
++    size += 0x10;
++    size = size & (~0xf);
++  }
++
++  rb_thread_stack_size = size;
++
++  return Qnil;
++}
++
+ int rb_thread_critical;
+ 
+ 
+@@ -13919,7 +14027,7 @@ rb_exec_recursive(func, obj, arg)
+ 	int state;
+ 
+ 	hash = recursive_push(hash, objid);
+-	PUSH_TAG(PROT_NONE);
++	PUSH_TAG(PROT_EMPTY);
+ 	result = (state = EXEC_TAG()) ? Qundef : (*func) (obj, arg, Qfalse);
+ 	POP_TAG();
+ 	recursive_pop(hash, objid);
+@@ -13944,6 +14052,8 @@ Init_Thread()
+ {
+     VALUE cThGroup;
+ 
++    rb_thread_stack_size = (1024 * 1024);
++
+     recursive_key = rb_intern("__recursive_key__");
+     rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);
+     rb_cThread = rb_define_class("Thread", rb_cObject);
+@@ -13968,6 +14078,9 @@ Init_Thread()
+     rb_define_singleton_method(rb_cThread, "abort_on_exception", rb_thread_s_abort_exc, 0);
+     rb_define_singleton_method(rb_cThread, "abort_on_exception=", rb_thread_s_abort_exc_set, 1);
+ 
++    rb_define_singleton_method(rb_cThread, "stack_size", rb_thread_stacksize_get, 0);
++    rb_define_singleton_method(rb_cThread, "stack_size=", rb_thread_stacksize_set, 1);
++
+     rb_define_method(rb_cThread, "run", rb_thread_run, 0);
+     rb_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 0);
+     rb_define_method(rb_cThread, "kill", rb_thread_kill, 0);
+@@ -14006,7 +14119,7 @@ Init_Thread()
+ #ifdef MBARI_API
+     rb_define_method(rb_cCont, "thread", rb_cont_thread, 0);
+ #endif
+-    rb_define_global_function("callcc", rb_callcc, 0);
++    /* rb_define_global_function("callcc", rb_callcc, 0); */
+     rb_global_variable(&cont_protect);
+ 
+     cThGroup = rb_define_class("ThreadGroup", rb_cObject);
+diff --git a/gc.c b/gc.c
+index 80f2c16..4a83543 100644
+--- a/gc.c
++++ b/gc.c
+@@ -68,7 +68,19 @@ int _setjmp(), _longjmp();
+ #endif
+ #define GC_STACK_MAX  (GC_LEVEL_MAX+GC_STACK_PAD)
+ 
+-static VALUE *stack_limit, *gc_stack_limit;
++/* The address of the end of the main thread's application stack. When the
++ * main thread is active, application code may not cause the stack to grow
++ * past this point. Past this point there's still a small area reserved for
++ * garbage collector operations.
++ */
++static VALUE *stack_limit;
++/*
++ * The address of the end of the current thread's GC stack. When running
++ * the GC, the stack may not grow past this point.
++ * The value of this variable is reset every time garbage_collect() is
++ * called.
++ */
++static VALUE *gc_stack_limit;
+ 
+ static size_t malloc_increase = 0;
+ static size_t malloc_limit = GC_MALLOC_LIMIT;
+@@ -715,8 +727,6 @@ VALUE *rb_gc_stack_start = 0;
+ VALUE *rb_gc_register_stack_start = 0;
+ #endif
+ 
+-VALUE *rb_gc_stack_end = (VALUE *)STACK_GROW_DIRECTION;
+-
+ 
+ #ifdef DJGPP
+ /* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) */
+@@ -750,12 +760,12 @@ VALUE *__sp(void) {
+ #endif
+ 
+ #if STACK_GROW_DIRECTION < 0
+-# define STACK_LENGTH  (rb_gc_stack_start - STACK_END)
++# define STACK_LENGTH(start)  ((start) - STACK_END)
+ #elif STACK_GROW_DIRECTION > 0
+-# define STACK_LENGTH  (STACK_END - rb_gc_stack_start + 1)
++# define STACK_LENGTH(start)  (STACK_END - (start) + 1)
+ #else
+-# define STACK_LENGTH  ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\
+-                                           : STACK_END - rb_gc_stack_start + 1)
++# define STACK_LENGTH(start)  ((STACK_END < (start)) ? (start) - STACK_END\
++                                           : STACK_END - (start) + 1)
+ #endif
+ #if STACK_GROW_DIRECTION > 0
+ # define STACK_UPPER(a, b) a
+@@ -778,15 +788,31 @@ ruby_stack_length(base)
+     VALUE **base;
+ {
+     SET_STACK_END;
++    VALUE *start;
++    if (rb_curr_thread == rb_main_thread) {
++	start = rb_gc_stack_start;
++    } else {
++	start = rb_curr_thread->stk_base;
++    }
+     if (base) *base = STACK_UPPER(start, STACK_END);
+-    return STACK_LENGTH;
++    return STACK_LENGTH(start);
+ }
+ 
+ int
+ ruby_stack_check()
+ {
+     SET_STACK_END;
+-    return __stack_past(stack_limit, STACK_END);
++    if (!rb_main_thread || rb_curr_thread == rb_main_thread) {
++	return __stack_past(stack_limit, STACK_END);
++    } else {
++	/* ruby_stack_check() is only called periodically, but we want to
++	 * detect a stack overflow before the thread's guard area is accessed.
++	 * So we append a '+ getpagesize()' to the address check.
++	 *
++	 * TODO: support architectures on which the stack grows upwards.
++	 */
++	return __stack_past(rb_curr_thread->guard + getpagesize(), STACK_END);
++    }
+ }
+ 
+ /*
+@@ -797,22 +823,24 @@ ruby_stack_check()
+ #if STACK_WIPE_METHOD
+ void rb_gc_wipe_stack(void)
+ {
+-  VALUE *stack_end = rb_gc_stack_end;
+-  VALUE *sp = __sp();
+-  rb_gc_stack_end = sp;
++  if (rb_curr_thread) {
++    VALUE *stack_end = rb_curr_thread->gc_stack_end;
++    VALUE *sp = __sp();
++    rb_curr_thread->gc_stack_end = sp;
+ #if STACK_WIPE_METHOD == 1
+ #warning clearing of "ghost references" from the call stack has been disabled
+ #elif STACK_WIPE_METHOD == 2  /* alloca ghost stack before clearing it */
+-  if (__stack_past(sp, stack_end)) {
+-    size_t bytes = __stack_depth((char *)stack_end, (char *)sp);
+-    STACK_UPPER(sp = nativeAllocA(bytes), stack_end = nativeAllocA(bytes));
+-    __stack_zero(stack_end, sp);
+-  }
++    if (__stack_past(sp, stack_end)) {
++      size_t bytes = __stack_depth((char *)stack_end, (char *)sp);
++      STACK_UPPER(sp = nativeAllocA(bytes), stack_end = nativeAllocA(bytes));
++      __stack_zero(stack_end, sp);
++    }
+ #elif STACK_WIPE_METHOD == 3    /* clear unallocated area past stack pointer */
+-  __stack_zero(stack_end, sp);  /* will crash if compiler pushes a temp. here */
++    __stack_zero(stack_end, sp);  /* will crash if compiler pushes a temp. here */
+ #else
+ #error unsupported method of clearing ghost references from the stack
+ #endif
++  }
+ }
+ #else
+ #warning clearing of "ghost references" from the call stack completely disabled
+@@ -1683,10 +1711,12 @@ garbage_collect_0(VALUE *top_frame)
+     rb_mark_table_prepare();
+     init_mark_stack();
+ 
+-    gc_mark((VALUE)ruby_current_node);
+-
+     /* mark frame stack */
+-    for (frame = ruby_frame; frame; frame = frame->prev) {
++    if (rb_curr_thread == rb_main_thread)
++	frame = ruby_frame;
++    else
++	frame = rb_main_thread->frame;
++    for (; frame; frame = frame->prev) {
+ 	rb_gc_mark_frame(frame);
+ 	if (frame->tmp) {
+ 	    struct FRAME *tmp = frame->tmp;
+@@ -1696,12 +1726,30 @@ garbage_collect_0(VALUE *top_frame)
+ 	    }
+ 	}
+     }
+-    gc_mark((VALUE)ruby_scope);
+-    gc_mark((VALUE)ruby_dyna_vars);
++    
++    if (rb_curr_thread == rb_main_thread) {
++	gc_mark((VALUE)ruby_current_node);
++	gc_mark((VALUE)ruby_scope);
++	gc_mark((VALUE)ruby_dyna_vars);
++    } else {
++	gc_mark((VALUE)rb_main_thread->node);
++	gc_mark((VALUE)rb_main_thread->scope);
++	gc_mark((VALUE)rb_main_thread->dyna_vars);
++
++	/* scan the current thread's stack */
++	rb_gc_mark_locations(top_frame, rb_curr_thread->stk_base);
++    }
++
+     if (finalizer_table) {
+ 	mark_tbl(finalizer_table);
+     }
+ 
++    /* If this is not the main thread, we need to scan the C stack, so
++     * set top_frame to the end of the C stack.
++     */
++    if (rb_curr_thread != rb_main_thread)
++	top_frame = rb_main_thread->stk_pos;
++
+ #if STACK_GROW_DIRECTION < 0
+     rb_gc_mark_locations(top_frame, rb_gc_stack_start);
+ #elif STACK_GROW_DIRECTION > 0
+@@ -1721,6 +1769,7 @@ garbage_collect_0(VALUE *top_frame)
+     rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),
+ 			 (VALUE*)((char*)rb_gc_stack_start + 2));
+ #endif
++
+     rb_gc_mark_threads();
+ 
+     /* mark protected global variables */
+@@ -1767,17 +1816,17 @@ garbage_collect()
+ 
+ #if STACK_WIPE_SITES & 0x400
+ # ifdef nativeAllocA
+-  if (__stack_past (top, stack_limit)) {
+-  /* allocate a large frame to ensure app stack cannot grow into GC stack */
++  if ((!rb_main_thread || rb_curr_thread == rb_main_thread) && __stack_past (top, stack_limit)) {
++    /* allocate a large frame to ensure app stack cannot grow into GC stack */
+     (volatile void*) nativeAllocA(__stack_depth((void*)stack_limit,(void*)top));
+-  }  
++  }
+   garbage_collect_0(top);
+ # else /* no native alloca() available */
+   garbage_collect_0(top);
+-  {
++  if (rb_curr_thread) {
+     VALUE *paddedLimit = __stack_grow(gc_stack_limit, GC_STACK_PAD);
+-    if (__stack_past(rb_gc_stack_end, paddedLimit))
+-      rb_gc_stack_end = paddedLimit;
++    if (__stack_past(rb_curr_thread->gc_stack_end, paddedLimit))
++      rb_curr_thread->gc_stack_end = paddedLimit;
+   }
+   rb_gc_wipe_stack();  /* wipe the whole stack area reserved for this gc */  
+ # endif
+@@ -2630,9 +2679,6 @@ Init_GC()
+ {
+     VALUE rb_mObSpace;
+ 
+-#if !STACK_GROW_DIRECTION
+-    rb_gc_stack_end = stack_grow_direction(&rb_mObSpace);
+-#endif
+     rb_mGC = rb_define_module("GC");
+     rb_define_singleton_method(rb_mGC, "start", rb_gc_start, 0);
+     rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0);
+diff --git a/node.h b/node.h
+index c209fa5..1242be5 100644
+--- a/node.h
++++ b/node.h
+@@ -411,8 +411,12 @@ struct rb_thread {
+ 
+     size_t stk_len;
+     size_t stk_max;
++    size_t stk_size;
+     VALUE *stk_ptr;
+     VALUE *stk_pos;
++    VALUE *stk_base;
++    VALUE *guard;
++    VALUE *gc_stack_end;
+ #ifdef __ia64
+     size_t bstr_len;
+     size_t bstr_max;
+diff --git a/rubysig.h b/rubysig.h
+index fae0869..4a4dadc 100644
+--- a/rubysig.h
++++ b/rubysig.h
+@@ -152,7 +152,6 @@ void rb_trap_restore_mask _((void));
+ RUBY_EXTERN int rb_thread_critical;
+ void rb_thread_schedule _((void));
+ 
+-RUBY_EXTERN VALUE *rb_gc_stack_end;
+ RUBY_EXTERN int rb_gc_stack_grow_direction;  /* -1 for down or 1 for up */
+ 
+ #if STACK_GROW_DIRECTION > 0
+@@ -268,12 +267,14 @@ RUBY_EXTERN VALUE *__sp(void);
+ #if STACK_WIPE_METHOD == 0
+ #define rb_gc_wipe_stack() ((void)0)
+ #elif STACK_WIPE_METHOD == 4
+-#define rb_gc_wipe_stack() {     \
+-  VALUE *end = rb_gc_stack_end;  \
+-  VALUE *sp = __sp();            \
+-  rb_gc_stack_end = sp;          \
+-  __stack_zero(end, sp);   \
+-}
++#define rb_gc_wipe_stack() do { \
++  if (rb_curr_thread) {     \
++    VALUE *end = rb_curr_thread->gc_stack_end;  \
++    VALUE *sp = __sp();            \
++    rb_curr_thread->gc_stack_end = sp;          \
++    __stack_zero(end, sp);   \
++  } \
++} while (0)
+ #else
+ RUBY_EXTERN void rb_gc_wipe_stack(void);
+ #endif
+@@ -283,7 +284,7 @@ RUBY_EXTERN void rb_gc_wipe_stack(void);
+ */
+ #define rb_gc_update_stack_extent() do { \
+     VALUE *sp = __sp(); \
+-    if __stack_past(rb_gc_stack_end, sp) rb_gc_stack_end = sp; \
++    if (rb_curr_thread && __stack_past(rb_curr_thread->gc_stack_end, sp)) rb_curr_thread->gc_stack_end = sp; \
+ } while(0)
+ 
+ 
+diff --git a/signal.c b/signal.c
+index 4cf3bec..58798bd 100644
+--- a/signal.c
++++ b/signal.c
+@@ -14,6 +14,7 @@
+ 
+ #include "ruby.h"
+ #include "rubysig.h"
++#include "node.h"
+ #include <signal.h>
+ #include <stdio.h>
+ 
+@@ -428,15 +429,22 @@ typedef RETSIGTYPE (*sighandler_t)_((int));
+ static sighandler_t
+ ruby_signal(signum, handler)
+     int signum;
+-    sighandler_t handler;
++    void *handler;
+ {
+     struct sigaction sigact, old;
+ 
+     rb_trap_accept_nativethreads[signum] = 0;
+ 
+-    sigact.sa_handler = handler;
++    if (signum == SIGSEGV || signum == SIGBUS) {
++      sigact.sa_sigaction = handler;
++      sigact.sa_flags = (SA_ONSTACK | SA_RESETHAND | SA_SIGINFO);
++    } else {
++      sigact.sa_handler = handler;
++      sigact.sa_flags = 0;
++    }
++
+     sigemptyset(&sigact.sa_mask);
+-    sigact.sa_flags = 0;
++
+ # ifdef SA_NOCLDWAIT
+     if (signum == SIGCHLD && handler == SIG_IGN)
+ 	sigact.sa_flags |= SA_NOCLDWAIT;
+@@ -599,7 +607,132 @@ sighandler(sig)
+     }
+ }
+ 
++#include <stdio.h>
++#ifdef HAVE_STDARG_PROTOTYPES
++#include <stdarg.h>
++#define va_init_list(a,b) va_start(a,b)
++#else
++#include <varargs.h>
++#define va_init_list(a,b) va_start(a)
++#endif
++
++void
++#ifdef HAVE_STDARG_PROTOTYPES
++sig_printf(const char *fmt, ...)
++#else
++  sig_printf(fmt, va_alist)
++     const char *fmt;
++    va_dcl
++#endif
++{
++  char buf[BUFSIZ];
++  va_list args;
++  FILE *out = stderr;
++
++  va_init_list(args, fmt);
++  vfprintf(out, fmt, args);
++  va_end(args);
++  fprintf(out, "\n");
++}
++
++static void
++dump_machine_state(uc)
++     ucontext_t *uc;
++{
++  const char *dump64 =
++    " ----------------- Register state dump ----------------------\n"
++    "rax = 0x%.16x  rbx    = 0x%.16x  rcx = 0x%.16x  rdx = 0x%.16x\n"
++    "rdi = 0x%.16x  rsi    = 0x%.16x  rbp = 0x%.16x  rsp = 0x%.16x\n"
++    "r8  = 0x%.16x  r9     = 0x%.16x  r10 = 0x%.16x  r11 = 0x%.16x\n"
++    "r12 = 0x%.16x  r13    = 0x%.16x  r14 = 0x%.16x  r15 = 0x%.16x\n"
++    "rip = 0x%.16x  rflags = 0x%.16x  cs  = 0x%.16x  fs  = 0x%.16x\n"
++    "gs  = 0x%.16x";
++
++  const char *dump32 =
++    " ----------------- Register state dump -------------------\n"
++    "eax = 0x%.8x  ebx    = 0x%.8x  ecx = 0x%.8x  edx = 0x%.8x\n"
++    "edi = 0x%.8x  esi    = 0x%.8x  ebp = 0x%.8x  esp = 0x%.8x\n"
++    "ss  = 0x%.8x  eflags = 0x%.8x  eip = 0x%.8x  cs  = 0x%.8x\n"
++    "ds  = 0x%.8x  es     = 0x%.8x  fs  = 0x%.8x  gs  = 0x%.8x\n";
++
++#if defined(__LP64__) && defined(__APPLE__)
++  sig_printf(dump64, uc->uc_mcontext->__ss.__rax, uc->uc_mcontext->__ss.__rbx,
++	     uc->uc_mcontext->__ss.__rcx, uc->uc_mcontext->__ss.__rdx, uc->uc_mcontext->__ss.__rdi,
++	     uc->uc_mcontext->__ss.__rsi, uc->uc_mcontext->__ss.__rbp, uc->uc_mcontext->__ss.__rsp,
++	     uc->uc_mcontext->__ss.__r8, uc->uc_mcontext->__ss.__r9, uc->uc_mcontext->__ss.__r10,
++	     uc->uc_mcontext->__ss.__r11, uc->uc_mcontext->__ss.__r12, uc->uc_mcontext->__ss.__r13,
++	     uc->uc_mcontext->__ss.__r14, uc->uc_mcontext->__ss.__r15, uc->uc_mcontext->__ss.__rip,
++	     uc->uc_mcontext->__ss.__rflags, uc->uc_mcontext->__ss.__cs, uc->uc_mcontext->__ss.__fs,
++	     uc->uc_mcontext->__ss.__gs);
++#elif !defined(__LP64__) && defined(__APPLE__)
++  sig_printf(dump32, uc->uc_mcontext->__ss.__eax, uc->uc_mcontext->__ss.__ebx,
++	     uc->uc_mcontext->__ss.__ecx, uc->uc_mcontext->__ss.__edx,
++	     uc->uc_mcontext->__ss.__edi, uc->uc_mcontext->__ss.__esi,
++	     uc->uc_mcontext->__ss.__ebp, uc->uc_mcontext->__ss.__esp,
++	     uc->uc_mcontext->__ss.__ss, uc->uc_mcontext->__ss.__eflags,
++	     uc->uc_mcontext->__ss.__eip, uc->uc_mcontext->__ss.__cs,
++	     uc->uc_mcontext->__ss.__ds, uc->uc_mcontext->__ss.__es,
++	     uc->uc_mcontext->__ss.__fs, uc->uc_mcontext->__ss.__gs);
++#elif defined(__i386__)
++  sig_printf(dump32, uc->uc_mcontext.gregs[REG_EAX], uc->uc_mcontext.gregs[REG_EBX],
++	     uc->uc_mcontext.gregs[REG_ECX], uc->uc_mcontext.gregs[REG_EDX],
++	     uc->uc_mcontext.gregs[REG_EDI], uc->uc_mcontext.gregs[REG_ESI],
++	     uc->uc_mcontext.gregs[REG_EBP], uc->uc_mcontext.gregs[REG_ESP],
++	     uc->uc_mcontext.gregs[REG_SS], uc->uc_mcontext.gregs[REG_EFL],
++	     uc->uc_mcontext.gregs[REG_EIP], uc->uc_mcontext.gregs[REG_EIP],
++	     uc->uc_mcontext.gregs[REG_DS], uc->uc_mcontext.gregs[REG_ES],
++	     uc->uc_mcontext.gregs[REG_FS], uc->uc_mcontext.gregs[REG_FS]);
++#elif defined(__x86_64__)
++  sig_printf(dump64, uc->uc_mcontext.gregs[REG_RAX], uc->uc_mcontext.gregs[REG_RBX],
++	     uc->uc_mcontext.gregs[REG_RCX], uc->uc_mcontext.gregs[REG_RDX],
++	     uc->uc_mcontext.gregs[REG_RDI], uc->uc_mcontext.gregs[REG_RSI],
++	     uc->uc_mcontext.gregs[REG_RBP], uc->uc_mcontext.gregs[REG_RSP],
++	     uc->uc_mcontext.gregs[REG_R8], uc->uc_mcontext.gregs[REG_R9],
++	     uc->uc_mcontext.gregs[REG_R10], uc->uc_mcontext.gregs[REG_R11],
++	     uc->uc_mcontext.gregs[REG_R12], uc->uc_mcontext.gregs[REG_R13],
++	     uc->uc_mcontext.gregs[REG_R14], uc->uc_mcontext.gregs[REG_R15],
++	     uc->uc_mcontext.gregs[REG_RIP], uc->uc_mcontext.gregs[REG_EFL],
++	     uc->uc_mcontext.gregs[REG_CSGSFS]);
++#else
++#endif
++}
++
++static int
++check_guard(caddr_t fault_addr, rb_thread_t th) {
++  if(fault_addr <= (caddr_t)rb_curr_thread->guard &&
++     fault_addr >= (caddr_t)rb_curr_thread->stk_ptr) {
++    return 1;
++  }
++  return 0;
++}
++
+ #ifdef SIGBUS
++#ifdef POSIX_SIGNAL
++static void sigbus _((int, siginfo_t*, void*));
++static void
++sigbus(sig, ip, context)
++     int sig;
++     siginfo_t *ip;
++     void *context;
++{
++#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
++  if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
++    sigsend_to_ruby_thread(sig);
++    return;
++  }
++#endif
++
++  dump_machine_state(context);
++  if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) {
++    /* we hit the guard page, print out a warning to help app developers */
++    rb_bug("Thread stack overflow! Try increasing it!");
++  } else {
++    rb_bug("Bus Error");
++  }
++}
++
++#else /* !defined(POSIX_SIGNAL) */
++
+ static RETSIGTYPE sigbus _((int));
+ static RETSIGTYPE
+ sigbus(sig)
+@@ -615,8 +748,36 @@ sigbus(sig)
+     rb_bug("Bus Error");
+ }
+ #endif
++#endif
++
+ 
+ #ifdef SIGSEGV
++#ifdef POSIX_SIGNAL
++static void sigsegv _((int, siginfo_t*, void*));
++static void
++sigsegv(sig, ip, context)
++     int sig;
++     siginfo_t *ip;
++     void *context;
++{
++#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)
++  if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {
++    sigsend_to_ruby_thread(sig);
++    return;
++  }
++#endif
++
++  dump_machine_state(context);
++  if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) {
++    /* we hit the guard page, print out a warning to help app developers */
++    rb_bug("Thread stack overflow! Try increasing it!");
++  } else {
++    rb_bug("Segmentation fault");
++  }
++}
++
++#else /* !defined(POSIX_SIGNAL) */
++
+ static RETSIGTYPE sigsegv _((int));
+ static RETSIGTYPE
+ sigsegv(sig)
+@@ -633,6 +794,7 @@ sigsegv(sig)
+     rb_bug("Segmentation fault");
+ }
+ #endif
++#endif
+ 
+ #ifdef SIGPIPE
+ static RETSIGTYPE sigpipe _((int));
+@@ -704,7 +866,8 @@ static VALUE
+ trap(arg)
+     struct trap_arg *arg;
+ {
+-    sighandler_t func, oldfunc;
++    sighandler_t oldfunc;
++    void *func;
+     VALUE command, oldcmd;
+     int sig = -1;
+     const char *s;
+@@ -951,6 +1114,20 @@ sig_list()
+ }
+ 
+ static void
++create_sigstack()
++{
++  stack_t ss;
++  ss.ss_size = SIGSTKSZ;
++  ss.ss_sp = malloc(ss.ss_size);
++  ss.ss_flags = 0;
++  if (sigaltstack(&ss, NULL) < 0) {
++    free(ss.ss_sp);
++    fprintf(stderr, "Couldn't create signal stack! Error %d: %s\n", errno, strerror(errno));
++    exit(1);
++  }
++}
++
++static void
+ install_sighandler(signum, handler)
+     int signum;
+     sighandler_t handler;
+@@ -959,7 +1136,7 @@ install_sighandler(signum, handler)
+ 
+     old = ruby_signal(signum, handler);
+     if (old != SIG_DFL) {
+-	ruby_signal(signum, old);
++       ruby_signal(signum, old);
+     }
+ }
+ 
+@@ -1088,6 +1265,8 @@ Init_signal()
+     rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
+     rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
+ 
++    create_sigstack();
++
+     install_sighandler(SIGINT, sighandler);
+ #ifdef SIGHUP
+     install_sighandler(SIGHUP, sighandler);

diff --git a/patchsets/patches-ee-1.8.7-2010.02-r1/series b/patchsets/patches-ee-1.8.7-2010.02-r1/series
new file mode 100644
index 0000000..ad69a95
--- /dev/null
+++ b/patchsets/patches-ee-1.8.7-2010.02-r1/series
@@ -0,0 +1,10 @@
+001_memory_leak.patch
+002_mkconfig.patch
+003_mkmf-parallel-install.patch
+004_configure-libdir.patch
+005_mkconfig-libdir.patch
+006_pathname_warning.patch
+007_no-undefined-ext.patch
+008_berkdb-5.0.patch
+010_openssl1.patch
+012_webrick-CVE-2010-0541.patch



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2011-05-15  6:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-15  6:24 [gentoo-commits] proj/ruby-scripts:master commit in: patchsets/patches-ee-1.8.7-2010.02-r1/ Hans de Graaff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox