]> granicus.if.org Git - python/commitdiff
#11515: Merge with 3.1.
authorEzio Melotti <ezio.melotti@gmail.com>
Tue, 15 Mar 2011 03:59:46 +0000 (05:59 +0200)
committerEzio Melotti <ezio.melotti@gmail.com>
Tue, 15 Mar 2011 03:59:46 +0000 (05:59 +0200)
42 files changed:
1  2 
Lib/decimal.py
Lib/ftplib.py
Lib/gettext.py
Lib/http/client.py
Lib/idlelib/EditorWindow.py
Lib/importlib/_bootstrap.py
Lib/nntplib.py
Lib/socketserver.py
Lib/test/test_compile.py
Lib/test/test_descr.py
Lib/test/test_numeric_tower.py
Lib/test/test_os.py
Lib/test/test_re.py
Lib/test/test_set.py
Lib/test/test_warnings.py
Lib/tkinter/__init__.py
Lib/tkinter/tix.py
Lib/tkinter/ttk.py
Lib/turtle.py
Lib/xml/dom/minidom.py
Mac/BuildScript/build-installer.py
Mac/Tools/pythonw.c
Modules/_ctypes/callproc.c
Modules/_ctypes/libffi/ChangeLog
Modules/_ctypes/libffi/src/dlmalloc.c
Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c
Modules/_struct.c
Modules/_threadmodule.c
Modules/parsermodule.c
Modules/posixmodule.c
Modules/zipimport.c
Objects/bytearrayobject.c
Objects/bytesobject.c
Objects/longobject.c
Objects/stringlib/string_format.h
Python/_warnings.c
Python/sysmodule.c
Tools/demo/ss1.py
Tools/msi/msi.py
Tools/pybench/pybench.py
setup.py

diff --cc Lib/decimal.py
Simple merge
diff --cc Lib/ftplib.py
index 22b5fd2175a44c90d86b9fdc6d70a02a87a7fb24,ea91c1707c137dfcd6185facfc7e37786dfcb4cd..7c398879bcf5f276748906db3fa981aaac0af1d6
@@@ -595,196 -581,6 +595,196 @@@ class FTP
              self.file = self.sock = None
  
  
-         >>> ftps.login()  # login anonimously previously securing control channel
 +try:
 +    import ssl
 +except ImportError:
 +    pass
 +else:
 +    class FTP_TLS(FTP):
 +        '''A FTP subclass which adds TLS support to FTP as described
 +        in RFC-4217.
 +
 +        Connect as usual to port 21 implicitly securing the FTP control
 +        connection before authenticating.
 +
 +        Securing the data connection requires user to explicitly ask
 +        for it by calling prot_p() method.
 +
 +        Usage example:
 +        >>> from ftplib import FTP_TLS
 +        >>> ftps = FTP_TLS('ftp.python.org')
++        >>> ftps.login()  # login anonymously previously securing control channel
 +        '230 Guest login ok, access restrictions apply.'
 +        >>> ftps.prot_p()  # switch to secure data connection
 +        '200 Protection level set to P'
 +        >>> ftps.retrlines('LIST')  # list directory content securely
 +        total 9
 +        drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 .
 +        drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 ..
 +        drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 bin
 +        drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 etc
 +        d-wxrwxr-x   2 ftp      wheel        1024 Sep  5 13:43 incoming
 +        drwxr-xr-x   2 root     wheel        1024 Nov 17  1993 lib
 +        drwxr-xr-x   6 1094     wheel        1024 Sep 13 19:07 pub
 +        drwxr-xr-x   3 root     wheel        1024 Jan  3  1994 usr
 +        -rw-r--r--   1 root     root          312 Aug  1  1994 welcome.msg
 +        '226 Transfer complete.'
 +        >>> ftps.quit()
 +        '221 Goodbye.'
 +        >>>
 +        '''
 +        ssl_version = ssl.PROTOCOL_TLSv1
 +
 +        def __init__(self, host='', user='', passwd='', acct='', keyfile=None,
 +                     certfile=None, context=None,
 +                     timeout=_GLOBAL_DEFAULT_TIMEOUT):
 +            if context is not None and keyfile is not None:
 +                raise ValueError("context and keyfile arguments are mutually "
 +                                 "exclusive")
 +            if context is not None and certfile is not None:
 +                raise ValueError("context and certfile arguments are mutually "
 +                                 "exclusive")
 +            self.keyfile = keyfile
 +            self.certfile = certfile
 +            self.context = context
 +            self._prot_p = False
 +            FTP.__init__(self, host, user, passwd, acct, timeout)
 +
 +        def login(self, user='', passwd='', acct='', secure=True):
 +            if secure and not isinstance(self.sock, ssl.SSLSocket):
 +                self.auth()
 +            return FTP.login(self, user, passwd, acct)
 +
 +        def auth(self):
 +            '''Set up secure control connection by using TLS/SSL.'''
 +            if isinstance(self.sock, ssl.SSLSocket):
 +                raise ValueError("Already using TLS")
 +            if self.ssl_version == ssl.PROTOCOL_TLSv1:
 +                resp = self.voidcmd('AUTH TLS')
 +            else:
 +                resp = self.voidcmd('AUTH SSL')
 +            if self.context is not None:
 +                self.sock = self.context.wrap_socket(self.sock)
 +            else:
 +                self.sock = ssl.wrap_socket(self.sock, self.keyfile,
 +                                            self.certfile,
 +                                            ssl_version=self.ssl_version)
 +            self.file = self.sock.makefile(mode='r', encoding=self.encoding)
 +            return resp
 +
 +        def prot_p(self):
 +            '''Set up secure data connection.'''
 +            # PROT defines whether or not the data channel is to be protected.
 +            # Though RFC-2228 defines four possible protection levels,
 +            # RFC-4217 only recommends two, Clear and Private.
 +            # Clear (PROT C) means that no security is to be used on the
 +            # data-channel, Private (PROT P) means that the data-channel
 +            # should be protected by TLS.
 +            # PBSZ command MUST still be issued, but must have a parameter of
 +            # '0' to indicate that no buffering is taking place and the data
 +            # connection should not be encapsulated.
 +            self.voidcmd('PBSZ 0')
 +            resp = self.voidcmd('PROT P')
 +            self._prot_p = True
 +            return resp
 +
 +        def prot_c(self):
 +            '''Set up clear text data connection.'''
 +            resp = self.voidcmd('PROT C')
 +            self._prot_p = False
 +            return resp
 +
 +        # --- Overridden FTP methods
 +
 +        def ntransfercmd(self, cmd, rest=None):
 +            conn, size = FTP.ntransfercmd(self, cmd, rest)
 +            if self._prot_p:
 +                if self.context is not None:
 +                    conn = self.context.wrap_socket(conn)
 +                else:
 +                    conn = ssl.wrap_socket(conn, self.keyfile, self.certfile,
 +                                           ssl_version=self.ssl_version)
 +            return conn, size
 +
 +        def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
 +            self.voidcmd('TYPE I')
 +            conn = self.transfercmd(cmd, rest)
 +            try:
 +                while 1:
 +                    data = conn.recv(blocksize)
 +                    if not data:
 +                        break
 +                    callback(data)
 +                # shutdown ssl layer
 +                if isinstance(conn, ssl.SSLSocket):
 +                    conn.unwrap()
 +            finally:
 +                conn.close()
 +            return self.voidresp()
 +
 +        def retrlines(self, cmd, callback = None):
 +            if callback is None: callback = print_line
 +            resp = self.sendcmd('TYPE A')
 +            conn = self.transfercmd(cmd)
 +            fp = conn.makefile('r', encoding=self.encoding)
 +            try:
 +                while 1:
 +                    line = fp.readline()
 +                    if self.debugging > 2: print('*retr*', repr(line))
 +                    if not line:
 +                        break
 +                    if line[-2:] == CRLF:
 +                        line = line[:-2]
 +                    elif line[-1:] == '\n':
 +                        line = line[:-1]
 +                    callback(line)
 +                # shutdown ssl layer
 +                if isinstance(conn, ssl.SSLSocket):
 +                    conn.unwrap()
 +            finally:
 +                fp.close()
 +                conn.close()
 +            return self.voidresp()
 +
 +        def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None):
 +            self.voidcmd('TYPE I')
 +            conn = self.transfercmd(cmd, rest)
 +            try:
 +                while 1:
 +                    buf = fp.read(blocksize)
 +                    if not buf: break
 +                    conn.sendall(buf)
 +                    if callback: callback(buf)
 +                # shutdown ssl layer
 +                if isinstance(conn, ssl.SSLSocket):
 +                    conn.unwrap()
 +            finally:
 +                conn.close()
 +            return self.voidresp()
 +
 +        def storlines(self, cmd, fp, callback=None):
 +            self.voidcmd('TYPE A')
 +            conn = self.transfercmd(cmd)
 +            try:
 +                while 1:
 +                    buf = fp.readline()
 +                    if not buf: break
 +                    if buf[-2:] != B_CRLF:
 +                        if buf[-1] in B_CRLF: buf = buf[:-1]
 +                        buf = buf + B_CRLF
 +                    conn.sendall(buf)
 +                    if callback: callback(buf)
 +                # shutdown ssl layer
 +                if isinstance(conn, ssl.SSLSocket):
 +                    conn.unwrap()
 +            finally:
 +                conn.close()
 +            return self.voidresp()
 +
 +    __all__.append('FTP_TLS')
 +    all_errors = (Error, IOError, EOFError, ssl.SSLError)
 +
 +
  _150_re = None
  
  def parse150(resp):
diff --cc Lib/gettext.py
Simple merge
Simple merge
Simple merge
index cd7f5d63c8103cdda1ea71a9b65f5bce19ce04d6,6f60843d36c95dc001bd7eef37eebe347118e571..425b8bf8c79ffd54cf3ddae2d7dbae89df49857a
@@@ -291,52 -301,34 +291,52 @@@ class FrozenImporter
          return imp.is_frozen_package(fullname)
  
  
 -class PyLoader:
 +class _LoaderBasics:
  
 -    """Loader base class for Python source code.
 +    """Base class of common code needed by both SourceLoader and
 +    _SourcelessFileLoader."""
  
 -    Subclasses need to implement the methods:
 +    def is_package(self, fullname):
 +        """Concrete implementation of InspectLoader.is_package by checking if
 +        the path returned by get_filename has a filename of '__init__.py'."""
 +        filename = self.get_filename(fullname).rpartition(path_sep)[2]
 +        return filename.rsplit('.', 1)[0] == '__init__'
  
 -    - source_path
 -    - get_data
 -    - is_package
 +    def _bytes_from_bytecode(self, fullname, data, source_mtime):
 +        """Return the marshalled bytes from bytecode, verifying the magic
-         number and timestamp alon the way.
++        number and timestamp along the way.
  
 -    """
 +        If source_mtime is None then skip the timestamp check.
  
 -    @module_for_loader
 -    def load_module(self, module):
 -        """Load a source module."""
 -        return self._load_module(module)
 +        """
 +        magic = data[:4]
 +        raw_timestamp = data[4:8]
 +        if len(magic) != 4 or magic != imp.get_magic():
 +            raise ImportError("bad magic number in {}".format(fullname))
 +        elif len(raw_timestamp) != 4:
 +            raise EOFError("bad timestamp in {}".format(fullname))
 +        elif source_mtime is not None:
 +            if marshal._r_long(raw_timestamp) != source_mtime:
 +                raise ImportError("bytecode is stale for {}".format(fullname))
 +        # Can't return the code object as errors from marshal loading need to
 +        # propagate even when source is available.
 +        return data[8:]
  
 -    def _load_module(self, module):
 -        """Initialize a module from source."""
 +    @module_for_loader
 +    def _load_module(self, module, *, sourceless=False):
 +        """Helper for load_module able to handle either source or sourceless
 +        loading."""
          name = module.__name__
 -        code_object = self.get_code(module.__name__)
 -        # __file__ may have been set by the caller, e.g. bytecode path.
 -        if not hasattr(module, '__file__'):
 -            module.__file__ = self.source_path(name)
 +        code_object = self.get_code(name)
 +        module.__file__ = self.get_filename(name)
 +        if not sourceless:
 +            module.__cached__ = imp.cache_from_source(module.__file__)
 +        else:
 +            module.__cached__ = module.__file__
 +        module.__package__ = name
          if self.is_package(name):
 -            module.__path__  = [module.__file__.rsplit(path_sep, 1)[0]]
 -        module.__package__ = module.__name__
 -        if not hasattr(module, '__path__'):
 +            module.__path__ = [module.__file__.rsplit(path_sep, 1)[0]]
 +        else:
              module.__package__ = module.__package__.rpartition('.')[0]
          module.__loader__ = self
          exec(code_object, module.__dict__)
diff --cc Lib/nntplib.py
index 70a75b60d27a5f52731ef1f73d5286169195eb50,326c62df473c6351e44c15bc160438a59b73e789..bf66734a523fcbd2b103ac5a1a5cb251ab11c376
@@@ -905,197 -584,33 +905,197 @@@ class _NNTPBase
      def quit(self):
          """Process a QUIT command and close the socket.  Returns:
          - resp: server response if successful"""
 -
 -        resp = self.shortcmd('QUIT')
 -        self.file.close()
 -        self.sock.close()
 -        del self.file, self.sock
 +        try:
 +            resp = self._shortcmd('QUIT')
 +        finally:
 +            self._close()
          return resp
  
-         reader-specific comamnds, such as `group'.  If you get
 +    def login(self, user=None, password=None, usenetrc=True):
 +        if self.authenticated:
 +            raise ValueError("Already logged in.")
 +        if not user and not usenetrc:
 +            raise ValueError(
 +                "At least one of `user` and `usenetrc` must be specified")
 +        # If no login/password was specified but netrc was requested,
 +        # try to get them from ~/.netrc
 +        # Presume that if .netrc has an entry, NNRP authentication is required.
 +        try:
 +            if usenetrc and not user:
 +                import netrc
 +                credentials = netrc.netrc()
 +                auth = credentials.authenticators(self.host)
 +                if auth:
 +                    user = auth[0]
 +                    password = auth[2]
 +        except IOError:
 +            pass
 +        # Perform NNTP authentication if needed.
 +        if not user:
 +            return
 +        resp = self._shortcmd('authinfo user ' + user)
 +        if resp.startswith('381'):
 +            if not password:
 +                raise NNTPReplyError(resp)
 +            else:
 +                resp = self._shortcmd('authinfo pass ' + password)
 +                if not resp.startswith('281'):
 +                    raise NNTPPermanentError(resp)
 +        # Attempt to send mode reader if it was requested after login.
 +        if self.readermode_afterauth:
 +            self._setreadermode()
 +
 +    def _setreadermode(self):
 +        try:
 +            self.welcome = self._shortcmd('mode reader')
 +        except NNTPPermanentError:
 +            # Error 5xx, probably 'not implemented'
 +            pass
 +        except NNTPTemporaryError as e:
 +            if e.response.startswith('480'):
 +                # Need authorization before 'mode reader'
 +                self.readermode_afterauth = True
 +            else:
 +                raise
 +
 +    if _have_ssl:
 +        def starttls(self, context=None):
 +            """Process a STARTTLS command. Arguments:
 +            - context: SSL context to use for the encrypted connection
 +            """
 +            # Per RFC 4642, STARTTLS MUST NOT be sent after authentication or if
 +            # a TLS session already exists.
 +            if self.tls_on:
 +                raise ValueError("TLS is already enabled.")
 +            if self.authenticated:
 +                raise ValueError("TLS cannot be started after authentication.")
 +            resp = self._shortcmd('STARTTLS')
 +            if resp.startswith('382'):
 +                self.file.close()
 +                self.sock = _encrypt_on(self.sock, context)
 +                self.file = self.sock.makefile("rwb")
 +                self.tls_on = True
 +                # Capabilities may change after TLS starts up, so ask for them
 +                # again.
 +                self._caps = None
 +                self.getcapabilities()
 +            else:
 +                raise NNTPError("TLS failed to start.")
 +
 +
 +class NNTP(_NNTPBase):
 +
 +    def __init__(self, host, port=NNTP_PORT, user=None, password=None,
 +                 readermode=None, usenetrc=False,
 +                 timeout=_GLOBAL_DEFAULT_TIMEOUT):
 +        """Initialize an instance.  Arguments:
 +        - host: hostname to connect to
 +        - port: port to connect to (default the standard NNTP port)
 +        - user: username to authenticate with
 +        - password: password to use with username
 +        - readermode: if true, send 'mode reader' command after
 +                      connecting.
 +        - usenetrc: allow loading username and password from ~/.netrc file
 +                    if not specified explicitly
 +        - timeout: timeout (in seconds) used for socket connections
 +
 +        readermode is sometimes necessary if you are connecting to an
 +        NNTP server on the local machine and intend to call
++        reader-specific commands, such as `group'.  If you get
 +        unexpected NNTPPermanentErrors, you might need to set
 +        readermode.
 +        """
 +        self.host = host
 +        self.port = port
 +        self.sock = socket.create_connection((host, port), timeout)
 +        file = self.sock.makefile("rwb")
 +        _NNTPBase.__init__(self, file, host,
 +                           readermode, timeout)
 +        if user or usenetrc:
 +            self.login(user, password, usenetrc)
 +
 +    def _close(self):
 +        try:
 +            _NNTPBase._close(self)
 +        finally:
 +            self.sock.close()
 +
 +
 +if _have_ssl:
 +    class NNTP_SSL(_NNTPBase):
 +
 +        def __init__(self, host, port=NNTP_SSL_PORT,
 +                    user=None, password=None, ssl_context=None,
 +                    readermode=None, usenetrc=False,
 +                    timeout=_GLOBAL_DEFAULT_TIMEOUT):
 +            """This works identically to NNTP.__init__, except for the change
 +            in default port and the `ssl_context` argument for SSL connections.
 +            """
 +            self.sock = socket.create_connection((host, port), timeout)
 +            self.sock = _encrypt_on(self.sock, ssl_context)
 +            file = self.sock.makefile("rwb")
 +            _NNTPBase.__init__(self, file, host,
 +                               readermode=readermode, timeout=timeout)
 +            if user or usenetrc:
 +                self.login(user, password, usenetrc)
 +
 +        def _close(self):
 +            try:
 +                _NNTPBase._close(self)
 +            finally:
 +                self.sock.close()
 +
 +    __all__.append("NNTP_SSL")
 +
  
  # Test retrieval when run as a script.
 -# Assumption: if there's a local news server, it's called 'news'.
 -# Assumption: if user queries a remote news server, it's named
 -# in the environment variable NNTPSERVER (used by slrn and kin)
 -# and we want readermode off.
  if __name__ == '__main__':
 -    import os
 -    newshost = 'news' and os.environ["NNTPSERVER"]
 -    if newshost.find('.') == -1:
 -        mode = 'readermode'
 +    import argparse
 +    from email.utils import parsedate
 +
 +    parser = argparse.ArgumentParser(description="""\
 +        nntplib built-in demo - display the latest articles in a newsgroup""")
 +    parser.add_argument('-g', '--group', default='gmane.comp.python.general',
 +                        help='group to fetch messages from (default: %(default)s)')
 +    parser.add_argument('-s', '--server', default='news.gmane.org',
 +                        help='NNTP server hostname (default: %(default)s)')
 +    parser.add_argument('-p', '--port', default=-1, type=int,
 +                        help='NNTP port number (default: %s / %s)' % (NNTP_PORT, NNTP_SSL_PORT))
 +    parser.add_argument('-n', '--nb-articles', default=10, type=int,
 +                        help='number of articles to fetch (default: %(default)s)')
 +    parser.add_argument('-S', '--ssl', action='store_true', default=False,
 +                        help='use NNTP over SSL')
 +    args = parser.parse_args()
 +
 +    port = args.port
 +    if not args.ssl:
 +        if port == -1:
 +            port = NNTP_PORT
 +        s = NNTP(host=args.server, port=port)
      else:
 -        mode = None
 -    s = NNTP(newshost, readermode=mode)
 -    resp, count, first, last, name = s.group('comp.lang.python')
 -    print(resp)
 +        if port == -1:
 +            port = NNTP_SSL_PORT
 +        s = NNTP_SSL(host=args.server, port=port)
 +
 +    caps = s.getcapabilities()
 +    if 'STARTTLS' in caps:
 +        s.starttls()
 +    resp, count, first, last, name = s.group(args.group)
      print('Group', name, 'has', count, 'articles, range', first, 'to', last)
 -    resp, subs = s.xhdr('subject', '{0}-{1}'.format(first, last))
 -    print(resp)
 -    for item in subs:
 -        print("%7s %s" % item)
 -    resp = s.quit()
 -    print(resp)
 +
 +    def cut(s, lim):
 +        if len(s) > lim:
 +            s = s[:lim - 4] + "..."
 +        return s
 +
 +    first = str(int(last) - args.nb_articles + 1)
 +    resp, overviews = s.xover(first, last)
 +    for artnum, over in overviews:
 +        author = decode_header(over['from']).split('<', 1)[0]
 +        subject = decode_header(over['subject'])
 +        lines = int(over[':lines'])
 +        print("{:7} {:20} {:42} ({})".format(
 +              artnum, cut(author, 20), cut(subject, 42), lines)
 +              )
 +
 +    s.quit()
index 18aec290e89f15e819a5748dd0c69ca647fe4a80,3d32c3ea1923a6bde9b8dfbe57903e03377011ed..089b3bac112937decf849e7758686825f168c1d4
@@@ -672,20 -648,8 +672,20 @@@ class StreamRequestHandler(BaseRequestH
      rbufsize = -1
      wbufsize = 0
  
-     # Disable nagle algoritm for this socket, if True.
 +    # A timeout to apply to the request socket, if not None.
 +    timeout = None
 +
++    # Disable nagle algorithm for this socket, if True.
 +    # Use only when wbufsize != 0, to avoid small packets.
 +    disable_nagle_algorithm = False
 +
      def setup(self):
          self.connection = self.request
 +        if self.timeout is not None:
 +            self.connection.settimeout(self.timeout)
 +        if self.disable_nagle_algorithm:
 +            self.connection.setsockopt(socket.IPPROTO_TCP,
 +                                       socket.TCP_NODELAY, True)
          self.rfile = self.connection.makefile('rb', self.rbufsize)
          self.wfile = self.connection.makefile('wb', self.wbufsize)
  
index 3325785c73c5cd63b90197665f6a7eac67fff1a5,749a5517b1957a5ccbcb5a8c24e881335c6aacdb..58ef2979a051018a16909f856da2e73945680a08
@@@ -190,10 -177,10 +190,10 @@@ if 1
              self.assertEqual(eval("-" + all_one_bits), -18446744073709551615)
          else:
              self.fail("How many bits *does* this machine have???")
-         # Verify treatment of contant folding on -(sys.maxsize+1)
+         # Verify treatment of constant folding on -(sys.maxsize+1)
          # i.e. -2147483648 on 32 bit platforms.  Should return int, not long.
 -        self.assertTrue(isinstance(eval("%s" % (-sys.maxsize - 1)), int))
 -        self.assertTrue(isinstance(eval("%s" % (-sys.maxsize - 2)), int))
 +        self.assertIsInstance(eval("%s" % (-sys.maxsize - 1)), int)
 +        self.assertIsInstance(eval("%s" % (-sys.maxsize - 2)), int)
  
      if sys.maxsize == 9223372036854775807:
          def test_32_63_bit_values(self):
Simple merge
index b0c953731e5cab52ba81af36c35c585d27e5d53a,0000000000000000000000000000000000000000..bef3d4c35de58d1eed8455c9e57e79db24912da4
mode 100644,000000..100644
--- /dev/null
@@@ -1,206 -1,0 +1,206 @@@
- # test interactions betwen int, float, Decimal and Fraction
++# test interactions between int, float, Decimal and Fraction
 +
 +import unittest
 +import random
 +import math
 +import sys
 +import operator
 +from test.support import run_unittest
 +
 +from decimal import Decimal as D
 +from fractions import Fraction as F
 +
 +# Constants related to the hash implementation;  hash(x) is based
 +# on the reduction of x modulo the prime _PyHASH_MODULUS.
 +_PyHASH_MODULUS = sys.hash_info.modulus
 +_PyHASH_INF = sys.hash_info.inf
 +
 +class HashTest(unittest.TestCase):
 +    def check_equal_hash(self, x, y):
 +        # check both that x and y are equal and that their hashes are equal
 +        self.assertEqual(hash(x), hash(y),
 +                         "got different hashes for {!r} and {!r}".format(x, y))
 +        self.assertEqual(x, y)
 +
 +    def test_bools(self):
 +        self.check_equal_hash(False, 0)
 +        self.check_equal_hash(True, 1)
 +
 +    def test_integers(self):
 +        # check that equal values hash equal
 +
 +        # exact integers
 +        for i in range(-1000, 1000):
 +            self.check_equal_hash(i, float(i))
 +            self.check_equal_hash(i, D(i))
 +            self.check_equal_hash(i, F(i))
 +
 +        # the current hash is based on reduction modulo 2**n-1 for some
 +        # n, so pay special attention to numbers of the form 2**n and 2**n-1.
 +        for i in range(100):
 +            n = 2**i - 1
 +            if n == int(float(n)):
 +                self.check_equal_hash(n, float(n))
 +                self.check_equal_hash(-n, -float(n))
 +            self.check_equal_hash(n, D(n))
 +            self.check_equal_hash(n, F(n))
 +            self.check_equal_hash(-n, D(-n))
 +            self.check_equal_hash(-n, F(-n))
 +
 +            n = 2**i
 +            self.check_equal_hash(n, float(n))
 +            self.check_equal_hash(-n, -float(n))
 +            self.check_equal_hash(n, D(n))
 +            self.check_equal_hash(n, F(n))
 +            self.check_equal_hash(-n, D(-n))
 +            self.check_equal_hash(-n, F(-n))
 +
 +        # random values of various sizes
 +        for _ in range(1000):
 +            e = random.randrange(300)
 +            n = random.randrange(-10**e, 10**e)
 +            self.check_equal_hash(n, D(n))
 +            self.check_equal_hash(n, F(n))
 +            if n == int(float(n)):
 +                self.check_equal_hash(n, float(n))
 +
 +    def test_binary_floats(self):
 +        # check that floats hash equal to corresponding Fractions and Decimals
 +
 +        # floats that are distinct but numerically equal should hash the same
 +        self.check_equal_hash(0.0, -0.0)
 +
 +        # zeros
 +        self.check_equal_hash(0.0, D(0))
 +        self.check_equal_hash(-0.0, D(0))
 +        self.check_equal_hash(-0.0, D('-0.0'))
 +        self.check_equal_hash(0.0, F(0))
 +
 +        # infinities and nans
 +        self.check_equal_hash(float('inf'), D('inf'))
 +        self.check_equal_hash(float('-inf'), D('-inf'))
 +
 +        for _ in range(1000):
 +            x = random.random() * math.exp(random.random()*200.0 - 100.0)
 +            self.check_equal_hash(x, D.from_float(x))
 +            self.check_equal_hash(x, F.from_float(x))
 +
 +    def test_complex(self):
 +        # complex numbers with zero imaginary part should hash equal to
 +        # the corresponding float
 +
 +        test_values = [0.0, -0.0, 1.0, -1.0, 0.40625, -5136.5,
 +                       float('inf'), float('-inf')]
 +
 +        for zero in -0.0, 0.0:
 +            for value in test_values:
 +                self.check_equal_hash(value, complex(value, zero))
 +
 +    def test_decimals(self):
 +        # check that Decimal instances that have different representations
 +        # but equal values give the same hash
 +        zeros = ['0', '-0', '0.0', '-0.0e10', '000e-10']
 +        for zero in zeros:
 +            self.check_equal_hash(D(zero), D(0))
 +
 +        self.check_equal_hash(D('1.00'), D(1))
 +        self.check_equal_hash(D('1.00000'), D(1))
 +        self.check_equal_hash(D('-1.00'), D(-1))
 +        self.check_equal_hash(D('-1.00000'), D(-1))
 +        self.check_equal_hash(D('123e2'), D(12300))
 +        self.check_equal_hash(D('1230e1'), D(12300))
 +        self.check_equal_hash(D('12300'), D(12300))
 +        self.check_equal_hash(D('12300.0'), D(12300))
 +        self.check_equal_hash(D('12300.00'), D(12300))
 +        self.check_equal_hash(D('12300.000'), D(12300))
 +
 +    def test_fractions(self):
 +        # check special case for fractions where either the numerator
 +        # or the denominator is a multiple of _PyHASH_MODULUS
 +        self.assertEqual(hash(F(1, _PyHASH_MODULUS)), _PyHASH_INF)
 +        self.assertEqual(hash(F(-1, 3*_PyHASH_MODULUS)), -_PyHASH_INF)
 +        self.assertEqual(hash(F(7*_PyHASH_MODULUS, 1)), 0)
 +        self.assertEqual(hash(F(-_PyHASH_MODULUS, 1)), 0)
 +
 +    def test_hash_normalization(self):
 +        # Test for a bug encountered while changing long_hash.
 +        #
 +        # Given objects x and y, it should be possible for y's
 +        # __hash__ method to return hash(x) in order to ensure that
 +        # hash(x) == hash(y).  But hash(x) is not exactly equal to the
 +        # result of x.__hash__(): there's some internal normalization
 +        # to make sure that the result fits in a C long, and is not
 +        # equal to the invalid hash value -1.  This internal
 +        # normalization must therefore not change the result of
 +        # hash(x) for any x.
 +
 +        class HalibutProxy:
 +            def __hash__(self):
 +                return hash('halibut')
 +            def __eq__(self, other):
 +                return other == 'halibut'
 +
 +        x = {'halibut', HalibutProxy()}
 +        self.assertEqual(len(x), 1)
 +
 +class ComparisonTest(unittest.TestCase):
 +    def test_mixed_comparisons(self):
 +
 +        # ordered list of distinct test values of various types:
 +        # int, float, Fraction, Decimal
 +        test_values = [
 +            float('-inf'),
 +            D('-1e999999999'),
 +            -1e308,
 +            F(-22, 7),
 +            -3.14,
 +            -2,
 +            0.0,
 +            1e-320,
 +            True,
 +            F('1.2'),
 +            D('1.3'),
 +            float('1.4'),
 +            F(275807, 195025),
 +            D('1.414213562373095048801688724'),
 +            F(114243, 80782),
 +            F(473596569, 84615),
 +            7e200,
 +            D('infinity'),
 +            ]
 +        for i, first in enumerate(test_values):
 +            for second in test_values[i+1:]:
 +                self.assertLess(first, second)
 +                self.assertLessEqual(first, second)
 +                self.assertGreater(second, first)
 +                self.assertGreaterEqual(second, first)
 +
 +    def test_complex(self):
 +        # comparisons with complex are special:  equality and inequality
 +        # comparisons should always succeed, but order comparisons should
 +        # raise TypeError.
 +        z = 1.0 + 0j
 +        w = -3.14 + 2.7j
 +
 +        for v in 1, 1.0, F(1), D(1), complex(1):
 +            self.assertEqual(z, v)
 +            self.assertEqual(v, z)
 +
 +        for v in 2, 2.0, F(2), D(2), complex(2):
 +            self.assertNotEqual(z, v)
 +            self.assertNotEqual(v, z)
 +            self.assertNotEqual(w, v)
 +            self.assertNotEqual(v, w)
 +
 +        for v in (1, 1.0, F(1), D(1), complex(1),
 +                  2, 2.0, F(2), D(2), complex(2), w):
 +            for op in operator.le, operator.lt, operator.ge, operator.gt:
 +                self.assertRaises(TypeError, op, z, v)
 +                self.assertRaises(TypeError, op, v, z)
 +
 +
 +def test_main():
 +    run_unittest(HashTest, ComparisonTest)
 +
 +if __name__ == '__main__':
 +    test_main()
Simple merge
Simple merge
Simple merge
index 2ce7764765c030cf25ac8aa0f44d215cfd10d2b3,77f5be033a76ccbed1cde3320aff2e6900c1627f..c8865fe6245ae52e095a8063bd8d259a3e84b885
@@@ -758,21 -692,29 +758,21 @@@ class PyEnvironmentVariableTests(Enviro
  class BootstrapTest(unittest.TestCase):
      def test_issue_8766(self):
          # "import encodings" emits a warning whereas the warnings is not loaded
-         # or not completly loaded (warnings imports indirectly encodings by
+         # or not completely loaded (warnings imports indirectly encodings by
          # importing linecache) yet
 -        cwd = tempfile.mkdtemp()
 -        try:
 -            encodings = os.path.join(cwd, 'encodings')
 -            os.mkdir(encodings)
 -            try:
 -                env = os.environ.copy()
 -                env['PYTHONPATH'] = cwd
 -
 -                # encodings loaded by initfsencoding()
 -                retcode = subprocess.call([sys.executable, '-c', 'pass'], env=env)
 -                self.assertEqual(retcode, 0)
 -
 -                # Use -W to load warnings module at startup
 -                retcode = subprocess.call(
 -                    [sys.executable, '-c', 'pass', '-W', 'always'],
 -                    env=env)
 -                self.assertEqual(retcode, 0)
 -            finally:
 -                os.rmdir(encodings)
 -        finally:
 -            os.rmdir(cwd)
 +        with support.temp_cwd() as cwd, support.temp_cwd('encodings'):
 +            env = os.environ.copy()
 +            env['PYTHONPATH'] = cwd
 +
 +            # encodings loaded by initfsencoding()
 +            retcode = subprocess.call([sys.executable, '-c', 'pass'], env=env)
 +            self.assertEqual(retcode, 0)
 +
 +            # Use -W to load warnings module at startup
 +            retcode = subprocess.call(
 +                [sys.executable, '-c', 'pass', '-W', 'always'],
 +                env=env)
 +            self.assertEqual(retcode, 0)
  
  def test_main():
      py_warnings.onceregistry.clear()
Simple merge
Simple merge
Simple merge
diff --cc Lib/turtle.py
Simple merge
Simple merge
Simple merge
index 0b2fafc68a99bdeb1863a5b1ceb7958a5695b086,e70a76f846f5ce84659b4f2306ee544658f8d8da..30c82ac4760de0702c705c8dc465040fa64d4c0f
   * application bundle inside the Python framework. This is needed to run
   * GUI code: some GUI API's don't work unless the program is inside an
   * application bundle.
 + *
 + * This program uses posix_spawn rather than plain execv because we need
 + * slightly more control over how the "real" interpreter is executed.
 + *
 + * On OSX 10.4 (and earlier) this falls back to using exec because the
 + * posix_spawnv functions aren't available there.
   */
 +
 +#pragma weak_import posix_spawnattr_init
 +#pragma weak_import posix_spawnattr_setbinpref_np
 +#pragma weak_import posix_spawnattr_setflags
 +#pragma weak_import posix_spawn
 +
 +#include <Python.h>
  #include <unistd.h>
 +#ifdef HAVE_SPAWN_H
 +#include <spawn.h>
 +#endif
 +#include <stdio.h>
 +#include <string.h>
 +#include <errno.h>
  #include <err.h>
-     /* Run the real python executable using the same architure as this
-      * executable, this allows users to controle the architecture using
 +#include <dlfcn.h>
 +#include <stdlib.h>
 +#include <Python.h>
 +
 +
 +extern char** environ;
 +
 +/*
 + * Locate the python framework by looking for the
 + * library that contains Py_Initialize.
 + *
 + * In a regular framework the structure is:
 + *
 + *    Python.framework/Versions/2.7
 + *              /Python
 + *              /Resources/Python.app/Contents/MacOS/Python
 + *
 + * In a virtualenv style structure the expected
 + * structure is:
 + *
 + *    ROOT
 + *       /bin/pythonw
 + *       /.Python   <- the dylib
 + *       /.Resources/Python.app/Contents/MacOS/Python
 + *
 + * NOTE: virtualenv's are not an officially supported
 + * feature, support for that structure is provided as
 + * a convenience.
 + */
 +static char* get_python_path(void)
 +{
 +    size_t len;
 +    Dl_info info;
 +    char* end;
 +    char* g_path;
 +
 +    if (dladdr(Py_Initialize, &info) == 0) {
 +        return NULL;
 +    }
 +
 +    len = strlen(info.dli_fname);
 +
 +    g_path = malloc(len+60);
 +    if (g_path == NULL) {
 +        return NULL;
 +    }
 +
 +    strcpy(g_path, info.dli_fname);
 +    end = g_path + len - 1;
 +    while (end != g_path && *end != '/') {
 +        end --;
 +    }
 +    end++;
 +    if (*end == '.') {
 +        end++;
 +    }
 +    strcpy(end, "Resources/Python.app/Contents/MacOS/" PYTHONFRAMEWORK);
 +
 +    return g_path;
 +}
 +
 +#ifdef HAVE_SPAWN_H
 +static void
 +setup_spawnattr(posix_spawnattr_t* spawnattr)
 +{
 +    size_t ocount;
 +    size_t count;
 +    cpu_type_t cpu_types[1];
 +    short flags = 0;
 +#ifdef __LP64__
 +    int   ch;
 +#endif
 +
 +    if ((errno = posix_spawnattr_init(spawnattr)) != 0) {
 +        err(2, "posix_spawnattr_int");
 +        /* NOTREACHTED */
 +    }
 +
 +    count = 1;
 +
++    /* Run the real python executable using the same architecture as this
++     * executable, this allows users to control the architecture using
 +     * "arch -ppc python"
 +     */
 +
 +#if defined(__ppc64__)
 +    cpu_types[0] = CPU_TYPE_POWERPC64;
 +
 +#elif defined(__x86_64__)
 +    cpu_types[0] = CPU_TYPE_X86_64;
 +
 +#elif defined(__ppc__)
 +    cpu_types[0] = CPU_TYPE_POWERPC;
 +#elif defined(__i386__)
 +    cpu_types[0] = CPU_TYPE_X86;
 +#else
 +#       error "Unknown CPU"
 +#endif
 +
 +    if (posix_spawnattr_setbinpref_np(spawnattr, count,
 +                            cpu_types, &ocount) == -1) {
 +        err(1, "posix_spawnattr_setbinpref");
 +        /* NOTREACHTED */
 +    }
 +    if (count != ocount) {
 +        fprintf(stderr, "posix_spawnattr_setbinpref failed to copy\n");
 +        exit(1);
 +        /* NOTREACHTED */
 +    }
 +
 +
 +    /*
 +     * Set flag that causes posix_spawn to behave like execv
 +     */
 +    flags |= POSIX_SPAWN_SETEXEC;
 +    if ((errno = posix_spawnattr_setflags(spawnattr, flags)) != 0) {
 +        err(1, "posix_spawnattr_setflags");
 +        /* NOTREACHTED */
 +    }
 +}
 +#endif
 +
 +int
 +main(int argc, char **argv) {
 +    char* exec_path = get_python_path();
 +
 +    /*
 +     * Let argv[0] refer to the new interpreter. This is needed to
 +     * get the effect we want on OSX 10.5 or earlier. That is, without
 +     * changing argv[0] the real interpreter won't have access to
 +     * the Window Server.
 +     */
 +    argv[0] = exec_path;
  
 -static char Python[] = PYTHONWEXECUTABLE;
 +#ifdef HAVE_SPAWN_H
 +    /* We're weak-linking to posix-spawnv to ensure that
 +     * an executable build on 10.5 can work on 10.4.
 +     */
 +    if (posix_spawn != NULL) {
 +        posix_spawnattr_t spawnattr = NULL;
  
 -int main(int argc, char **argv) {
 -      argv[0] = Python;
 -      execv(Python, argv);
 -      err(1, "execv: %s", Python);
 -      /* NOTREACHED */
 +        setup_spawnattr(&spawnattr);
 +        posix_spawn(NULL, exec_path, NULL,
 +            &spawnattr, argv, environ);
 +        err(1, "posix_spawn: %s", exec_path);
 +    }
 +#endif
 +    execve(exec_path, argv, environ);
 +    err(1, "execve: %s", argv[0]);
 +    /* NOTREACHED */
  }
Simple merge
index 00ba7efc1dffb1a62c71b12b2f83d2d077877fa7,0000000000000000000000000000000000000000..78853c42f56eaddf8ca7087b78cdbefccef2326c
mode 100644,000000..100644
--- /dev/null
@@@ -1,4145 -1,0 +1,4145 @@@
-       * src/sh/ffi.c (ffi_prep_args): Take account into the alignement
 +2010-03-14  Matthias Klose  <doko@ubuntu.com>
 +
 +      * src/x86/ffi64.c: Fix typo in comment.
 +      * src/x86/ffi.c: Use /* ... */ comment style.
 +
 +2010-01-07  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 +
 +      PR libffi/40701
 +      * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL,
 +      PRIuLL, PRId64, PRIu64, PRIuPTR): Define.
 +      * testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on
 +      alpha*-dec-osf*.
 +      * testsuite/libffi.call/cls_align_uint64.c: Likewise.
 +      * testsuite/libffi.call/cls_ulonglong.c: Likewise.
 +      * testsuite/libffi.call/return_ll1.c: Likewise.
 +      * testsuite/libffi.call/stret_medium2.c: Likewise.
 +      * testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast
 +      MAP_FAILED to char *.
 +
 +2010-01-06  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 +
 +      * src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__.
 +
 +2009-12-31  Anthony Green  <green@redhat.com>
 +
 +      * README: Update for libffi 3.0.9.
 +
 +2009-12-27  Matthias Klose  <doko@ubuntu.com>
 +
 +      * configure.ac (HAVE_LONG_DOUBLE): Define for mips when
 +      appropriate.
 +      * configure: Rebuilt.
 +
 +2009-12-26  Anthony Green  <green@redhat.com>
 +
 +      * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for
 +      avr32*-*-*.
 +      * testsuite/libffi.call/cls_double_va.c: Ditto.
 +
 +2009-12-26  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h
 +      and inttypes.h.
 +      * testsuite/libffi.special/unwindtest.cc: Ditto.
 +
 +2009-12-26  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * configure.ac: Add amd64-*-openbsd*.
 +      * configure: Rebuilt.
 +      * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link
 +      openbsd programs with -lpthread.
 +
 +2009-12-26  Anthony Green  <green@redhat.com>
 +
 +      * testsuite/libffi.call/cls_double_va.c,
 +      testsuite/libffi.call/cls_longdouble.c,
 +      testsuite/libffi.call/cls_longdouble_va.c,
 +      testsuite/libffi.call/cls_pointer.c,
 +      testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for
 +      mips*-*-* and arm*-*-*.
 +      * testsuite/libffi.call/cls_align_longdouble_split.c,
 +      testsuite/libffi.call/cls_align_longdouble_split2.c,
 +      testsuite/libffi.call/stret_medium2.c,
 +      testsuite/libffi.call/stret_medium.c,
 +      testsuite/libffi.call/stret_large.c,
 +      testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*.
 +
 +2009-12-31  Kay Tietz  <ktietz70@googlemail.com>
 +
 +      * testsuite/libffi.call/ffitest.h,
 +      testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix
 +      definitions.
 +
 +2009-12-31  Carlo Bramini  <carlo.bramix@libero.it>
 +
 +      * configure.ac (AM_LTLDFLAGS): Define for windows hosts.
 +      * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS.
 +      * configure: Rebuilt.
 +      * Makefile.in: Rebuilt.
 +
 +2009-12-31  Anthony Green  <green@redhat.com>
 +          Blake Chaffin.
 +
 +      * testsuite/libffi.call/huge_struct.c: New test case from Blake
 +      Chaffin @ Apple.
 +
 +2009-12-28  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to
 +      local variables.
 +      (aix_adjust_aggregate_sizes): New function.
 +      (ffi_prep_cif_machdep): Call it.
 +
 +2009-12-26  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets.
 +      * configure: Regenerate.
 +      * fficonfig.h.in: Likewise.
 +      * src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for
 +      Solaris/x86.
 +
 +2009-12-26  Andreas Schwab  <schwab@linux-m68k.org>
 +
 +      * src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count
 +      when a float arguments is passed in memory.
 +      (ffi_closure_helper_SYSV): Mark general registers as used up when
 +      a 64bit or soft-float long double argument is passed in memory.
 +
 +2009-12-25  Matthias Klose  <doko@ubuntu.com>
 +
 +      * man/ffi_call.3: Fix #include in examples.
 +      * doc/libffi.texi: Add dircategory.
 +
 +2009-12-25  Frank Everdij <f.p.x.everdij@tudelft.nl>
 +
 +      * include/ffi.h.in: Placed '__GNUC__' ifdef around
 +      '__attribute__((aligned(8)))' in ffi_closure, fixes compile for
 +      IRIX MIPSPro c99.
 +      * include/ffi_common.h: Added '__sgi' define to non
 +      '__attribute__((__mode__()))' integer typedefs.
 +      * src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32,
 +      ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check.
 +      (ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added
 +      FFI_LONGDOUBLE support and alignment(N32 only).
 +      * src/mips/ffitarget.h: Corrected '#include <sgidefs.h>' for IRIX and
 +      fixed non '__attribute__((__mode__()))' integer typedefs.
 +      * src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame'
 +      since they are Linux/GNU Assembler specific.
 +
 +2009-12-25  Bradley Smith  <brad@brad-smith.co.uk>
 +
 +      * configure.ac, Makefile.am, src/avr32/ffi.c,
 +      src/avr32/ffitarget.h,
 +      src/avr32/sysv.S: Add AVR32 port.
 +      * configure, Makefile.in: Rebuilt.
 +
 +2009-12-21  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * configure.ac: Make i?86 build on FreeBSD and OpenBSD.
 +      * configure: Regenerate.
 +
 +2009-12-15  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 +
 +      * testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX.
 +
 +2009-12-13  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 +
 +      * src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE
 +      type on HP-UX.
 +
 +2009-12-11  Eric Botcazou  <ebotcazou@adacore.com>
 +
 +      * src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long
 +      double' arguments.
 +
 +2009-12-11  Eric Botcazou  <ebotcazou@adacore.com>
 +
 +      * testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10.
 +
 +2009-12-10  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 +
 +      PR libffi/40700
 +      * src/closures.c [X86_64 && __sun__ && __svr4__]
 +      (FFI_MMAP_EXEC_WRIT): Define.
 +
 +2009-12-08  David Daney  <ddaney@caviumnetworks.com>
 +
 +      * testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-*
 +      * testsuite/libffi.call/cls_align_longdouble_split2.c: Same.
 +      * testsuite/libffi.call/stret_large.c: Same.
 +      * testsuite/libffi.call/cls_align_longdouble_split.c: Same.
 +      * testsuite/libffi.call/stret_large2.c: Same.
 +      * testsuite/libffi.call/stret_medium2.c: Same.
 +
 +2009-12-07  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump
 +      typo.
 +
 +2009-12-05  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64
 +      code.
 +      * src/powerpc/aix_closure.S: Same.
 +
 +2009-12-05  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * Makefile.in: Regenerate.
 +      * configure: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * man/Makefile.in: Regenerate.
 +      * testsuite/Makefile.in: Regenerate.
 +
 +2009-12-04  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/aix_closure.S: Reorganize 64-bit code to match
 +      linux64_closure.S.
 +
 +2009-12-04  Uros Bizjak  <ubizjak@gmail.com>
 +
 +      PR libffi/41908
 +      * src/x86/ffi64.c (classify_argument): Update from
 +      gcc/config/i386/i386.c.
 +      (ffi_closure_unix64_inner): Do not use the address of two consecutive
 +      SSE registers directly.
 +      * testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail
 +      for x86_64 linux targets.
 +
 +2009-12-04  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment
 +      pfr for long double split between fpr13 and stack.
 +
 +2009-12-03  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and
 +      fparg_count twice for long double.
 +
 +2009-12-03  David Edelsohn  <edelsohn@gnu.org>
 +
 +      PR libffi/42243
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses.
 +
 +2009-12-03  Uros Bizjak  <ubizjak@gmail.com>
 +
 +      * testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string.
 +      Remove xfails for x86 linux targets.
 +
 +2009-12-02  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64
 +      case.
 +
 +2009-12-01  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/aix.S (ffi_call_AIX): Convert to more standard
 +      register usage.  Call ffi_prep_args directly.  Add long double
 +      return value support.
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment
 +      applies to FFI_TYPE_DOUBLE.  Correct fpr_base increment typo.
 +      Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases.
 +      (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit
 +      mode.
 +      (ffi_closure_helper_DARWIN): Remove nf and ng counters.  Move temp
 +      into case.
 +      * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment.
 +      Allocate result area between params and FPRs.
 +
 +2009-11-30  David Edelsohn  <edelsohn@gnu.org>
 +
 +      PR target/35484
 +      * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and
 +      AIX64.
 +      * src/powerpc/aix.S: Implement AIX64 version.
 +      * src/powerpc/aix_closure.S: Implement AIX64 version.
 +      (ffi_closure_ASM): Use extsb, lha and displament addresses.
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64
 +      support.
 +      (ffi_prep_cif_machdep): Same.
 +      (ffi_call): Same.
 +      (ffi_closure_helper_DARWIN): Same.
 +
 +2009-11-02  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      PR libffi/41908
 +      * testsuite/libffi.call/testclosure.c: New test.
 +
 +2009-09-28  Kai Tietz  <kai.tietz@onevision.com>
 +
 +      * src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu
 +      assembly version use of ___chkstk.
 +
 +2009-09-23  Matthias Klose  <doko@ubuntu.com>
 +
 +      PR libffi/40242, PR libffi/41443
 +      * src/arm/sysv.S (__ARM_ARCH__): Define for processors
 +      __ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__,
 +      __ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__.
 +      Change the conditionals to __SOFTFP__ || __ARM_EABI__
 +      for -mfloat-abi=softfp to work.
 +
 +2009-09-17  Loren J. Rittle  <ljrittle@acm.org>
 +
 +      PR testsuite/32843 (strikes again)
 +      * src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to
 +      enable proper extension on char and short.
 +
 +2009-09-15  David Daney  <ddaney@caviumnetworks.com>
 +
 +      * src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special
 +      handling for FFI_TYPE_POINTER.
 +      * src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT,
 +      FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT,
 +      FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT,
 +      FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines.
 +      (FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations.
 +      (enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float.
 +      * src/mips/n32.S (ffi_call_N32): Add handling for soft-float
 +      structure and pointer returns.
 +      (ffi_closure_N32): Add handling for pointer returns.
 +      * src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags,
 +      calc_n32_return_struct_flags): Handle soft-float.
 +      (ffi_prep_cif_machdep):  Handle soft-float, fix pointer handling.
 +      (ffi_call_N32): Declare proper argument types.
 +      (ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle
 +      soft-float.
 +
 +2009-08-24  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * configure.ac (AC_PREREQ): Bump to 2.64.
 +
 +2009-08-22  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * Makefile.am (install-html, install-pdf): Remove.
 +      * Makefile.in: Regenerate.
 +
 +      * Makefile.in: Regenerate.
 +      * aclocal.m4: Regenerate.
 +      * configure: Regenerate.
 +      * fficonfig.h.in: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * man/Makefile.in: Regenerate.
 +      * testsuite/Makefile.in: Regenerate.
 +
 +2009-07-30  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force.
 +
 +2009-07-24  Dave Korn  <dave.korn.cygwin@gmail.com>
 +
 +      PR libffi/40807
 +      * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending
 +      return types for X86_WIN32.
 +      * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types.
 +      (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV,
 +      _ffi_closure_STDCALL): Likewise.
 +
 +      * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin.
 +      (dlmmap, dlmunmap): Also use these functions on Cygwin.
 +
 +2009-07-11  Richard Sandiford  <rdsandiford@googlemail.com>
 +
 +      PR testsuite/40699
 +      PR testsuite/40707
 +      PR testsuite/40709
 +      * testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and
 +      2009-06-30 commits.
 +
 +2009-07-01  Richard Sandiford  <r.sandiford@uk.ibm.com>
 +
 +      * testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path
 +      to "" before adding paths.  (This reinstates an assignment that
 +      was removed by my 2009-06-30 commit, but changes the initial
 +      value from "." to "".)
 +
 +2009-07-01  H.J. Lu  <hongjiu.lu@intel.com>
 +
 +      PR testsuite/40601
 +      * testsuite/lib/libffi-dg.exp (libffi-init): Properly set
 +      gccdir.  Adjust ld_library_path for gcc only if gccdir isn't
 +      empty.
 +
 +2009-06-30  Richard Sandiford  <r.sandiford@uk.ibm.com>
 +
 +      * testsuite/lib/libffi-dg.exp (libffi-init): Don't add "."
 +      to ld_library_path.  Use add_path.  Add just find_libgcc_s
 +      to ld_library_path, not every libgcc multilib directory.
 +
 +2009-06-16  Wim Lewis  <wiml@hhhh.org>
 +
 +      * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
 +      supposed to be callee-saved.
 +      * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
 +      return buffer for odd-size structs.
 +
 +2009-06-16  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      PR libffi/40444
 +      * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add
 +      allow_stack_execute for Darwin.
 +
 +2009-06-16  Andrew Haley  <aph@redhat.com>
 +
 +      * configure.ac (TARGETDIR): Add missing blank lines.
 +      * configure: Regenerate.
 +
 +2009-06-16  Andrew Haley  <aph@redhat.com>
 +
 +      * testsuite/libffi.call/cls_align_sint64.c,
 +      testsuite/libffi.call/cls_align_uint64.c,
 +      testsuite/libffi.call/cls_longdouble_va.c,
 +      testsuite/libffi.call/cls_ulonglong.c,
 +      testsuite/libffi.call/return_ll1.c,
 +      testsuite/libffi.call/stret_medium2.c: Fix printf format
 +      specifiers.
 +      * testsuite/libffi.call/ffitest.h,
 +      testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
 +
 +2009-06-15  Andrew Haley  <aph@redhat.com>
 +
 +      * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere.
 +      * testsuite/libffi.call/err_bad_abi.c: Likewise.
 +
 +2009-06-12  Andrew Haley  <aph@redhat.com>
 +
 +      * Makefile.am: Remove info_TEXINFOS.
 +
 +2009-06-12  Andrew Haley  <aph@redhat.com>
 +
 +      * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c,
 +      testsuite/libffi.call/cls_align_uint64.c,
 +      testsuite/libffi.call/cls_ulonglong.c,
 +      testsuite/libffi.call/return_ll1.c,
 +      testsuite/libffi.call/stret_medium2.c: Fix printf format
 +      specifiers.
 +      testsuite/libffi.special/unwindtest.cc: include stdint.h.
 +
 +2009-06-11  Timothy Wall  <twall@users.sf.net>
 +
 +      * Makefile.am,
 +      configure.ac,
 +      include/ffi.h.in,
 +      include/ffi_common.h,
 +      src/closures.c,
 +      src/dlmalloc.c,
 +      src/x86/ffi.c,
 +      src/x86/ffitarget.h,
 +      src/x86/win64.S (new),
 +      README: Added win64 support (mingw or MSVC)
 +      * Makefile.in,
 +      include/Makefile.in,
 +      man/Makefile.in,
 +      testsuite/Makefile.in,
 +      configure,
 +      aclocal.m4: Regenerated
 +      * ltcf-c.sh: properly escape cygwin/w32 path
 +      * man/ffi_call.3: Clarify size requirements for return value.
 +      * src/x86/ffi64.c: Fix filename in comment.
 +      * src/x86/win32.S: Remove unused extern.
 +
 +      * testsuite/libffi.call/closure_fn0.c,
 +      testsuite/libffi.call/closure_fn1.c,
 +      testsuite/libffi.call/closure_fn2.c,
 +      testsuite/libffi.call/closure_fn3.c,
 +      testsuite/libffi.call/closure_fn4.c,
 +      testsuite/libffi.call/closure_fn5.c,
 +      testsuite/libffi.call/closure_fn6.c,
 +      testsuite/libffi.call/closure_stdcall.c,
 +      testsuite/libffi.call/cls_12byte.c,
 +      testsuite/libffi.call/cls_16byte.c,
 +      testsuite/libffi.call/cls_18byte.c,
 +      testsuite/libffi.call/cls_19byte.c,
 +      testsuite/libffi.call/cls_1_1byte.c,
 +      testsuite/libffi.call/cls_20byte.c,
 +      testsuite/libffi.call/cls_20byte1.c,
 +      testsuite/libffi.call/cls_24byte.c,
 +      testsuite/libffi.call/cls_2byte.c,
 +      testsuite/libffi.call/cls_3_1byte.c,
 +      testsuite/libffi.call/cls_3byte1.c,
 +      testsuite/libffi.call/cls_3byte2.c,
 +      testsuite/libffi.call/cls_4_1byte.c,
 +      testsuite/libffi.call/cls_4byte.c,
 +      testsuite/libffi.call/cls_5_1_byte.c,
 +      testsuite/libffi.call/cls_5byte.c,
 +      testsuite/libffi.call/cls_64byte.c,
 +      testsuite/libffi.call/cls_6_1_byte.c,
 +      testsuite/libffi.call/cls_6byte.c,
 +      testsuite/libffi.call/cls_7_1_byte.c,
 +      testsuite/libffi.call/cls_7byte.c,
 +      testsuite/libffi.call/cls_8byte.c,
 +      testsuite/libffi.call/cls_9byte1.c,
 +      testsuite/libffi.call/cls_9byte2.c,
 +      testsuite/libffi.call/cls_align_double.c,
 +      testsuite/libffi.call/cls_align_float.c,
 +      testsuite/libffi.call/cls_align_longdouble.c,
 +      testsuite/libffi.call/cls_align_longdouble_split.c,
 +      testsuite/libffi.call/cls_align_longdouble_split2.c,
 +      testsuite/libffi.call/cls_align_pointer.c,
 +      testsuite/libffi.call/cls_align_sint16.c,
 +      testsuite/libffi.call/cls_align_sint32.c,
 +      testsuite/libffi.call/cls_align_sint64.c,
 +      testsuite/libffi.call/cls_align_uint16.c,
 +      testsuite/libffi.call/cls_align_uint32.c,
 +      testsuite/libffi.call/cls_align_uint64.c,
 +      testsuite/libffi.call/cls_dbls_struct.c,
 +      testsuite/libffi.call/cls_double.c,
 +      testsuite/libffi.call/cls_double_va.c,
 +      testsuite/libffi.call/cls_float.c,
 +      testsuite/libffi.call/cls_longdouble.c,
 +      testsuite/libffi.call/cls_longdouble_va.c,
 +      testsuite/libffi.call/cls_multi_schar.c,
 +      testsuite/libffi.call/cls_multi_sshort.c,
 +      testsuite/libffi.call/cls_multi_sshortchar.c,
 +      testsuite/libffi.call/cls_multi_uchar.c,
 +      testsuite/libffi.call/cls_multi_ushort.c,
 +      testsuite/libffi.call/cls_multi_ushortchar.c,
 +      testsuite/libffi.call/cls_pointer.c,
 +      testsuite/libffi.call/cls_pointer_stack.c,
 +      testsuite/libffi.call/cls_schar.c,
 +      testsuite/libffi.call/cls_sint.c,
 +      testsuite/libffi.call/cls_sshort.c,
 +      testsuite/libffi.call/cls_uchar.c,
 +      testsuite/libffi.call/cls_uint.c,
 +      testsuite/libffi.call/cls_ulonglong.c,
 +      testsuite/libffi.call/cls_ushort.c,
 +      testsuite/libffi.call/err_bad_abi.c,
 +      testsuite/libffi.call/err_bad_typedef.c,
 +      testsuite/libffi.call/float2.c,
 +      testsuite/libffi.call/huge_struct.c,
 +      testsuite/libffi.call/nested_struct.c,
 +      testsuite/libffi.call/nested_struct1.c,
 +      testsuite/libffi.call/nested_struct10.c,
 +      testsuite/libffi.call/nested_struct2.c,
 +      testsuite/libffi.call/nested_struct3.c,
 +      testsuite/libffi.call/nested_struct4.c,
 +      testsuite/libffi.call/nested_struct5.c,
 +      testsuite/libffi.call/nested_struct6.c,
 +      testsuite/libffi.call/nested_struct7.c,
 +      testsuite/libffi.call/nested_struct8.c,
 +      testsuite/libffi.call/nested_struct9.c,
 +      testsuite/libffi.call/problem1.c,
 +      testsuite/libffi.call/return_ldl.c,
 +      testsuite/libffi.call/return_ll1.c,
 +      testsuite/libffi.call/stret_large.c,
 +      testsuite/libffi.call/stret_large2.c,
 +      testsuite/libffi.call/stret_medium.c,
 +      testsuite/libffi.call/stret_medium2.c,
 +      testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
 +      of checking for MMAP.  Use intptr_t instead of long casts.
 +
 +2009-06-11  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*.
 +      * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*.
 +      * testsuite/libffi.call/err_bad_typedef.c: Likewise.
 +
 +2009-06-09  Andrew Haley  <aph@redhat.com>
 +
 +      * src/x86/freebsd.S: Add missing file.
 +
 +2009-06-08  Andrew Haley  <aph@redhat.com>
 +
 +      Import from libffi 3.0.8:
 +
 +      * doc/libffi.texi: New file.
 +      * doc/libffi.info: Likewise.
 +      * doc/stamp-vti: Likewise.
 +      * man/Makefile.am: New file.
 +      * man/ffi_call.3: New file.
 +
 +      * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S,
 +      src/dlmalloc.c.
 +      (nodist_libffi_la_SOURCES): Add X86_FREEBSD.
 +
 +      * configure.ac: Bump version to 3.0.8.
 +      parisc*-*-linux*: Add.
 +      i386-*-freebsd* | i386-*-openbsd*: Add.
 +      powerpc-*-beos*: Add.
 +      AM_CONDITIONAL X86_FREEBSD: Add.
 +      AC_CONFIG_FILES: Add man/Makefile.
 +
 +      * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void).
 +
 +2009-06-08  Andrew Haley  <aph@redhat.com>
 +
 +      * README: Import from libffi 3.0.8.
 +
 +2009-06-08  Andrew Haley  <aph@redhat.com>
 +
 +      * testsuite/libffi.call/err_bad_abi.c: Add xfails.
 +      * testsuite/libffi.call/cls_longdouble_va.c: Add xfails.
 +      * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*.
 +      * testsuite/libffi.call/err_bad_typedef.c: Add xfails.
 +
 +      * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args.
 +      * testsuite/libffi.call/stret_medium.c: Likewise.
 +      * testsuite/libffi.call/stret_large2.c: Likewise.
 +      * testsuite/libffi.call/stret_large.c:  Likewise.
 +
 +2008-12-26  Timothy Wall  <twall@users.sf.net>
 +
 +      * testsuite/libffi.call/cls_longdouble.c,
 +      testsuite/libffi.call/cls_longdouble_va.c,
 +      testsuite/libffi.call/cls_align_longdouble.c,
 +      testsuite/libffi.call/cls_align_longdouble_split.c,
 +      testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
 +      failures on x86_64 cygwin/mingw.
 +
 +2008-12-22  Timothy Wall  <twall@users.sf.net>
 +
 +      * testsuite/libffi.call/closure_fn0.c,
 +      testsuite/libffi.call/closure_fn1.c,
 +      testsuite/libffi.call/closure_fn2.c,
 +      testsuite/libffi.call/closure_fn3.c,
 +      testsuite/libffi.call/closure_fn4.c,
 +      testsuite/libffi.call/closure_fn5.c,
 +      testsuite/libffi.call/closure_fn6.c,
 +      testsuite/libffi.call/closure_loc_fn0.c,
 +      testsuite/libffi.call/closure_stdcall.c,
 +      testsuite/libffi.call/cls_align_pointer.c,
 +      testsuite/libffi.call/cls_pointer.c,
 +      testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
 +      pointer to integer (intptr_t).
 +      * testsuite/libffi.call/cls_longdouble.c: disable for win64.
 +
 +2008-07-24  Anthony Green  <green@redhat.com>
 +
 +      * testsuite/libffi.call/cls_dbls_struct.c,
 +      testsuite/libffi.call/cls_double_va.c,
 +      testsuite/libffi.call/cls_longdouble.c,
 +      testsuite/libffi.call/cls_longdouble_va.c,
 +      testsuite/libffi.call/cls_pointer.c,
 +      testsuite/libffi.call/cls_pointer_stack.c,
 +      testsuite/libffi.call/err_bad_abi.c: Clean up failures from
 +      compiler warnings.
 +
 +2008-03-04  Anthony Green  <green@redhat.com>
 +          Blake Chaffin
 +          hos@tamanegi.org
 +
 +      * testsuite/libffi.call/cls_align_longdouble_split2.c
 +        testsuite/libffi.call/cls_align_longdouble_split.c
 +        testsuite/libffi.call/cls_dbls_struct.c
 +        testsuite/libffi.call/cls_double_va.c
 +        testsuite/libffi.call/cls_longdouble.c
 +        testsuite/libffi.call/cls_longdouble_va.c
 +        testsuite/libffi.call/cls_pointer.c
 +        testsuite/libffi.call/cls_pointer_stack.c
 +        testsuite/libffi.call/err_bad_abi.c
 +        testsuite/libffi.call/err_bad_typedef.c
 +        testsuite/libffi.call/stret_large2.c
 +        testsuite/libffi.call/stret_large.c
 +        testsuite/libffi.call/stret_medium2.c
 +        testsuite/libffi.call/stret_medium.c: New tests from Apple.
 +
 +2009-06-05  Andrew Haley  <aph@redhat.com>
 +
 +      * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from
 +      libffi.
 +
 +2009-06-04  Andrew Haley  <aph@redhat.com>
 +
 +      * src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out
 +      stdcall changes.
 +
 +2008-02-26  Anthony Green  <green@redhat.com>
 +          Thomas Heller  <theller@ctypes.org>
 +
 +      * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
 +      comment.
 +
 +2008-02-03  Timothy Wall  <twall@users.sf.net>
 +
 +      * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
 +        offset based on code pointer, not data pointer.
 +
 +2008-01-31  Timothy Wall <twall@users.sf.net>
 +
 +      * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
 +      closures.
 +      * src/x86/ffitarget.h: Increase size of trampoline for stdcall
 +      closures.
 +      * src/x86/win32.S: Add assembly for stdcall closure.
 +      * src/x86/ffi.c: Initialize stdcall closure trampoline.
 +
 +2009-06-04  Andrew Haley  <aph@redhat.com>
 +
 +      * include/ffi.h.in: Change void (*)() to void (*)(void).
 +      * src/x86/ffi.c: Likewise.
 +
 +2009-06-04  Andrew Haley  <aph@redhat.com>
 +
 +      * src/powerpc/ppc_closure.S: Insert licence header.
 +      * src/powerpc/linux64_closure.S: Likewise.
 +      * src/m68k/sysv.S: Likewise.
 +
 +      * src/sh64/ffi.c: Change void (*)() to void (*)(void).
 +      * src/powerpc/ffi.c: Likewise.
 +      * src/powerpc/ffi_darwin.c: Likewise.
 +      * src/m32r/ffi.c: Likewise.
 +      * src/sh64/ffi.c: Likewise.
 +      * src/x86/ffi64.c: Likewise.
 +      * src/alpha/ffi.c: Likewise.
 +      * src/alpha/osf.S: Likewise.
 +      * src/frv/ffi.c: Likewise.
 +      * src/s390/ffi.c: Likewise.
 +      * src/pa/ffi.c: Likewise.
 +      * src/pa/hpux32.S: Likewise.
 +      * src/ia64/unix.S: Likewise.
 +      * src/ia64/ffi.c: Likewise.
 +      * src/sparc/ffi.c: Likewise.
 +      * src/mips/ffi.c: Likewise.
 +      * src/sh/ffi.c: Likewise.
 +
 +2008-02-15  David Daney  <ddaney@avtrex.com>
 +
 +      * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
 +      Define (conditionally), and use it to include cachectl.h.
 +      (ffi_prep_closure_loc): Fix cache flushing.
 +      * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
 +
 +2009-06-04  Andrew Haley  <aph@redhat.com>
 +
 +      include/ffi.h.in,
 +      src/arm/ffitarget.h,
 +      src/arm/ffi.c,
 +      src/arm/sysv.S,
 +      src/powerpc/ffitarget.h,
 +      src/closures.c,
 +      src/sh64/ffitarget.h,
 +      src/sh64/ffi.c,
 +      src/sh64/sysv.S,
 +      src/types.c,
 +      src/x86/ffi64.c,
 +      src/x86/ffitarget.h,
 +      src/x86/win32.S,
 +      src/x86/darwin.S,
 +      src/x86/ffi.c,
 +      src/x86/sysv.S,
 +      src/x86/unix64.S,
 +      src/alpha/ffitarget.h,
 +      src/alpha/ffi.c,
 +      src/alpha/osf.S,
 +      src/m68k/ffitarget.h,
 +      src/frv/ffitarget.h,
 +      src/frv/ffi.c,
 +      src/s390/ffitarget.h,
 +      src/s390/sysv.S,
 +      src/cris/ffitarget.h,
 +      src/pa/linux.S,
 +      src/pa/ffitarget.h,
 +      src/pa/ffi.c,
 +      src/raw_api.c,
 +      src/ia64/ffitarget.h,
 +      src/ia64/unix.S,
 +      src/ia64/ffi.c,
 +      src/ia64/ia64_flags.h,
 +      src/java_raw_api.c,
 +      src/debug.c,
 +      src/sparc/v9.S,
 +      src/sparc/ffitarget.h,
 +      src/sparc/ffi.c,
 +      src/sparc/v8.S,
 +      src/mips/ffitarget.h,
 +      src/mips/n32.S,
 +      src/mips/o32.S,
 +      src/mips/ffi.c,
 +      src/prep_cif.c,
 +      src/sh/ffitarget.h,
 +      src/sh/ffi.c,
 +      src/sh/sysv.S: Update license text.
 +
 +2009-05-22  Dave Korn  <dave.korn.cygwin@gmail.com>
 +
 +      * src/x86/win32.S (_ffi_closure_STDCALL):  New function.
 +      (.eh_frame):  Add FDE for it.
 +
 +2009-05-22  Dave Korn  <dave.korn.cygwin@gmail.com>
 +
 +      * configure.ac:  Also check if assembler supports pc-relative
 +      relocs on X86_WIN32 targets.
 +      * configure:  Regenerate.
 +      * src/x86/win32.S (ffi_prep_args):  Declare extern, not global.
 +      (_ffi_call_SYSV):  Add missing function type symbol .def and
 +      add EH markup labels.
 +      (_ffi_call_STDCALL):  Likewise.
 +      (_ffi_closure_SYSV):  Likewise.
 +      (_ffi_closure_raw_SYSV):  Likewise.
 +      (.eh_frame):  Add hand-crafted EH data.
 +
 +2009-04-09  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * testsuite/lib/libffi-dg.exp: Change copyright header to refer to
 +      version 3 of the GNU General Public License and to point readers
 +      at the COPYING3 file and the FSF's license web page.
 +      * testsuite/libffi.call/call.exp: Likewise.
 +      * testsuite/libffi.special/special.exp: Likewise.
 +
 +2009-03-01  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * configure: Regenerate.
 +
 +2008-12-18  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      PR libffi/26048
 +      * configure.ac (HAVE_AS_X86_PCREL): New test.
 +      * configure: Regenerate.
 +      * fficonfig.h.in: Regenerate.
 +      * src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate
 +      RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET,
 +      RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler.
 +      (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
 +      * src/x86/unix64.S (.Lstore_table): Move to .text section.
 +      (.Lload_table): Likewise.
 +      (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
 +
 +2008-12-18  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * configure: Regenerate.
 +
 +2008-11-21  Eric Botcazou  <ebotcazou@adacore.com>
 +
 +      * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for
 +      signed/unsigned int8/16 return values.
 +      * src/sparc/v8.S (ffi_call_v8): Likewise.
 +      (ffi_closure_v8): Likewise.
 +
 +2008-09-26  Peter O'Gorman  <pogma@thewrittenword.com>
 +          Steve Ellcey  <sje@cup.hp.com>
 +
 +      * configure: Regenerate for new libtool.
 +      * Makefile.in: Ditto.
 +      * include/Makefile.in: Ditto.
 +      * aclocal.m4: Ditto.
 +
 +2008-08-25  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
 +      FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
 +      Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
 +      Adjust copyright notice.
 +      * src/powerpc/ffi.c: Add two new flags to indicate if we have one
 +      register or two register to use for FFI_SYSV structs.
 +      (ffi_prep_cif_machdep): Pass the right register flag introduced above.
 +      (ffi_closure_helper_SYSV): Fix the return type for
 +      FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
 +      Adjust copyright notice.
 +
 +2008-07-16  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
 +      int.
 +
 +2008-06-17  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * configure: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * testsuite/Makefile.in: Regenerate.
 +
 +2008-06-07  Joseph Myers  <joseph@codesourcery.com>
 +
 +      * configure.ac (parisc*-*-linux*, powerpc-*-sysv*,
 +      powerpc-*-beos*): Remove.
 +      * configure: Regenerate.
 +
 +2008-05-09  Julian Brown  <julian@codesourcery.com>
 +
 +      * Makefile.am (LTLDFLAGS): New.
 +      (libffi_la_LDFLAGS): Use above.
 +      * Makefile.in: Regenerate.
 +
 +2008-04-18  Paolo Bonzini  <bonzini@gnu.org>
 +
 +      PR bootstrap/35457
 +      * aclocal.m4: Regenerate.
 +      * configure: Regenerate.
 +
 +2008-03-26  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/sysv.S: Add .note.GNU-stack on Linux.
 +      * src/sh64/sysv.S: Likewise.
 +
 +2008-03-26  Daniel Jacobowitz  <dan@debian.org>
 +
 +      * src/arm/sysv.S: Fix ARM comment marker.
 +
 +2008-03-26  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/alpha/osf.S: Add .note.GNU-stack on Linux.
 +      * src/s390/sysv.S: Likewise.
 +      * src/powerpc/ppc_closure.S: Likewise.
 +      * src/powerpc/sysv.S: Likewise.
 +      * src/x86/unix64.S: Likewise.
 +      * src/x86/sysv.S: Likewise.
 +      * src/sparc/v8.S: Likewise.
 +      * src/sparc/v9.S: Likewise.
 +      * src/m68k/sysv.S: Likewise.
 +      * src/arm/sysv.S: Likewise.
 +
 +2008-03-16  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 +
 +      * aclocal.m4: Regenerate.
 +      * configure: Likewise.
 +      * Makefile.in: Likewise.
 +      * include/Makefile.in: Likewise.
 +      * testsuite/Makefile.in: Likewise.
 +
 +2008-02-12  Bjoern Koenig  <bkoenig@alpha-tierchen.de>
 +          Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * configure.ac: Add amd64-*-freebsd* target.
 +      * configure: Regenerate.
 +
 +2008-01-30  H.J. Lu  <hongjiu.lu@intel.com>
 +
 +      PR libffi/34612
 +      * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
 +      returning struct.
 +
 +      * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
 +      tests.
 +
 +2008-01-24  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * configure: Regenerate.
 +
 +2008-01-06  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko.
 +
 +2008-01-05  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      PR testsuite/32843
 +      * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for
 +      signed/unsigned int8/16 for X86_DARWIN.
 +      Updated copyright info.
 +      Handle one and two byte structs with special cif->flags.
 +      * src/x86/ffitarget.h: Add special types for one and two byte structs.
 +      Updated copyright info.
 +      * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like
 +      sysv.S
 +      Remove code to pop args from the stack after call.
 +      Special-case signed/unsigned for int8/16, one and two byte structs.
 +      (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
 +      FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
 +      FFI_TYPE_SINT32.
 +      Updated copyright info.
 +
 +2007-12-08  David Daney  <ddaney@avtrex.com>
 +
 +      * src/mips/n32.S (ffi_call_N32):  Replace dadd with ADDU, dsub with
 +      SUBU, add with ADDU and use smaller code sequences.
 +
 +2007-12-07  David Daney  <ddaney@avtrex.com>
 +
 +      * src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return
 +      type.
 +
 +2007-12-06  David Daney  <ddaney@avtrex.com>
 +
 +      * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already
 +      defined.
 +      (ffi_java_raw): New typedef.
 +      (ffi_java_raw_call, ffi_java_ptrarray_to_raw,
 +      ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to
 +      ffi_java_raw.
 +      (ffi_java_raw_closure) : Same.
 +      (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change
 +      parameter types.
 +      * src/java_raw_api.c (ffi_java_raw_size):  Replace FFI_SIZEOF_ARG with
 +      FFI_SIZEOF_JAVA_RAW.
 +      (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw.
 +      Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use
 +      sizeof(ffi_java_raw) for alignment calculations.
 +      (ffi_java_ptrarray_to_raw): Same.
 +      (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER
 +      if FFI_SIZEOF_JAVA_RAW == 4.
 +      (ffi_java_raw_to_rvalue): Same.
 +      (ffi_java_raw_call): Change type of raw to ffi_java_raw.
 +      (ffi_java_translate_args): Same.
 +      (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change
 +      parameter types.
 +      * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI.
 +
 +2007-12-06  David Daney  <ddaney@avtrex.com>
 +
 +      * src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on
 +      pointer values.
 +
 +2007-12-01  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      PR libffi/31937
 +      * src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT.
 +      Add local FFI_TYPE_UINT128 to handle soft-float long-double-128.
 +      * src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and
 +      set the NUM_FPR_ARG_REGISTERS according to.
 +      Add support for potential soft-float support under hard-float
 +      architecture.
 +      (ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of
 +      FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according
 +      to the FFI_LINUX_SOFT_FLOAT ABI.
 +      (ffi_prep_cif_machdep): Likewise.
 +      (ffi_closure_helper_SYSV): Likewise.
 +      * src/powerpc/ppc_closure.S: Make sure not to store float/double
 +      on archs where __NO_FPRS__ is true.
 +      Add FFI_TYPE_UINT128 support.
 +      * src/powerpc/sysv.S: Add support for soft-float long-double-128.
 +      Adjust copyright notice.
 +
 +2007-11-25  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * src/closures.c: Move defintion of MAYBE_UNUSED from here to ...
 +      * include/ffi_common.h: ... here.
 +      Update copyright.
 +
 +2007-11-17  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * src/powerpc/sysv.S: Load correct cr to compare if we have long double.
 +      * src/powerpc/linux64.S: Likewise.
 +      * src/powerpc/ffi.c: Add a comment to show which part goes into cr6.
 +      * testsuite/libffi.call/return_ldl.c: New test.
 +
 +2007-09-04    <aph@redhat.com>
 +
 +      * src/arm/sysv.S (UNWIND): New.
 +      (Whole file): Conditionally compile unwinder directives.
 +      * src/arm/sysv.S: Add unwinder directives.
 +
 +      * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes.
 +      Only treat r0 as a struct address if we're actually returning a
 +      struct by address.
 +      Only copy the bytes that are actually within a struct.
 +      (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes
 +      is returned in r0, not passed by address.
 +      (ffi_call): Allocate a word-sized temporary for the case where
 +      a composite is returned in r0.
 +      (ffi_prep_incoming_args_SYSV): Align as necessary.
 +
 +2007-08-05  Steven Newbury  <s_j_newbury@yahoo.co.uk>
 +
 +      * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of
 +      directly using the sys_cacheflush syscall.
 +
 +2007-07-27  Andrew Haley  <aph@redhat.com>
 +
 +      * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float.
 +
 +2007-09-03  Maciej W. Rozycki  <macro@linux-mips.org>
 +
 +      * Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS.
 +      * configure.ac: Likewise.
 +      * Makefile.in: Regenerate.
 +      * include/Makefile.in: Likewise.
 +      * testsuite/Makefile.in: Likewise.
 +      * configure: Likewise.
 +
 +2007-08-24  David Daney  <ddaney@avtrex.com>
 +
 +      * testsuite/libffi.call/return_sl.c: New test.
 +
 +2007-08-10  David Daney  <ddaney@avtrex.com>
 +
 +      * testsuite/libffi.call/cls_multi_ushort.c,
 +      testsuite/libffi.call/cls_align_uint16.c,
 +      testsuite/libffi.call/nested_struct1.c,
 +      testsuite/libffi.call/nested_struct3.c,
 +      testsuite/libffi.call/cls_7_1_byte.c,
 +      testsuite/libffi.call/nested_struct5.c,
 +      testsuite/libffi.call/cls_double.c,
 +      testsuite/libffi.call/nested_struct7.c,
 +      testsuite/libffi.call/cls_sint.c,
 +      testsuite/libffi.call/nested_struct9.c,
 +      testsuite/libffi.call/cls_20byte1.c,
 +      testsuite/libffi.call/cls_multi_sshortchar.c,
 +      testsuite/libffi.call/cls_align_sint64.c,
 +      testsuite/libffi.call/cls_3byte2.c,
 +      testsuite/libffi.call/cls_multi_schar.c,
 +      testsuite/libffi.call/cls_multi_uchar.c,
 +      testsuite/libffi.call/cls_19byte.c,
 +      testsuite/libffi.call/cls_9byte1.c,
 +      testsuite/libffi.call/cls_align_float.c,
 +      testsuite/libffi.call/closure_fn1.c,
 +      testsuite/libffi.call/problem1.c,
 +      testsuite/libffi.call/closure_fn3.c,
 +      testsuite/libffi.call/cls_sshort.c,
 +      testsuite/libffi.call/closure_fn5.c,
 +      testsuite/libffi.call/cls_align_double.c,
 +      testsuite/libffi.call/nested_struct.c,
 +      testsuite/libffi.call/cls_2byte.c,
 +      testsuite/libffi.call/nested_struct10.c,
 +      testsuite/libffi.call/cls_4byte.c,
 +      testsuite/libffi.call/cls_6byte.c,
 +      testsuite/libffi.call/cls_8byte.c,
 +      testsuite/libffi.call/cls_multi_sshort.c,
 +      testsuite/libffi.call/cls_align_sint16.c,
 +      testsuite/libffi.call/cls_align_uint32.c,
 +      testsuite/libffi.call/cls_20byte.c,
 +      testsuite/libffi.call/cls_float.c,
 +      testsuite/libffi.call/nested_struct2.c,
 +      testsuite/libffi.call/cls_5_1_byte.c,
 +      testsuite/libffi.call/nested_struct4.c,
 +      testsuite/libffi.call/cls_24byte.c,
 +      testsuite/libffi.call/nested_struct6.c,
 +      testsuite/libffi.call/cls_64byte.c,
 +      testsuite/libffi.call/nested_struct8.c,
 +      testsuite/libffi.call/cls_uint.c,
 +      testsuite/libffi.call/cls_multi_ushortchar.c,
 +      testsuite/libffi.call/cls_schar.c,
 +      testsuite/libffi.call/cls_uchar.c,
 +      testsuite/libffi.call/cls_align_uint64.c,
 +      testsuite/libffi.call/cls_ulonglong.c,
 +      testsuite/libffi.call/cls_align_longdouble.c,
 +      testsuite/libffi.call/cls_1_1byte.c,
 +      testsuite/libffi.call/cls_12byte.c,
 +      testsuite/libffi.call/cls_3_1byte.c,
 +      testsuite/libffi.call/cls_3byte1.c,
 +      testsuite/libffi.call/cls_4_1byte.c,
 +      testsuite/libffi.call/cls_6_1_byte.c,
 +      testsuite/libffi.call/cls_16byte.c,
 +      testsuite/libffi.call/cls_18byte.c,
 +      testsuite/libffi.call/closure_fn0.c,
 +      testsuite/libffi.call/cls_9byte2.c,
 +      testsuite/libffi.call/closure_fn2.c,
 +      testsuite/libffi.call/closure_fn4.c,
 +      testsuite/libffi.call/cls_ushort.c,
 +      testsuite/libffi.call/closure_fn6.c,
 +      testsuite/libffi.call/cls_5byte.c,
 +      testsuite/libffi.call/cls_align_pointer.c,
 +      testsuite/libffi.call/cls_7byte.c,
 +      testsuite/libffi.call/cls_align_sint32.c,
 +      testsuite/libffi.special/unwindtest_ffi_call.cc,
 +      testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*.
 +
 +2007-08-10  David Daney  <ddaney@avtrex.com>
 +
 +      PR libffi/28313
 +      * configure.ac: Don't treat mips64 as a special case.
 +      * Makefile.am (nodist_libffi_la_SOURCES): Add n32.S.
 +      * configure: Regenerate
 +      * Makefile.in: Ditto.
 +      * fficonfig.h.in: Ditto.
 +      * src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent.
 +      (LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros.
 +      (FFI_DEFAULT_ABI): Set for n64 case.
 +      (FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases.
 +      * src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE.
 +      (ffi_closure_N32): New function.
 +      (.eh_frame): New section
 +      * src/mips/o32.S: Clean up comments.
 +      (ffi_closure_O32): Pass ffi_closure parameter in $12.
 +      * src/mips/ffi.c: Use FFI_MIPS_N32 instead of
 +      _MIPS_SIM == _ABIN32 throughout.
 +      (FFI_MIPS_STOP_HERE): New, use in place of
 +      ffi_stop_here.
 +      (ffi_prep_args): Use unsigned long to hold pointer values.  Rewrite
 +      to support n32/n64 ABIs.
 +      (calc_n32_struct_flags): Rewrite.
 +      (calc_n32_return_struct_flags): Remove unused variable.  Reverse
 +      position of flag bits.
 +      (ffi_prep_cif_machdep): Rewrite n32 portion.
 +      (ffi_call): Enable for n64.  Add special handling for small structure
 +      return values.
 +      (ffi_prep_closure_loc): Add n32 and n64 support.
 +      (ffi_closure_mips_inner_O32): Add cast to silence warning.
 +      (copy_struct_N32, ffi_closure_mips_inner_N32): New functions.
 +
 +2007-08-08  David Daney  <ddaney@avtrex.com>
 +
 +      * testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition.
 +      * testsuite/libffi.call/cls_align_uint16.c (main): Use correct type
 +      specifiers.
 +      * testsuite/libffi.call/nested_struct1.c (main): Ditto.
 +      * testsuite/libffi.call/cls_sint.c (main): Ditto.
 +      * testsuite/libffi.call/nested_struct9.c (main): Ditto.
 +      * testsuite/libffi.call/cls_20byte1.c (main): Ditto.
 +      * testsuite/libffi.call/cls_9byte1.c (main): Ditto.
 +      * testsuite/libffi.call/closure_fn1.c (main): Ditto.
 +      * testsuite/libffi.call/closure_fn3.c (main): Ditto.
 +      * testsuite/libffi.call/return_dbl2.c (main): Ditto.
 +      * testsuite/libffi.call/cls_sshort.c (main): Ditto.
 +      * testsuite/libffi.call/return_fl3.c (main): Ditto.
 +      * testsuite/libffi.call/closure_fn5.c (main): Ditto.
 +      * testsuite/libffi.call/nested_struct.c (main): Ditto.
 +      * testsuite/libffi.call/nested_struct10.c (main): Ditto.
 +      * testsuite/libffi.call/return_ll1.c (main): Ditto.
 +      * testsuite/libffi.call/cls_8byte.c (main): Ditto.
 +      * testsuite/libffi.call/cls_align_uint32.c (main): Ditto.
 +      * testsuite/libffi.call/cls_align_sint16.c (main): Ditto.
 +      * testsuite/libffi.call/cls_20byte.c (main): Ditto.
 +      * testsuite/libffi.call/nested_struct2.c (main): Ditto.
 +      * testsuite/libffi.call/cls_24byte.c (main): Ditto.
 +      * testsuite/libffi.call/nested_struct6.c (main): Ditto.
 +      * testsuite/libffi.call/cls_uint.c (main): Ditto.
 +      * testsuite/libffi.call/cls_12byte.c (main): Ditto.
 +      * testsuite/libffi.call/cls_16byte.c (main): Ditto.
 +      * testsuite/libffi.call/closure_fn0.c (main): Ditto.
 +      * testsuite/libffi.call/cls_9byte2.c (main): Ditto.
 +      * testsuite/libffi.call/closure_fn2.c (main): Ditto.
 +      * testsuite/libffi.call/return_dbl1.c (main): Ditto.
 +      * testsuite/libffi.call/closure_fn4.c (main): Ditto.
 +      * testsuite/libffi.call/closure_fn6.c (main): Ditto.
 +      * testsuite/libffi.call/cls_align_sint32.c (main): Ditto.
 +
 +2007-08-07  Andrew Haley  <aph@redhat.com>
 +
 +      * src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous
 +      checkin.
 +
 +2007-08-06  Andrew Haley  <aph@redhat.com>
 +
 +      PR testsuite/32843
 +      * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
 +      FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
 +      FFI_TYPE_SINT32.
 +
 +2007-08-02  David Daney  <ddaney@avtrex.com>
 +
 +      * testsuite/libffi.call/return_ul.c (main): Define return type as
 +      ffi_arg.  Use proper printf conversion specifier.
 +
 +2007-07-30  Andrew Haley  <aph@redhat.com>
 +
 +      PR testsuite/32843
 +      * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for
 +      signed/unsigned int8/16.
 +      * src/x86/sysv.S (ffi_call_SYSV): Rewrite to:
 +      Use a jump table.
 +      Remove code to pop args from the stack after call.
 +      Special-case signed/unsigned int8/16.
 +      * testsuite/libffi.call/return_sc.c (main): Revert.
 +
 +2007-07-26  Richard Guenther  <rguenther@suse.de>
 +
 +      PR testsuite/32843
 +      * testsuite/libffi.call/return_sc.c (main): Verify call
 +      result as signed char, not ffi_arg.
 +
 +2007-07-16  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64.
 +      * configure: Regenerate.
 +
 +2007-07-11  David Daney  <ddaney@avtrex.com>
 +
 +      * src/mips/ffi.c: Don't include sys/cachectl.h.
 +      (ffi_prep_closure_loc): Use __builtin___clear_cache() instead of
 +      cacheflush().
 +
 +2007-05-18  Aurelien Jarno  <aurelien@aurel32.net>
 +
 +      * src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted
 +      from (ffi_prep_closure): ... this.
 +      (FFI_INIT_TRAMPOLINE): Adjust.
 +
 +2005-12-31  Phil Blundell  <pb@reciva.com>
 +
 +      * src/arm/ffi.c (ffi_prep_incoming_args_SYSV,
 +      ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support.
 +      * src/arm/sysv.S(ffi_closure_SYSV): Likewise.
 +      * src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
 +      (FFI_CLOSURES): Enable closure support.
 +
 +2007-07-03  Andrew Haley  <aph@hedges.billgatliff.com>
 +
 +      * testsuite/libffi.call/cls_multi_ushort.c,
 +      testsuite/libffi.call/cls_align_uint16.c,
 +      testsuite/libffi.call/nested_struct1.c,
 +      testsuite/libffi.call/nested_struct3.c,
 +      testsuite/libffi.call/cls_7_1_byte.c,
 +      testsuite/libffi.call/cls_double.c,
 +      testsuite/libffi.call/nested_struct5.c,
 +      testsuite/libffi.call/nested_struct7.c,
 +      testsuite/libffi.call/cls_sint.c,
 +      testsuite/libffi.call/nested_struct9.c,
 +      testsuite/libffi.call/cls_20byte1.c,
 +      testsuite/libffi.call/cls_multi_sshortchar.c,
 +      testsuite/libffi.call/cls_align_sint64.c,
 +      testsuite/libffi.call/cls_3byte2.c,
 +      testsuite/libffi.call/cls_multi_schar.c,
 +      testsuite/libffi.call/cls_multi_uchar.c,
 +      testsuite/libffi.call/cls_19byte.c,
 +      testsuite/libffi.call/cls_9byte1.c,
 +      testsuite/libffi.call/cls_align_float.c,
 +      testsuite/libffi.call/closure_fn1.c,
 +      testsuite/libffi.call/problem1.c,
 +      testsuite/libffi.call/closure_fn3.c,
 +      testsuite/libffi.call/cls_sshort.c,
 +      testsuite/libffi.call/closure_fn5.c,
 +      testsuite/libffi.call/cls_align_double.c,
 +      testsuite/libffi.call/cls_2byte.c,
 +      testsuite/libffi.call/nested_struct.c,
 +      testsuite/libffi.call/nested_struct10.c,
 +      testsuite/libffi.call/cls_4byte.c,
 +      testsuite/libffi.call/cls_6byte.c,
 +      testsuite/libffi.call/cls_8byte.c,
 +      testsuite/libffi.call/cls_multi_sshort.c,
 +      testsuite/libffi.call/cls_align_uint32.c,
 +      testsuite/libffi.call/cls_align_sint16.c,
 +      testsuite/libffi.call/cls_float.c,
 +      testsuite/libffi.call/cls_20byte.c,
 +      testsuite/libffi.call/cls_5_1_byte.c,
 +      testsuite/libffi.call/nested_struct2.c,
 +      testsuite/libffi.call/cls_24byte.c,
 +      testsuite/libffi.call/nested_struct4.c,
 +      testsuite/libffi.call/nested_struct6.c,
 +      testsuite/libffi.call/cls_64byte.c,
 +      testsuite/libffi.call/nested_struct8.c,
 +      testsuite/libffi.call/cls_uint.c,
 +      testsuite/libffi.call/cls_multi_ushortchar.c,
 +      testsuite/libffi.call/cls_schar.c,
 +      testsuite/libffi.call/cls_uchar.c,
 +      testsuite/libffi.call/cls_align_uint64.c,
 +      testsuite/libffi.call/cls_ulonglong.c,
 +      testsuite/libffi.call/cls_align_longdouble.c,
 +      testsuite/libffi.call/cls_1_1byte.c,
 +      testsuite/libffi.call/cls_12byte.c,
 +      testsuite/libffi.call/cls_3_1byte.c,
 +      testsuite/libffi.call/cls_3byte1.c,
 +      testsuite/libffi.call/cls_4_1byte.c,
 +      testsuite/libffi.call/cls_6_1_byte.c,
 +      testsuite/libffi.call/cls_16byte.c,
 +      testsuite/libffi.call/cls_18byte.c,
 +      testsuite/libffi.call/closure_fn0.c,
 +      testsuite/libffi.call/cls_9byte2.c,
 +      testsuite/libffi.call/closure_fn2.c,
 +      testsuite/libffi.call/closure_fn4.c,
 +      testsuite/libffi.call/cls_ushort.c,
 +      testsuite/libffi.call/closure_fn6.c,
 +      testsuite/libffi.call/cls_5byte.c,
 +      testsuite/libffi.call/cls_align_pointer.c,
 +      testsuite/libffi.call/cls_7byte.c,
 +      testsuite/libffi.call/cls_align_sint32.c,
 +      testsuite/libffi.special/unwindtest_ffi_call.cc,
 +      testsuite/libffi.special/unwindtest.cc: Enable for ARM.
 +
 +2007-07-05  H.J. Lu  <hongjiu.lu@intel.com>
 +
 +      * aclocal.m4: Regenerated.
 +
 +2007-06-02  Paolo Bonzini  <bonzini@gnu.org>
 +
 +      * configure: Regenerate.
 +
 +2007-05-23  Steve Ellcey  <sje@cup.hp.com>
 +
 +      * Makefile.in: Regenerate.
 +      * configure: Regenerate.
 +      * aclocal.m4: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * testsuite/Makefile.in: Regenerate.
 +
 +2007-05-10  Roman Zippel <zippel@linux-m68k.org>
 +
 +      * src/m68k/ffi.c (ffi_prep_incoming_args_SYSV,
 +      ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support.
 +      * src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise.
 +      * src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
 +      (FFI_CLOSURES): Enable closure support.
 +
 +2007-05-10  Roman Zippel <zippel@linux-m68k.org>
 +
 +      * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test.
 +      * configure: Regenerate.
 +      * fficonfig.h.in: Regenerate.
 +      * src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC,
 +      CFI_OFFSET,CFI_DEF_CFA): New macros.
 +      (ffi_call_SYSV): Add callframe annotation.
 +
 +2007-05-10  Roman Zippel <zippel@linux-m68k.org>
 +
 +      * src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix
 +      numerous test suite failures.
 +      * src/m68k/sysv.S (ffi_call_SYSV): Likewise.
 +
 +2007-04-11  Paolo Bonzini  <bonzini@gnu.org>
 +
 +      * Makefile.am (EXTRA_DIST): Bring up to date.
 +      * Makefile.in: Regenerate.
 +      * src/frv/eabi.S: Remove RCS keyword.
 +
 +2007-04-06  Richard Henderson  <rth@redhat.com>
 +
 +      * configure.ac: Tidy target case.
 +      (HAVE_LONG_DOUBLE): Allow the target to override.
 +      * configure: Regenerate.
 +      * include/ffi.h.in: Don't define ffi_type_foo if
 +      LIBFFI_HIDE_BASIC_TYPES is defined.
 +      (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define
 +      to ffi_type_double.
 +      * types.c (LIBFFI_HIDE_BASIC_TYPES): Define.
 +      (FFI_TYPEDEF, ffi_type_void): Mark the data const.
 +      (ffi_type_longdouble): Special case for Alpha.  Don't define
 +      if long double == double.
 +
 +      * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value.
 +      (ffi_prep_cif_machdep): Handle it as the 128-bit type.
 +      (ffi_call, ffi_closure_osf_inner): Likewise.
 +      (ffi_closure_osf_inner): Likewise.  Mark hidden.
 +      (ffi_call_osf, ffi_closure_osf): Mark hidden.
 +      * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition.
 +      * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
 +      (load_table): Handle 128-bit long double.
 +
 +      * testsuite/libffi.call/float4.c: Add -mieee for alpha.
 +
 +2007-04-06  Tom Tromey  <tromey@redhat.com>
 +
 +      PR libffi/31491:
 +      * README: Fixed bug in example.
 +
 +2007-04-03  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/closures.c: Include sys/statfs.h.
 +      (_GNU_SOURCE): Define on Linux.
 +      (FFI_MMAP_EXEC_SELINUX): Define.
 +      (selinux_enabled): New variable.
 +      (selinux_enabled_check): New function.
 +      (is_selinux_enabled): Define.
 +      (dlmmap): Use it.
 +
 +2007-03-24  Uros Bizjak  <ubizjak@gmail.com>
 +
 +      * testsuite/libffi.call/return_fl2.c (return_fl): Mark as static.
 +      Use 'volatile float sum' to create sum of floats to avoid false
 +      negative due to excess precision on ix86 targets.
 +      (main): Ditto.
 +
 +2007-03-08  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * src/powerpc/ffi.c (flush_icache): Fix left-over from previous
 +      patch.
 +      (ffi_prep_closure_loc): Remove unneeded casts.  Add needed ones.
 +
 +2007-03-07  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New.
 +      (ffi_prep_closure_loc): New.
 +      (ffi_prep_raw_closure_loc): New.
 +      (ffi_prep_java_raw_closure_loc): New.
 +      * src/closures.c: New file.
 +      * src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment):
 +      Replace sflags with exec_offset.
 +      [FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset,
 +      sub_segment_exec_offset): New macros.
 +      (get_segment_flags, set_segment_flags, check_segment_merge): New
 +      macros.
 +      (is_mmapped_segment, is_extern_segment): Use get_segment_flags.
 +      (add_segment, sys_alloc, create_mspace, create_mspace_with_base,
 +      destroy_mspace): Use new macros.
 +      (sys_alloc): Silence warning.
 +      * Makefile.am (libffi_la_SOURCES): Add src/closures.c.
 +      * Makefile.in: Rebuilt.
 +      * src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in
 +      terms of ffi_prep_closure_loc.
 +      * src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted
 +      from...
 +      (ffi_prep_raw_closure): ... this.  Re-implement in terms of the
 +      renamed version.
 +      * src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and
 +      adjusted from...
 +      (ffi_prep_java_raw_closure): ... this.  Re-implement in terms of
 +      the renamed version.
 +      * src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from
 +      (ffi_prep_closure): ... this.
 +      * src/pa/ffi.c: Likewise.
 +      * src/cris/ffi.c: Likewise.  Adjust.
 +      * src/frv/ffi.c: Likewise.
 +      * src/ia64/ffi.c: Likewise.
 +      * src/mips/ffi.c: Likewise.
 +      * src/powerpc/ffi_darwin.c: Likewise.
 +      * src/s390/ffi.c: Likewise.
 +      * src/sh/ffi.c: Likewise.
 +      * src/sh64/ffi.c: Likewise.
 +      * src/sparc/ffi.c: Likewise.
 +      * src/x86/ffi64.c: Likewise.
 +      * src/x86/ffi.c: Likewise.
 +      (FFI_INIT_TRAMPOLINE): Adjust.
 +      (ffi_prep_raw_closure_loc): Renamed and adjusted from...
 +      (ffi_prep_raw_closure): ... this.
 +      * src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from
 +      (ffi_prep_closure): ... this.
 +      (flush_icache): Adjust.
 +
 +2007-03-07  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * src/dlmalloc.c: New file, imported version 2.8.3 of Doug
 +      Lea's malloc.
 +
 +2007-03-01  Brooks Moses  <brooks.moses@codesourcery.com>
 +
 +      * Makefile.am: Add dummy install-pdf target.
 +      * Makefile.in: Regenerate
 +
 +2007-02-13  Andreas Krebbel  <krebbel1@de.ibm.com>
 +
 +      * src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep,
 +      ffi_closure_helper_SYSV): Add long double handling.
 +
 +2007-02-02  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2
 +      immediately after bctrl instruction.
 +
 +2007-01-18  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * Makefile.am (all-recursive, install-recursive,
 +      mostlyclean-recursive, clean-recursive, distclean-recursive,
 +      maintainer-clean-recursive): Add missing targets.
 +      * Makefile.in: Rebuilt.
 +
 +2006-12-14  Andreas Tobler  <a.tobler@schweiz.org>
 +
 +      * configure.ac: Add TARGET for x86_64-*-darwin*.
 +      * Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources
 +      for X86_DARWIN.
 +      * src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*.
 +      * src/x86/darwin64.S: New file for x86_64-*-darwin* support.
 +      * configure: Regenerate.
 +      * Makefile.in: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * testsuite/Makefile.in: Regenerate.
 +      * testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for
 +      ffi_call only.
 +
 +2006-12-13  Andreas Tobler <a.tobler@schweiz.org>
 +
 +      * aclocal.m4: Regenerate with aclocal -I .. as written in the
 +      Makefile.am.
 +
 +2006-10-31  Geoffrey Keating  <geoffk@apple.com>
 +
 +      * src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New.
 +      (ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for
 +      Darwin.
 +      * testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL.
 +      * testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL.
 +
 +2006-10-10  Paolo Bonzini  <bonzini@gnu.org>
 +          Sandro Tolaini  <tolaini@libero.it>
 +
 +      * configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and
 +      conditional.
 +      * configure: Regenerated.
 +      * Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case.
 +      (EXTRA_DIST): Add src/x86/darwin.S.
 +      * Makefile.in: Regenerated.
 +      * include/Makefile.in: Regenerated.
 +      * testsuite/Makefile.in: Regenerated.
 +
 +      * src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like
 +      X86_WIN32, and additionally align stack to 16 bytes.
 +      * src/x86/darwin.S: New, based on sysv.S.
 +      * src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs.
 +
 +2006-09-12  David Daney  <ddaney@avtrex.com>
 +
 +      PR libffi/23935
 +      * include/Makefile.am: Install both ffi.h and ffitarget.h in
 +      $(libdir)/gcc/$(target_alias)/$(gcc_version)/include.
 +      * aclocal.m4: Regenerated for automake 1.9.6.
 +      * Makefile.in: Regenerated.
 +      * include/Makefile.in: Regenerated.
 +      * testsuite/Makefile.in: Regenerated.
 +
 +2006-08-17  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * include/ffi_common.h (struct): Revert accidental commit.
 +
 +2006-08-15  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * include/ffi_common.h: Remove lint directives.
 +      * include/ffi.h.in: Likewise.
 +
 +2006-07-25  Torsten Schoenfeld  <kaffeetisch@gmx.de>
 +
 +      * include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly
 +      for 32-bit architectures.
 +      * testsuite/libffi.call/return_ul.c: New test case.
 +
 +2006-07-19  David Daney  <ddaney@avtrex.com>
 +
 +      * testsuite/libffi.call/closure_fn6.c: Remove xfail for mips,
 +      xfail remains for mips64.
 +
 +2006-05-23  Carlos O'Donell  <carlos@codesourcery.com>
 +
 +      * Makefile.am: Add install-html target. Add install-html to .PHONY
 +      * Makefile.in: Regenerate.
 +      * aclocal.m4: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * testsuite/Makefile.in: Regenerate.
 +
 +2006-05-18  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 +
 +      * pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from
 +      stack slot.
 +
 +2006-04-22  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * README: Remove notice about 'Crazy Comments'.
 +      * src/debug.c: Remove lint directives. Cleanup white spaces.
 +      * src/java_raw_api.c: Likewise.
 +      * src/prep_cif.c: Likewise.
 +      * src/raw_api.c: Likewise.
 +      * src/ffitest.c: Delete. No longer needed, all test cases migrated
 +      to the testsuite.
 +      * src/arm/ffi.c: Remove lint directives.
 +      * src/m32r/ffi.c: Likewise.
 +      * src/pa/ffi.c: Likewise.
 +      * src/powerpc/ffi.c: Likewise.
 +      * src/powerpc/ffi_darwin.c: Likewise.
 +      * src/sh/ffi.c: Likewise.
 +      * src/sh64/ffi.c: Likewise.
 +      * src/x86/ffi.c: Likewise.
 +      * testsuite/libffi.call/float2.c: Likewise.
 +      * testsuite/libffi.call/promotion.c: Likewise.
 +      * testsuite/libffi.call/struct1.c: Likewise.
 +
 +2006-04-13  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/pa/hpux32.S: Correct unwind offset calculation for
 +      ffi_closure_pa32.
 +      * src/pa/linux.S: Likewise.
 +
 +2006-04-12  James E Wilson  <wilson@specifix.com>
 +
 +      PR libgcj/26483
 +      * src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros.
 +      (hfa_type_load): Call stf_spill.
 +      (hfa_type_store): Call ldf_fill.
 +      (ffi_call): Adjust calls to above routines.  Add local temps for
 +      macro result.
 +
 +2006-04-10  Matthias Klose  <doko@debian.org>
 +
 +      * testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib
 +      directory names containing underscores.
 +
 +2006-04-07  James E Wilson  <wilson@specifix.com>
 +
 +      * testsuite/libffi.call/float4.c: New testcase.
 +
 +2006-04-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 +          Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * Makefile.am: Add PA_HPUX port.
 +      * Makefile.in: Regenerate.
 +      * include/Makefile.in: Likewise.
 +      * testsuite/Makefile.in: Likewise.
 +      * configure.ac: Add PA_HPUX rules.
 +      * configure: Regenerate.
 +      * src/pa/ffitarget.h: Rename linux target to PA_LINUX.
 +      Add PA_HPUX and PA64_HPUX.
 +      Rename FFI_LINUX ABI to FFI_PA32 ABI.
 +      (FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets.
 +      (FFI_TYPE_SMALL_STRUCT2): Define.
 +      (FFI_TYPE_SMALL_STRUCT4): Likewise.
 +      (FFI_TYPE_SMALL_STRUCT8): Likewise.
 +      (FFI_TYPE_SMALL_STRUCT3): Redefine.
 +      (FFI_TYPE_SMALL_STRUCT5): Likewise.
 +      (FFI_TYPE_SMALL_STRUCT6): Likewise.
 +      (FFI_TYPE_SMALL_STRUCT7): Likewise.
 +      * src/pa/ffi.c (ROUND_DOWN): Delete.
 +      (fldw, fstw, fldd, fstd): Use '__asm__'.
 +      (ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2,
 +      FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8.
 +      (ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment.
 +      Simplify incrementing of stack slot variable. Change type of local
 +      'n' to unsigned int.
 +      (ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long
 +      double on PA_HPUX.
 +      (ffi_prep_cif_machdep): Likewise.
 +      (ffi_call): Likewise.
 +      (ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change
 +      return type to ffi_status. Simplify incrementing of stack slot
 +      variable. Only copy floating point argument registers when PA_LINUX
 +      is true. Reformat debug statement.
 +      Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and
 +      FFI_TYPE_SMALL_STRUCT8.
 +      (ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to
 +      declaration.
 +      (ffi_prep_closure): Make linux trampoline conditional on PA_LINUX.
 +      Add nops to cache flush.  Add trampoline for PA_HPUX.
 +      * src/pa/hpux32.S: New file.
 +      * src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename
 +      ffi_prep_args_LINUX to ffi_prep_args_pa32.
 +      Localize labels. Add support for 2, 4 and 8-byte small structs. Handle
 +      unaligned destinations in 3, 5, 6 and 7-byte small structs. Order
 +      argument type checks so that common argument types appear first.
 +      (ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename
 +      ffi_closure_inner_LINUX to ffi_closure_inner_pa32.
 +
 +2006-03-24  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX.  Default
 +      for 32-bit using IBM extended double format.  Fix FFI_LAST_ABI.
 +      * src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of
 +      FFI_TYPE_LONGDOUBLE.
 +      (ffi_prep_args64): Assert using IBM extended double.
 +      (ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type.
 +      Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args.
 +      (ffi_call): Handle FFI_LINUX.
 +      (ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs
 +      gpr3 return pointer as for struct return.  Handle FFI_LINUX
 +      FFI_TYPE_LONGDOUBLE return and args.  Don't increment "nf"
 +      unnecessarily.
 +      * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2
 +      for FFI_TYPE_LONGDOUBLE.  Move epilogue insns into case table.
 +      Don't use r6 as pointer to results, instead use sp offset.  Don't
 +      make a special call to load lr with case table address, instead
 +      use offset from previous call.
 +      * src/powerpc/sysv.S (ffi_call_SYSV): Save long double return.
 +      * src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double
 +      return.
 +
 +2006-03-15  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments
 +      passed with FP registers correctly.
 +      (ffi_closure_helper_SYSV): Likewise.
 +      * src/sh64/sysv.S: Likewise.
 +
 +2006-03-01  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif,
 +      args and userdata unused.
 +      (closure_test_fn1): Mark cif and userdata unused.
 +      (main): Remove unused res.
 +
 +2006-02-28  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for
 +      -O2, -O3, -Os and the warning flags -W -Wall.
 +      * testsuite/libffi.special/special.exp: Likewise.
 +      * testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark
 +      unused parameter unused for gcc or else do nothing.
 +      * testsuite/libffi.special/ffitestcxx.h: Likewise.
 +      * testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif
 +      and userdata unused.
 +      * testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise.
 +      * testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise.
 +      * testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast
 +      void* to avoid compiler warning.
 +      (main): Likewise.
 +      (cls_struct_align_gn): Mark cif and userdata unused.
 +      * testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn):
 +      Likewise.
 +      * testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise.
 +      * testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise.
 +      * testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and
 +      data unused.
 +      (main): Cast res_call to silence gcc.
 +      * testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and
 +      data unused.
 +      (main): Cast res_call to silence gcc.
 +      * testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif
 +      and data unused.
 +      (main): Cast res_call to silence gcc.
 +      * testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and
 +      data unused.
 +      (main): Cast res_call to silence gcc.
 +      * testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and
 +      data unused.
 +      (main): Cast res_call to silence gcc.
 +      * testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif
 +      and data unused.
 +      (main): Cast res_call to silence gcc.
 +      * testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and
 +      userdata unused.
 +      (cls_ret_schar_fn): Cast printf parameter to silence gcc.
 +      * testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and
 +      userdata unused.
 +      (cls_ret_sint_fn): Cast printf parameter to silence gcc.
 +      * testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and
 +      userdata unused.
 +      (cls_ret_sshort_fn): Cast printf parameter to silence gcc.
 +      * testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn):  Mark cif and
 +      userdata unused.
 +      (cls_ret_uchar_fn): Cast printf parameter to silence gcc.
 +      * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and
 +      userdata unused.
 +      (cls_ret_uint_fn): Cast printf parameter to silence gcc.
 +      * testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif
 +      and userdata unused.
 +      * testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and
 +      userdata unused.
 +      (cls_ret_ushort_fn): Cast printf parameter to silence gcc.
 +      * testsuite/libffi.call/float.c (floating): Remove unused parameter e.
 +      * testsuite/libffi.call/float1.c (main): Remove unused variable i.
 +      Cleanup white spaces.
 +      * testsuite/libffi.call/negint.c (checking): Remove unused variable i.
 +      * testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark
 +      cif and userdata unused.
 +      * testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn):
 +      Likewise.
 +      * testsuite/libffi.call/nested_struct10.c (B_gn): Likewise.
 +      * testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf
 +      formatters to silence gcc.
 +      (B_gn): Mark cif and userdata unused.
 +      * testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata
 +      unused.
 +      * testsuite/libffi.call/nested_struct4.c: Mention related PR.
 +      (B_gn): Mark cif and userdata unused.
 +      * testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata
 +      unused.
 +      * testsuite/libffi.call/nested_struct6.c: Mention related PR.
 +      (B_gn): Mark cif and userdata unused.
 +      * testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata
 +      unused.
 +      * testsuite/libffi.call/nested_struct8.c (B_gn): Likewise.
 +      * testsuite/libffi.call/nested_struct9.c (B_gn): Likewise.
 +      * testsuite/libffi.call/problem1.c (stub): Likewise.
 +      * testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence
 +      gcc.
 +      * testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned
 +      in the last commit for this test case in the test case itself.
 +      * testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as
 +      unused.
 +      * testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise.
 +      * testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise.
 +      * testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise.
 +      * testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise.
 +      * testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise.
 +      * testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise.
 +
 +2006-02-22  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/sysv.S: Fix register numbers in the FDE for
 +      ffi_closure_SYSV.
 +
 +2006-02-20  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/return_fl2.c (return_fl): Remove static
 +      declaration to avoid a false negative on ix86. See PR323.
 +
 +2006-02-18  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable
 +      and cast integer to void * if needed.  Update the pointer to
 +      the FP register saved area correctly.
 +
 +2006-02-17  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630
 +      is fixed.
 +      * testsuite/libffi.call/nested_struct4.c: Likewise.
 +
 +2006-02-16  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/return_dbl.c: New test case.
 +      * testsuite/libffi.call/return_dbl1.c: Likewise.
 +      * testsuite/libffi.call/return_dbl2.c: Likewise.
 +      * testsuite/libffi.call/return_fl.c: Likewise.
 +      * testsuite/libffi.call/return_fl1.c: Likewise.
 +      * testsuite/libffi.call/return_fl2.c: Likewise.
 +      * testsuite/libffi.call/return_fl3.c: Likewise.
 +      * testsuite/libffi.call/closure_fn6.c: Likewise.
 +
 +      * testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong
 +      definition.
 +      * testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition
 +      here to be used by other test cases too.
 +
 +      * testsuite/libffi.call/nested_struct10.c: New test case.
 +      * testsuite/libffi.call/nested_struct9.c: Likewise.
 +      * testsuite/libffi.call/nested_struct8.c: Likewise.
 +      * testsuite/libffi.call/nested_struct7.c: Likewise.
 +      * testsuite/libffi.call/nested_struct6.c: Likewise.
 +      * testsuite/libffi.call/nested_struct5.c: Likewise.
 +      * testsuite/libffi.call/nested_struct4.c: Likewise.
 +
 +2006-01-21  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * configure.ac: Enable libffi for sparc64-*-freebsd*.
 +      * configure: Rebuilt.
 +
 +2006-01-18  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3,
 +      instead do the shifting inline.
 +      * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5
 +      shift count unconditionally.  Simplify load sequences for 1, 2, 3, 4
 +      and 8 byte structs, for the remaining struct sizes don't call
 +      __lshrdi3, instead do the shifting inline.
 +
 +2005-12-07  Thiemo Seufer  <ths@networkno.de>
 +
 +      * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add
 +      missing parentheses.
 +      * src/mips/o32.S (ffi_call_O32): Code formatting. Define
 +      and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations.
 +      (ffi_closure_O32): Likewise, but with newly defined A3_OFF2,
 +      A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2,
 +      V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2,
 +      FA_0_0_OFF2.
 +      * src/mips/ffi.c (ffi_prep_args): Code formatting. Fix
 +      endianness bugs.
 +      (ffi_prep_closure): Improve trampoline instruction scheduling.
 +      (ffi_closure_mips_inner_O32): Fix endianness bugs.
 +
 +2005-12-03  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/powerpc/ffi.c: Formatting.
 +      (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
 +      (ffi_prep_args64): Likewise.
 +
 +2005-09-30  Geoffrey Keating  <geoffk@apple.com>
 +
 +      * testsuite/lib/libffi-dg.exp (libffi_target_compile): For
 +      darwin, use -shared-libgcc not -lgcc_s, and explain why.
 +
 +2005-09-26  Tom Tromey  <tromey@redhat.com>
 +
 +      * testsuite/libffi.call/float1.c (value_type): New typedef.
 +      (CANARY): New define.
 +      (main): Check for result buffer overflow.
 +      * src/powerpc/linux64.S: Handle linux64 long double returns.
 +      * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant.
 +      (ffi_prep_cif_machdep): Handle linux64 long double returns.
 +
 +2005-08-25  Alan Modra  <amodra@bigpond.net.au>
 +
 +      PR target/23404
 +      * src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack
 +      homed fp args.
 +      (ffi_status ffi_prep_cif_machdep): Correct stack sizing for same.
 +
 +2005-08-11  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test.
 +      (AH_BOTTOM): Add FFI_HIDDEN definition.
 +      * configure: Rebuilt.
 +      * fficonfig.h.in: Rebuilt.
 +      * src/powerpc/ffi.c (hidden): Remove.
 +      (ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64,
 +      ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden.
 +      * src/powerpc/linux64_closure.S (ffi_closure_LINUX64,
 +      .ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden.
 +      * src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove,
 +      add FFI_HIDDEN to its prototype.
 +      (ffi_closure_SYSV_inner): New.
 +      * src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
 +      * src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
 +
 +2005-08-10  Alfred M. Szmidt  <ams@gnu.org>
 +
 +      PR libffi/21819:
 +      * configure: Rebuilt.
 +      * configure.ac: Handle i*86-*-gnu*.
 +
 +2005-08-09  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use
 +      DW_CFA_offset_extended_sf rather than
 +      DW_CFA_GNU_negative_offset_extended.
 +      * src/powerpc/sysv.S (ffi_call_SYSV): Likewise.
 +
 +2005-07-22  SUGIOKA Toshinobu  <sugioka@itonet.co.jp>
 +
 +      * src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly
 +      on sh3.
 +      (ffi_closure_SYSV): Change the stack layout for sh3 struct argument.
 +      * src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is
 +      partially on register.
 +      (ffi_closure_helper_SYSV): Likewise.
 +      (ffi_prep_cif_machdep): Don't set too many cif->flags.
 +
 +2005-07-20  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/ffi.c (ffi_call): Handle small structures correctly.
 +      Remove empty line.
 +      * src/sh64/ffi.c (simple_type): Remove.
 +      (return_type): Handle small structures correctly.
 +      (ffi_prep_args): Likewise.
 +      (ffi_call): Likewise.
 +      (ffi_closure_helper_SYSV): Likewise.
 +      * src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return.
 +      Emit position independent code if PIC and remove wrong datalabel
 +      prefixes from EH data.
 +
 +2005-07-19  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.
 +      * Makefile.in: Regenerate.
 +      * include/Makefile.in: Likewise.
 +      * testsuite/Makefile.in: Likewise.
 +      * configure.ac: Add POWERPC_FREEBSD rules.
 +      * configure: Regenerate.
 +      * src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules.
 +      (FFI_SYSV_TYPE_SMALL_STRUCT): Define.
 +      * src/powerpc/ffi.c: Add flags to handle small structure returns
 +      in ffi_call_SYSV.
 +      (ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI.
 +      Aka FFI_SYSV.
 +      (ffi_closure_helper_SYSV): Likewise.
 +      * src/powerpc/ppc_closure.S: Add return types for small structures.
 +      * src/powerpc/sysv.S: Add bits to handle small structures for
 +      final SYSV 4 ABI.
 +
 +2005-07-10  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/cls_5_1_byte.c: New test file.
 +      * testsuite/libffi.call/cls_6_1_byte.c: Likewise.
 +      * testsuite/libffi.call/cls_7_1_byte.c: Likewise.
 +
 +2005-07-05  Randolph Chung  <tausq@debian.org>
 +
 +      * src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1
 +      as FFI_TYPE_SMALL_STRUCT3.  Break out handling for 5-7 byte
 +      structures.  Kill compilation warnings.
 +      (ffi_closure_inner_LINUX): Print return values as hex in debug
 +      message.  Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3.
 +      Properly handle 5-7 byte structure returns.
 +      * src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1)
 +      (FFI_TYPE_SMALL_STRUCT2): Remove.
 +      (FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5)
 +      (FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define.
 +      * src/pa/linux.S: Mark source file as using PA1.1 assembly.
 +      (checksmst1, checksmst2): Remove.
 +      (checksmst3): Optimize handling of 3-byte struct returns.
 +      (checksmst567): Properly handle 5-7 byte struct returns.
 +
 +2005-06-15  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      PR libgcj/21943
 +      * src/mips/n32.S: Enforce PIC code.
 +      * src/mips/o32.S: Likewise.
 +
 +2005-06-15  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * configure.ac: Treat i*86-*-solaris2.10 and up as X86_64.
 +      * configure: Regenerate.
 +
 +2005-06-01  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET
 +      to call ffi_closure_helper_SYSV.  Append @local instead.
 +      * src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV.
 +
 +2005-05-17  Kelley Cook  <kcook@gcc.gnu.org>
 +
 +      * configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS.
 +      Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF.
 +      * Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config.
 +      * aclocal.m4, configure, fficonfig.h.in, Makefile.in,
 +      include/Makefile.in, testsuite/Makefile.in: Regenerate.
 +
 +2005-05-09  Mike Stump  <mrs@apple.com>
 +
 +      * configure: Regenerate.
 +
 +2005-05-08  Richard Henderson  <rth@redhat.com>
 +
 +      PR libffi/21285
 +      * src/alpha/osf.S: Update unwind into to match code.
 +
 +2005-05-04  Andreas Degert <ad@papyrus-gmbh.de>
 +          Richard Henderson  <rth@redhat.com>
 +
 +      * src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in
 +      bit 11 of flags.
 +      (ffi_call): Mask return type field.  Pass ssecount to ffi_call_unix64.
 +      (ffi_prep_closure): Set carry bit if sse-used flag set.
 +      * src/x86/unix64.S (ffi_call_unix64): Add ssecount argument.
 +      Only load sse registers if ssecount non-zero.
 +      (ffi_closure_unix64): Only save sse registers if carry set on entry.
 +
 +2005-04-29  Ralf Corsepius  <ralf.corsepius@rtems.org>
 +
 +      * configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*,
 +      powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*.
 +      * configure: Regenerate.
 +
 +2005-04-20  Hans-Peter Nilsson  <hp@axis.com>
 +
 +      * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use,
 +      have Tcl8.3-compatible intermediate variable.
 +
 +2005-04-18  Simon Posnjak <simon.posnjak@siol.net>
 +          Hans-Peter Nilsson  <hp@axis.com>
 +
 +      * Makefile.am: Add CRIS support.
 +      * configure.ac: Likewise.
 +      * Makefile.in, configure, testsuite/Makefile.in,
 +      include/Makefile.in: Regenerate.
 +      * src/cris: New directory.
 +      * src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files.
 +      * src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__.
 +
 +      * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with
 +      \r?\n in output tests.
 +
 +2005-04-12  Mike Stump  <mrs@apple.com>
 +
 +      * configure: Regenerate.
 +
 +2005-03-30  Hans Boehm  <Hans.Boehm@hp.com>
 +
 +      * src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI.
 +
 +2005-03-30  Steve Ellcey  <sje@cup.hp.com>
 +
 +      * src/ia64/ffitarget.h (ffi_arg) ADD DI attribute.
 +      (ffi_sarg) Ditto.
 +      * src/ia64/unix.S (ffi_closure_unix): Extend gp
 +      to 64 bits in ILP32 mode.
 +      Load 64 bits even for short data.
 +
 +2005-03-23  Mike Stump  <mrs@apple.com>
 +
 +      * src/powerpc/darwin.S: Update for -m64 multilib.
 +      * src/powerpc/darwin_closure.S: Likewise.
 +
 +2005-03-21  Zack Weinberg  <zack@codesourcery.com>
 +
 +      * configure.ac: Do not invoke TL_AC_GCC_VERSION.
 +      Do not set tool_include_dir.
 +      * aclocal.m4, configure, Makefile.in, testsuite/Makefile.in:
 +      Regenerate.
 +      * include/Makefile.am: Set gcc_version and toollibffidir.
 +      * include/Makefile.in: Regenerate.
 +
 +2005-02-22  Andrew Haley  <aph@redhat.com>
 +
 +      * src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to
 +      odd-numbered register pairs for 64-bit integer types.
 +
 +2005-02-23  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      PR libffi/20104
 +      * testsuite/libffi.call/return_ll1.c: New test case.
 +
 +2005-02-11  Janis Johnson  <janis187@us.ibm.com>
 +
 +      * testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options.
 +      * testsuite/libffi.call/float.c: Ditto.
 +      * testsuite/libffi.call/float2.c: Ditto.
 +      * testsuite/libffi.call/float3.c: Ditto.
 +
 +2005-02-08  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv.
 +
 +2005-01-12  Eric Botcazou  <ebotcazou@libertysurf.fr>
 +
 +      * testsuite/libffi.special/special.exp (cxx_options): Add
 +      -shared-libgcc.
 +
 +2004-12-31  Richard Henderson  <rth@redhat.com>
 +
 +      * src/types.c (FFI_AGGREGATE_TYPEDEF): Remove.
 +      (FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF.  Replace size and
 +      offset parameters with a type parameter; deduce size and structure
 +      alignment.  Update all users.
 +
 +2004-12-31  Richard Henderson  <rth@redhat.com>
 +
 +      * src/types.c (FFI_TYPE_POINTER): Define with sizeof.
 +      (FFI_TYPE_LONGDOUBLE): Fix for ia64.
 +      * src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move
 +      into ffi_prep_closure.
 +      * src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite
 +      from scratch.
 +
 +2004-12-27  Richard Henderson  <rth@redhat.com>
 +
 +      * src/x86/unix64.S: Fix typo in unwind info.
 +
 +2004-12-25  Richard Henderson  <rth@redhat.com>
 +
 +      * src/x86/ffi64.c (struct register_args): Rename from stackLayout.
 +      (enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS.
 +      (merge_classes): Check for it.
 +      (SSE_CLASS_P): New.
 +      (classify_argument): Pass byte_offset by value; perform all updates
 +      inside struct case.
 +      (examine_argument): Add classes argument; handle
 +      X86_64_COMPLEX_X87_CLASS.
 +      (ffi_prep_args): Merge into ...
 +      (ffi_call): ... here.  Share stack frame with ffi_call_unix64.
 +      (ffi_prep_cif_machdep): Setup cif->flags for proper structure return.
 +      (ffi_fill_return_value): Remove.
 +      (ffi_prep_closure): Remove dead assert.
 +      (ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner.
 +      Rewrite to use struct register_args instead of va_list.  Create
 +      flags for handling structure returns.
 +      * src/x86/unix64.S: Remove dead strings.
 +      (ffi_call_unix64): Rename from ffi_call_UNIX64.  Rewrite to share
 +      stack frame with ffi_call.  Handle structure returns properly.
 +      (float2sse, floatfloat2sse, double2sse): Remove.
 +      (sse2float, sse2double, sse2floatfloat): Remove.
 +      (ffi_closure_unix64): Rename from ffi_closure_UNIX64.  Rewrite
 +      to handle structure returns properly.
 +
 +2004-12-08  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and
 +      PICFLAG.
 +      * Makefile.in: Regenerated.
 +
 +2004-12-02  Richard Sandiford  <rsandifo@redhat.com>
 +
 +      * configure.ac: Use TL_AC_GCC_VERSION to set gcc_version.
 +      * configure, aclocal.m4, Makefile.in: Regenerate.
 +      * include/Makefile.in, testsuite/Makefile.in: Regenerate.
 +
 +2004-11-29  Kelley Cook  <kcook@gcc.gnu.org>
 +
 +      * configure: Regenerate for libtool change.
 +
 +2004-11-25  Kelley Cook  <kcook@gcc.gnu.org>
 +
 +      * configure: Regenerate for libtool reversion.
 +
 +2004-11-24  Kelley Cook  <kcook@gcc.gnu.org>
 +
 +      * configure: Regenerate for libtool change.
 +
 +2004-11-23  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 +
 +      * testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp.
 +
 +2004-11-23  Richard Sandiford  <rsandifo@redhat.com>
 +
 +      * src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead
 +      of jal.  Use an absolute encoding for the frame information.
 +
 +2004-11-23  Kelley Cook  <kcook@gcc.gnu.org>
 +
 +      * Makefile.am: Remove no-dependencies.  Add ACLOCAL_AMFLAGS.
 +      * acinclude.m4: Delete logic for sincludes.
 +      * aclocal.m4, Makefile.in, configure: Regenerate.
 +      * include/Makefile: Likewise.
 +      * testsuite/Makefile: Likewise.
 +
 +2004-11-22  Eric Botcazou  <ebotcazou@libertysurf.fr>
 +
 +      * src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers
 +      on a 8-byte boundary.
 +      * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments.
 +
 +2004-10-27  Richard Earnshaw  <rearnsha@arm.com>
 +
 +      * src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return
 +      long long values.  Round stack allocation to a multiple of 8 bytes
 +      for ATPCS compatibility.
 +      * src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register
 +      names.  Handle returning long long types.  Add Thumb and interworking
 +      support.  Improve soft-float code.
 +
 +2004-10-27  Richard Earnshaw  <rearnsha@arm.com>
 +
 +      * testsuite/lib/libffi-db.exp (load_gcc_lib): New function.
 +      (libffi_exit): New function.
 +      (libffi_init): Build the testglue wrapper if needed.
 +
 +2004-10-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
 +
 +      PR other/18138
 +      * testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc.
 +
 +2004-10-25  Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
 +
 +      * src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0.
 +
 +2004-10-20  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/sysv.S (ffi_call_SYSV): Don't align for double data.
 +      * testsuite/libffi.call/float3.c: New test case.
 +
 +2004-10-18  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for
 +      the function returning a structure pointed with R2.
 +      * src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to
 +      the structure return value if T bit set.  Emit position
 +      independent code and EH data if PIC.
 +
 +2004-10-13  Kazuhiro Inaoka  <inaoka.kazuhiro@renesas.com>
 +
 +      * Makefile.am: Add m32r support.
 +      * configure.ac: Likewise.
 +      * Makefile.in: Regenerate.
 +      * confiugre: Regenerate.
 +      * src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF
 +      (uint64, sint64, double, longdouble)
 +      * src/m32r: New directory.
 +      * src/m32r/ffi.c: New file.
 +      * src/m32r/sysv.S: Likewise.
 +      * src/m32r/ffitarget.h: Likewise.
 +
 +2004-10-02  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * testsuite/libffi.call/negint.c: New test case.
 +
 +2004-09-14  H.J. Lu  <hongjiu.lu@intel.com>
 +
 +      PR libgcj/17465
 +      * testsuite/lib/libffi-dg.exp: Don't use global ld_library_path.
 +      Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH,
 +      LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and
 +      DYLD_LIBRARY_PATH.
 +
 +2004-09-05  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/many_win32.c: Remove whitespaces.
 +      * testsuite/libffi.call/promotion.c: Likewise.
 +      * testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup
 +      whitespaces.
 +      * testsuite/libffi.call/return_sc.c: Likewise.
 +      * testsuite/libffi.call/return_uc.c: Likewise.
 +
 +2004-09-05  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/darwin.S: Fix comments and identation.
 +      * src/powerpc/darwin_closure.S: Likewise.
 +
 +2004-09-02  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/ffi_darwin.c: Add flag for longdouble return values.
 +      (ffi_prep_args): Handle longdouble arguments.
 +      (ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for
 +      longdouble.
 +      (ffi_closure_helper_DARWIN): Add closure handling for longdouble.
 +      * src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble
 +      values.
 +      * src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise.
 +      * src/types.c: Defined longdouble size and alignment for darwin.
 +
 +2004-09-02  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/aix.S: Remove whitespaces.
 +      * src/powerpc/aix_closure.S: Likewise.
 +      * src/powerpc/asm.h: Likewise.
 +      * src/powerpc/ffi.c: Likewise.
 +      * src/powerpc/ffitarget.h: Likewise.
 +      * src/powerpc/linux64.S: Likewise.
 +      * src/powerpc/linux64_closure.S: Likewise.
 +      * src/powerpc/ppc_closure.S: Likewise.
 +      * src/powerpc/sysv.S: Likewise.
 +
 +2004-08-30  Anthony Green  <green@redhat.com>
 +
 +      * Makefile.am: Add frv support.
 +      * Makefile.in, testsuite/Makefile.in: Rebuilt.
 +      * configure.ac: Read configure.host.
 +      * configure.in: Read configure.host.
 +      * configure.host: New file.  frv-elf needs libgloss.
 +      * include/ffi.h.in: Force ffi_closure to have a nice big (8)
 +      alignment.  This is needed to frv and shouldn't harm the others.
 +      * include/ffi_common.h (ALIGN_DOWN): New macro.
 +      * src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files.
 +
 +2004-08-24  David Daney  <daney@avtrex.com>
 +
 +      * testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*.
 +      * testsuite/libffi.call/closure_fn1.c: Likewise.
 +      * testsuite/libffi.call/closure_fn2.c  Likewise.
 +      * testsuite/libffi.call/closure_fn3.c: Likewise.
 +      * testsuite/libffi.call/closure_fn4.c: Likewise.
 +      * testsuite/libffi.call/closure_fn5.c: Likewise.
 +      * testsuite/libffi.call/cls_18byte.c: Likewise.
 +      * testsuite/libffi.call/cls_19byte.c: Likewise.
 +      * testsuite/libffi.call/cls_1_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_24byte.c: Likewise.
 +      * testsuite/libffi.call/cls_2byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_4_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_4byte.c: Likewise.
 +      * testsuite/libffi.call/cls_64byte.c: Likewise.
 +      * testsuite/libffi.call/cls_6byte.c: Likewise.
 +      * testsuite/libffi.call/cls_7byte.c: Likewise.
 +      * testsuite/libffi.call/cls_8byte.c: Likewise.
 +      * testsuite/libffi.call/cls_9byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_9byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_align_double.c: Likewise.
 +      * testsuite/libffi.call/cls_align_float.c: Likewise.
 +      * testsuite/libffi.call/cls_align_longdouble.c: Likewise.
 +      * testsuite/libffi.call/cls_align_pointer.c: Likewise.
 +      * testsuite/libffi.call/cls_align_sint16.c: Likewise.
 +      * testsuite/libffi.call/cls_align_sint32.c: Likewise.
 +      * testsuite/libffi.call/cls_align_sint64.c: Likewise.
 +      * testsuite/libffi.call/cls_align_uint16.c: Likewise.
 +      * testsuite/libffi.call/cls_align_uint32.c: Likewise.
 +      * testsuite/libffi.call/cls_align_uint64.c: Likewise.
 +      * testsuite/libffi.call/cls_double.c: Likewise.
 +      * testsuite/libffi.call/cls_float.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_schar.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_sshort.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_ushort.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
 +      * testsuite/libffi.call/cls_schar.c: Likewise.
 +      * testsuite/libffi.call/cls_sint.c: Likewise.
 +      * testsuite/libffi.call/cls_sshort.c: Likewise.
 +      * testsuite/libffi.call/cls_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_uint.c: Likewise.
 +      * testsuite/libffi.call/cls_ulonglong.c: Likewise.
 +      * testsuite/libffi.call/cls_ushort.c: Likewise.
 +      * testsuite/libffi.call/nested_struct.c: Likewise.
 +      * testsuite/libffi.call/nested_struct1.c: Likewise.
 +      * testsuite/libffi.call/nested_struct2.c: Likewise.
 +      * testsuite/libffi.call/nested_struct3.c: Likewise.
 +      * testsuite/libffi.call/problem1.c: Likewise.
 +      * testsuite/libffi.special/unwindtest.cc: Likewise.
 +      * testsuite/libffi.call/cls_12byte.c: Likewise and set return value
 +      to zero.
 +      * testsuite/libffi.call/cls_16byte.c: Likewise.
 +      * testsuite/libffi.call/cls_5byte.c: Likewise.
 +
 +2004-08-23  David Daney <daney@avtrex.com>
 +
 +      PR libgcj/13141
 +      * src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI.
 +      * src/mips/ffi.c (ffi_prep_args): Fix alignment calculation.
 +      (ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point
 +      parameters and return types.
 +      (ffi_call): Handle FFI_O32_SOFT_FLOAT ABI.
 +      (ffi_prep_closure): Ditto.
 +      (ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix
 +      alignment calculations.
 +      * src/mips/o32.S (ffi_closure_O32): Don't use floating point
 +      instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant.
 +
 +2004-08-14  Casey Marshall <csm@gnu.org>
 +
 +      * src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to
 +      contain `FFI_TYPE_UINT64' as return type for any 64-bit
 +      integer (O32 ABI only).
 +      (ffi_prep_closure): new function.
 +      (ffi_closure_mips_inner_O32): new function.
 +      * src/mips/ffitarget.h: Define `FFI_CLOSURES' and
 +      `FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32.
 +      * src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return
 +      64 bit integers correctly.
 +      (ffi_closure_O32): new function.
 +      Added DWARF-2 unwind info for both functions.
 +
 +2004-08-10  Andrew Haley  <aph@redhat.com>
 +
 +      * src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments.
 +
 +2004-08-01  Robert Millan  <robertmh@gnu.org>
 +
 +      * configure.ac: Detect knetbsd-gnu and kfreebsd-gnu.
 +      * configure: Regenerate.
 +
 +2004-07-30  Maciej W. Rozycki  <macro@linux-mips.org>
 +
 +      * acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for <sys/mman.h>
 +      and mmap() explicitly instead of relying on preset autoconf cache
 +      variables.
 +      * aclocal.m4: Regenerate.
 +      * configure: Regenerate.
 +
 +2004-07-11  Ulrich Weigand  <uweigand@de.ibm.com>
 +
 +      * src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation.
 +      (ffi_check_float_struct): Remove unused prototype.
 +
 +2004-06-30  Geoffrey Keating  <geoffk@apple.com>
 +
 +      * src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment
 +      character on Darwin, use '\n\t' instead.
 +
 +2004-06-26  Matthias Klose  <doko@debian.org>
 +
 +      * libtool-version: Fix typo in revision/age.
 +
 +2004-06-17  Matthias Klose  <doko@debian.org>
 +
 +      * libtool-version: New.
 +      * Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname.
 +      * Makefile.in: Regenerate.
 +
 +2004-06-15  Paolo Bonzini  <bonzini@gnu.org>
 +
 +      * Makefile.am: Remove useless multilib rules.
 +      * Makefile.in: Regenerate.
 +      * aclocal.m4: Regenerate with automake 1.8.5.
 +      * configure.ac: Remove useless multilib configury.
 +      * configure: Regenerate.
 +
 +2004-06-15  Paolo Bonzini  <bonzini@gnu.org>
 +
 +      * .cvsignore: New file.
 +
 +2004-06-10  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/ia64/unix.S (ffi_call_unix): Insert group barrier break
 +      fp_done.
 +      (ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever
 +      changed from 8.
 +
 +2004-06-06  Sean McNeil  <sean@mcneil.com>
 +
 +      * configure.ac: Add x86_64-*-freebsd* support.
 +      * configure: Regenerate.
 +
 +2004-04-26  Joe Buck <jbuck@welsh-buck.org>
 +
 +      Bug 15093
 +      * configure.ac: Test for existence of mmap and sys/mman.h before
 +      checking blacklist.  Fix suggested by Jim Wilson.
 +      * configure: Regenerate.
 +
 +2004-04-26  Matt Austern  <austern@apple.com>
 +
 +      * src/powerpc/darwin.S: Go through a non-lazy pointer for initial
 +      FDE location.
 +      * src/powerpc/darwin_closure.S: Likewise.
 +
 +2004-04-24  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization
 +      error. Reported by Thomas Heller <theller@python.net>.
 +      * testsuite/libffi.call/cls_multi_sshort.c (main): Likewise.
 +      * testsuite/libffi.call/cls_multi_ushort.c (main): Likewise.
 +
 +2004-03-20  Matthias Klose  <doko@debian.org>
 +
 +      * src/pa/linux.S: Fix typo.
 +
 +2004-03-19  Matthias Klose  <doko@debian.org>
 +
 +      * Makefile.am: Update.
 +      * Makefile.in: Regenerate.
 +      * src/pa/ffi.h.in: Remove.
 +      * src/pa/ffitarget.h: New file.
 +
 +2004-02-10  Randolph Chung  <tausq@debian.org>
 +
 +      * Makefile.am: Add PA support.
 +      * Makefile.in: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * configure.ac: Add PA target.
 +      * configure: Regenerate.
 +      * src/pa/ffi.c: New file.
 +      * src/pa/ffi.h.in: Add PA support.
 +      * src/pa/linux.S: New file.
 +      * prep_cif.c: Add PA support.
 +
 +2004-03-16  Hosaka Yuji  <hos@tamanegi.org>
 +
 +      * src/types.c: Fix alignment size of X86_WIN32 case int64 and
 +      double.
 +      * src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type
 +      with ecif->cif->flags.
 +      (ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type
 +      with cif->flags.
 +      (ffi_prep_cif_machdep): Add X86_WIN32 struct case.
 +      (ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32.
 +      * src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b,
 +      sc_retstruct2b): Add for 1 or 2-bytes struct case.
 +
 +2004-03-15 Kelley Cook <kcook@gcc.gnu.org>
 +
 +      * configure.in: Rename file to ...
 +      * configure.ac: ... this.
 +      * fficonfig.h.in: Regenerate.
 +      * Makefile.in: Regenerate.
 +      * include/Makefile.in: Regenerate.
 +      * testsuite/Makefile.in: Regenerate.
 +
 +2004-03-12  Matt Austern  <austern@apple.com>
 +
 +      * src/powerpc/darwin.S: Fix EH information so it corresponds to
 +      changes in EH format resulting from addition of linkonce support.
 +      * src/powerpc/darwin_closure.S: Likewise.
 +
 +2004-03-11  Andreas Tobler  <a.tobler@schweiz.ch>
 +          Paolo Bonzini  <bonzini@gnu.org>
 +
 +      * Makefile.am (AUTOMAKE_OPTIONS): Set them.
 +      Remove VPATH. Remove rules for object files. Remove multilib support.
 +      (AM_CCASFLAGS): Add.
 +      * configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER.
 +      (AC_PREREQ): Bump version to 2.59.
 +      (AC_INIT): Fill with version info and bug address.
 +      (ORIGINAL_LD_FOR_MULTILIBS): Remove.
 +      (AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE.
 +      De-precious CC so that the right flags are passed down to multilibs.
 +      (AC_MSG_ERROR): Replace obsolete macro AC_ERROR.
 +      (AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES.
 +      (AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS.
 +      * configure: Rebuilt.
 +      * aclocal.m4: Likewise.
 +      * Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise.
 +      * fficonfig.h.in: Likewise.
 +
 +2004-03-11  Andreas Schwab  <schwab@suse.de>
 +
 +      * src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point
 +      arguments from fp registers only for the first 8 parameter slots.
 +      Don't convert a float parameter when passed in memory.
 +
 +2004-03-09  Hans-Peter Nilsson  <hp@axis.com>
 +
 +      * configure: Regenerate for config/accross.m4 correction.
 +
 +2004-02-25  Matt Kraai  <kraai@alumni.cmu.edu>
 +
 +      * src/powerpc/ffi.c (ffi_prep_args_SYSV): Change
 +      ecif->cif->bytes to bytes.
 +      (ffi_prep_cif_machdep): Add braces around nested if statement.
 +
 +2004-02-09  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/types.c (pointer): POWERPC64 has 8 byte pointers.
 +
 +      * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling.
 +      (ffi_closure_helper_LINUX64): Fix typo.
 +      * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128
 +      for powerpc64-*-*.
 +      * testsuite/libffi.call/float.c: Likewise.
 +      * testsuite/libffi.call/float2.c: Likewise.
 +
 +2004-02-08  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/powerpc/ffi.c (ffi_prep_cif_machdep <FFI_LINUX64>): Correct
 +      long double function return and long double arg handling.
 +      (ffi_closure_helper_LINUX64): Formatting.  Delete unused "ng" var.
 +      Use "end_pfr" instead of "nf".  Correct long double handling.
 +      Localise "temp".
 +      * src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double
 +      return value.
 +      * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate
 +      space for long double return value.  Adjust stack frame and offsets.
 +      Load f2 long double return.
 +
 +2004-02-07  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/types.c: Use 16 byte long double for POWERPC64.
 +
 +2004-01-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
 +
 +      * src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array
 +      when the structure return address is passed in %o0.
 +      (ffi_V9_return_struct): Rename into ffi_v9_layout_struct.
 +      (ffi_v9_layout_struct): Align the field following a nested structure
 +      on a word boundary.  Use memmove instead of memcpy.
 +      (ffi_call): Update call to ffi_V9_return_struct.
 +      (ffi_prep_closure): Define 'ctx' only for V8.
 +      (ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8
 +      and ffi_closure_sparc_inner_v9.
 +      (ffi_closure_sparc_inner_v8): Return long doubles by reference.
 +      Always skip the structure return address.  For structures and long
 +      doubles, copy the argument directly.
 +      (ffi_closure_sparc_inner_v9): Skip the structure return address only
 +      if required.  Shift the maximum floating-point slot accordingly.  For
 +      big structures, copy the argument directly; otherwise, left-justify the
 +      argument and call ffi_v9_layout_struct to lay out the structure on
 +      the stack.
 +      * src/sparc/v8.S: Undef STACKFRAME before defining it.
 +      (ffi_closure_v8): Pass the structure return address.  Update call to
 +      ffi_closure_sparc_inner_v8.  Short-circuit FFI_TYPE_INT handling.
 +      Skip the 'unimp' insn when returning long doubles and structures.
 +      * src/sparc/v9.S: Undef STACKFRAME before defining it.
 +      (ffi_closure_v9): Increase the frame size by 2 words.  Short-circuit
 +      FFI_TYPE_INT handling.  Load structures both in integers and
 +      floating-point registers on return.
 +      * README: Update status of the SPARC port.
 +
 +2004-01-24  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/pyobjc-tc.c (main): Treat result value
 +      as of type ffi_arg.
 +      * testsuite/libffi.call/struct3.c (main): Fix CHECK.
 +
 +2004-01-22  Ulrich Weigand  <uweigand@de.ibm.com>
 +
 +      * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result
 +      value as of type ffi_arg, not unsigned int.
 +
 +2004-01-21  Michael Ritzert  <ritzert@t-online.de>
 +
 +      * ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead
 +      of the LHS.
 +
 +2004-01-12  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for
 +      Solaris.
 +
 +2004-01-08  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED
 +      to void *.
 +
 +2003-12-10  Richard Henderson  <rth@redhat.com>
 +
 +      * testsuite/libffi.call/cls_align_pointer.c: Cast pointers to
 +      size_t instead of int.
 +
 +2003-12-04  Hosaka Yuji  <hos@tamanegi.org>
 +
 +      * testsuite/libffi.call/many_win32.c: Include <float.h>.
 +      * testsuite/libffi.call/many_win32.c (main): Replace variable
 +      int i with unsigned long ul.
 +
 +      * testsuite/libffi.call/cls_align_uint64.c: New test case.
 +      * testsuite/libffi.call/cls_align_sint64.c: Likewise.
 +      * testsuite/libffi.call/cls_align_uint32.c: Likewise.
 +      * testsuite/libffi.call/cls_align_sint32.c: Likewise.
 +      * testsuite/libffi.call/cls_align_uint16.c: Likewise.
 +      * testsuite/libffi.call/cls_align_sint16.c: Likewise.
 +      * testsuite/libffi.call/cls_align_float.c: Likewise.
 +      * testsuite/libffi.call/cls_align_double.c: Likewise.
 +      * testsuite/libffi.call/cls_align_longdouble.c: Likewise.
 +      * testsuite/libffi.call/cls_align_pointer.c: Likewise.
 +
 +2003-12-02  Hosaka Yuji  <hos@tamanegi.org>
 +
 +      PR other/13221
 +      * src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV):
 +      Align arguments to 32 bits.
 +
 +2003-12-01  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      PR other/13221
 +      * testsuite/libffi.call/cls_multi_sshort.c: New test case.
 +      * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_schar.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
 +      * testsuite/libffi.call/cls_multi_ushort.c: Likewise.
 +
 +      * testsuite/libffi.special/unwindtest.cc: Cosmetics.
 +
 +2003-11-26  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 +
 +      * testsuite/libffi.call/ffitest.h: Include <fcntl.h>.
 +      * testsuite/libffi.special/ffitestcxx.h: Likewise.
 +
 +2003-11-22  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * Makefile.in: Rebuilt.
 +      * configure: Likewise.
 +      * testsuite/libffi.special/unwindtest.cc: Convert the mmap to
 +      the right type.
 +
 +2003-11-21  Andreas Jaeger  <aj@suse.de>
 +          Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST.
 +      * configure.in: Call AC_FUNC_MMAP_BLACKLIST.
 +      * Makefile.in: Rebuilt.
 +      * aclocal.m4: Likewise.
 +      * configure: Likewise.
 +      * fficonfig.h.in: Likewise.
 +      * testsuite/lib/libffi-dg.exp: Add include dir.
 +      * testsuite/libffi.call/ffitest.h: Add MMAP definitions.
 +      * testsuite/libffi.special/ffitestcxx.h: Likewise.
 +      * testsuite/libffi.call/closure_fn0.c: Use MMAP functionality
 +      for ffi_closure if available.
 +      * testsuite/libffi.call/closure_fn1.c: Likewise.
 +      * testsuite/libffi.call/closure_fn2.c: Likewise.
 +      * testsuite/libffi.call/closure_fn3.c: Likewise.
 +      * testsuite/libffi.call/closure_fn4.c: Likewise.
 +      * testsuite/libffi.call/closure_fn5.c: Likewise.
 +      * testsuite/libffi.call/cls_12byte.c: Likewise.
 +      * testsuite/libffi.call/cls_16byte.c: Likewise.
 +      * testsuite/libffi.call/cls_18byte.c: Likewise.
 +      * testsuite/libffi.call/cls_19byte.c: Likewise.
 +      * testsuite/libffi.call/cls_1_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_24byte.c: Likewise.
 +      * testsuite/libffi.call/cls_2byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_4_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_4byte.c: Likewise.
 +      * testsuite/libffi.call/cls_5byte.c: Likewise.
 +      * testsuite/libffi.call/cls_64byte.c: Likewise.
 +      * testsuite/libffi.call/cls_6byte.c: Likewise.
 +      * testsuite/libffi.call/cls_7byte.c: Likewise.
 +      * testsuite/libffi.call/cls_8byte.c: Likewise.
 +      * testsuite/libffi.call/cls_9byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_9byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_double.c: Likewise.
 +      * testsuite/libffi.call/cls_float.c: Likewise.
 +      * testsuite/libffi.call/cls_schar.c: Likewise.
 +      * testsuite/libffi.call/cls_sint.c: Likewise.
 +      * testsuite/libffi.call/cls_sshort.c: Likewise.
 +      * testsuite/libffi.call/cls_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_uint.c: Likewise.
 +      * testsuite/libffi.call/cls_ulonglong.c: Likewise.
 +      * testsuite/libffi.call/cls_ushort.c: Likewise.
 +      * testsuite/libffi.call/nested_struct.c: Likewise.
 +      * testsuite/libffi.call/nested_struct1.c: Likewise.
 +      * testsuite/libffi.call/nested_struct2.c: Likewise.
 +      * testsuite/libffi.call/nested_struct3.c: Likewise.
 +      * testsuite/libffi.call/problem1.c: Likewise.
 +      * testsuite/libffi.special/unwindtest.cc: Likewise.
 +
 +2003-11-20  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional.
 +
 +2003-11-19  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin.
 +      Add -lgcc_s to additional flags.
 +
 +2003-11-12  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * configure.in, include/Makefile.am: PR libgcj/11147, install
 +      the ffitarget.h header file in a gcc versioned and target
 +      dependent place.
 +      * configure: Regenerated.
 +      * Makefile.in, include/Makefile.in: Likewise.
 +      * testsuite/Makefile.in: Likewise.
 +
 +2003-11-09  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/closure_fn0.c: Print result and check
 +      with dg-output to make debugging easier.
 +      * testsuite/libffi.call/closure_fn1.c: Likewise.
 +      * testsuite/libffi.call/closure_fn2.c: Likewise.
 +      * testsuite/libffi.call/closure_fn3.c: Likewise.
 +      * testsuite/libffi.call/closure_fn4.c: Likewise.
 +      * testsuite/libffi.call/closure_fn5.c: Likewise.
 +      * testsuite/libffi.call/cls_12byte.c: Likewise.
 +      * testsuite/libffi.call/cls_16byte.c: Likewise.
 +      * testsuite/libffi.call/cls_18byte.c: Likewise.
 +      * testsuite/libffi.call/cls_19byte.c: Likewise.
 +      * testsuite/libffi.call/cls_1_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_24byte.c: Likewise.
 +      * testsuite/libffi.call/cls_2byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_4_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_4byte.c: Likewise.
 +      * testsuite/libffi.call/cls_5byte.c: Likewise.
 +      * testsuite/libffi.call/cls_64byte.c: Likewise.
 +      * testsuite/libffi.call/cls_6byte.c: Likewise.
 +      * testsuite/libffi.call/cls_7byte.c: Likewise.
 +      * testsuite/libffi.call/cls_8byte.c: Likewise.
 +      * testsuite/libffi.call/cls_9byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_9byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_double.c: Likewise.
 +      * testsuite/libffi.call/cls_float.c: Likewise.
 +      * testsuite/libffi.call/cls_schar.c: Likewise.
 +      * testsuite/libffi.call/cls_sint.c: Likewise.
 +      * testsuite/libffi.call/cls_sshort.c: Likewise.
 +      * testsuite/libffi.call/cls_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_uint.c: Likewise.
 +      * testsuite/libffi.call/cls_ulonglong.c: Likewise.
 +      * testsuite/libffi.call/cls_ushort.c: Likewise.
 +      * testsuite/libffi.call/problem1.c: Likewise.
 +
 +      * testsuite/libffi.special/unwindtest.cc: Make ffi_closure
 +      static.
 +
 +2003-11-08  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/cls_9byte2.c: New test case.
 +      * testsuite/libffi.call/cls_9byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_64byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_19byte.c: Likewise.
 +      * testsuite/libffi.call/cls_18byte.c: Likewise.
 +      * testsuite/libffi.call/closure_fn4.c: Likewise.
 +      * testsuite/libffi.call/closure_fn5.c: Likewise.
 +      * testsuite/libffi.call/cls_schar.c: Likewise.
 +      * testsuite/libffi.call/cls_sint.c: Likewise.
 +      * testsuite/libffi.call/cls_sshort.c: Likewise.
 +      * testsuite/libffi.call/nested_struct2.c: Likewise.
 +      * testsuite/libffi.call/nested_struct3.c: Likewise.
 +
 +2003-11-08  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/cls_double.c: Do a check on the result.
 +      * testsuite/libffi.call/cls_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_uint.c: Likewise.
 +      * testsuite/libffi.call/cls_ulonglong.c: Likewise.
 +      * testsuite/libffi.call/cls_ushort.c: Likewise.
 +      * testsuite/libffi.call/return_sc.c: Cleanup whitespaces.
 +
 +2003-11-06  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/prep_cif.c (ffi_prep_cif): Move the validity check after
 +      the initialization.
 +
 +2003-10-23  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace
 +      FFI_ASSERT(FALSE) with FFI_ASSERT(0).
 +
 +2003-10-22  David Daney  <ddaney@avtrex.com>
 +
 +      * src/mips/ffitarget.h: Replace undefined UINT32 and friends with
 +      __attribute__((__mode__(__SI__))) and friends.
 +
 +2003-10-22  Andreas Schwab  <schwab@suse.de>
 +
 +      * src/ia64/ffi.c: Replace FALSE/TRUE with false/true.
 +
 +2003-10-21  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * configure.in: AC_LINK_FILES(ffitarget.h).
 +      * configure: Regenerate.
 +      * Makefile.in: Likewise.
 +      * include/Makefile.in: Likewise.
 +      * testsuite/Makefile.in: Likewise.
 +      * fficonfig.h.in: Likewise.
 +
 +2003-10-21  Paolo Bonzini  <bonzini@gnu.org>
 +          Richard Henderson  <rth@redhat.com>
 +
 +      Avoid that ffi.h includes fficonfig.h.
 +
 +      * Makefile.am (EXTRA_DIST): Include ffitarget.h files
 +      (TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
 +      (TARGET_SRC_MIPS_SGI): Removed.
 +      (MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
 +      (MIPS_SGI): Removed.
 +      (CLEANFILES): Removed.
 +      (mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New
 +      targets.
 +      * acconfig.h: Removed.
 +      * configure.in: Compute sizeofs only for double and long double.
 +      Use them to define and subst HAVE_LONG_DOUBLE.  Include comments
 +      into AC_DEFINE instead of using acconfig.h.  Create
 +      include/ffitarget.h instead of include/fficonfig.h.  Rename
 +      MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree.
 +      AC_DEFINE EH_FRAME_FLAGS.
 +      * include/Makefile.am (DISTCLEANFILES): New automake macro.
 +      (hack_DATA): Add ffitarget.h.
 +      * include/ffi.h.in: Remove all system specific definitions.
 +      Declare raw API even if it is not installed, why bother?
 +      Use limits.h instead of SIZEOF_* to define ffi_type_*.  Do
 +      not define EH_FRAME_FLAGS, it is in fficonfig.h now.  Include
 +      ffitarget.h instead of fficonfig.h.  Remove ALIGN macro.
 +      (UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead.
 +      * include/ffi_common.h (bool): Do not define.
 +      (ffi_assert): Accept failed assertion.
 +      (ffi_type_test): Return void and accept file/line.
 +      (FFI_ASSERT): Pass stringized failed assertion.
 +      (FFI_ASSERT_AT): New macro.
 +      (FFI_ASSERT_VALID_TYPE): New macro.
 +      (UINT8, SINT8, UINT16, SINT16, UINT32, SINT32,
 +      UINT64, SINT64): Define here with gcc's __attribute__ macro
 +      instead of in ffi.h
 +      (FLOAT32, ALIGN): Define here instead of in ffi.h
 +      * include/ffi-mips.h: Removed.  Its content moved to
 +      src/mips/ffitarget.h after separating assembly and C sections.
 +      * src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c
 +      src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c,
 +      src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S,
 +      src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c:
 +      SIZEOF_ARG -> FFI_SIZEOF_ARG.
 +      * src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+).
 +      * src/debug.c (ffi_assert): Accept stringized failed assertion.
 +      (ffi_type_test): Rewritten.
 +      * src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call
 +      FFI_ASSERT_VALID_TYPE.
 +      * src/alpha/ffitarget.h, src/arm/ffitarget.h,
 +      src/ia64/ffitarget.h, src/m68k/ffitarget.h,
 +      src/mips/ffitarget.h, src/powerpc/ffitarget.h,
 +      src/s390/ffitarget.h, src/sh/ffitarget.h,
 +      src/sh64/ffitarget.h, src/sparc/ffitarget.h,
 +      src/x86/ffitarget.h: New files.
 +      * src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S,
 +      src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S,
 +      src/powerpc/aix.S, src/powerpc/darwin.S,
 +      src/powerpc/ffi_darwin.c, src/powerpc/linux64.S,
 +      src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S,
 +      src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S,
 +      src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S,
 +      src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S:
 +      include fficonfig.h
 +
 +2003-10-20  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external
 +      _MIPS_SIM_NABI32, _MIPS_SIM_ABI32.
 +
 +2003-10-19  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again.
 +      Used when FFI_DEBUG = 1.
 +
 +2003-10-14  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/types.c (double, longdouble): Default POWERPC64 to 8 byte size
 +      and align.
 +
 +2003-10-06  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs,
 +      FFI_MIPS_O32 for O32 ABI.
 +
 +2003-10-01  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for
 +      SPARC64. Cleanup whitespaces.
 +
 +2003-09-19  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * testsuite/libffi.call/closure_fn0.c: Xfail mips, arm,
 +      strongarm, xscale. Cleanup whitespaces.
 +      * testsuite/libffi.call/closure_fn1.c: Likewise.
 +      * testsuite/libffi.call/closure_fn2.c: Likewise.
 +      * testsuite/libffi.call/closure_fn3.c: Likewise.
 +      * testsuite/libffi.call/cls_12byte.c: Likewise.
 +      * testsuite/libffi.call/cls_16byte.c: Likewise.
 +      * testsuite/libffi.call/cls_1_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte.c: Likewise.
 +      * testsuite/libffi.call/cls_24byte.c: Likewise.
 +      * testsuite/libffi.call/cls_2byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_4_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_4byte.c: Likewise.
 +      * testsuite/libffi.call/cls_5byte.c: Likewise.
 +      * testsuite/libffi.call/cls_6byte.c: Likewise.
 +      * testsuite/libffi.call/cls_7byte.c: Likewise.
 +      * testsuite/libffi.call/cls_8byte.c: Likewise.
 +      * testsuite/libffi.call/cls_double.c: Likewise.
 +      * testsuite/libffi.call/cls_float.c: Likewise.
 +      * testsuite/libffi.call/cls_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_uint.c: Likewise.
 +      * testsuite/libffi.call/cls_ulonglong.c: Likewise.
 +      * testsuite/libffi.call/cls_ushort.c: Likewise.
 +      * testsuite/libffi.call/nested_struct.c: Likewise.
 +      * testsuite/libffi.call/nested_struct1.c: Likewise.
 +      * testsuite/libffi.call/problem1.c: Likewise.
 +      * testsuite/libffi.special/unwindtest.cc: Likewise.
 +      * testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces.
 +
 +2003-09-18  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/aix.S: Cleanup whitespaces.
 +      * src/powerpc/aix_closure.S: Likewise.
 +
 +2003-09-18  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/darwin.S: Cleanup whitespaces, comment formatting.
 +      * src/powerpc/darwin_closure.S: Likewise.
 +      * src/powerpc/ffi_darwin.c: Likewise.
 +
 +2003-09-18  Andreas Tobler  <a.tobler@schweiz.ch>
 +          David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/types.c (double): Add AIX and Darwin to the right TYPEDEF.
 +      * src/powerpc/aix_closure.S: Remove the pointer to the outgoing
 +      parameter stack.
 +      * src/powerpc/darwin_closure.S: Likewise.
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures
 +      according to the Darwin/AIX ABI.
 +      (ffi_prep_cif_machdep): Likewise.
 +      (ffi_closure_helper_DARWIN): Likewise.
 +      Remove the outgoing parameter stack logic. Simplify the evaluation
 +      of the different CASE types.
 +      (ffi_prep_clousure): Avoid the casts on lvalues. Change the branch
 +      statement in the trampoline code.
 +
 +2003-09-18  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
-       Fix alignement bug, allocate 8 bytes for the result.
++      * src/sh/ffi.c (ffi_prep_args): Take account into the alignment
 +      for the register size.
 +      (ffi_closure_helper_SYSV): Handle the structure return value
 +      address correctly.
 +      (ffi_closure_helper_SYSV): Return the appropriate type when
 +      the registers are used for the structure return value.
 +      * src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for
 +      the 64-bit return value.  Update copyright years.
 +
 +2003-09-17  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in
 +      srcdir for ffi_mips.h.
 +
 +2003-09-12  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/prep_cif.c (initialize_aggregate): Include tail padding in
 +      structure size.
 +      * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct
 +      placement of float result.
 +      * testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct
 +      cast of "resp" for big-endian 64 bit machines.
 +
 +2003-09-11  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/types.c (double, longdouble): Merge identical SH and ARM
 +      typedefs, and add POWERPC64.
 +      * src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for
 +      struct split over gpr and rest.
 +      (ffi_prep_cif_machdep): Correct intarg_count for structures.
 +      * src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets.
 +
 +2003-09-09  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct
 +      passing correctly.
 +
 +2003-09-09  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * configure: Regenerate.
 +
 +2003-09-04  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * Makefile.am: Remove build rules for ffitest.
 +      * Makefile.in: Rebuilt.
 +
 +2003-09-04  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/java_raw_api.c: Include <stdlib.h> to fix compiler warning
 +      about implicit declaration of abort().
 +
 +2003-09-04  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * Makefile.am: Add dejagnu test framework. Fixes PR other/11411.
 +      * Makefile.in: Rebuilt.
 +      * configure.in: Add dejagnu test framework.
 +      * configure: Rebuilt.
 +
 +      * testsuite/Makefile.am: New file.
 +      * testsuite/Makefile.in: Built
 +      * testsuite/lib/libffi-dg.exp: New file.
 +      * testsuite/config/default.exp: Likewise.
 +      * testsuite/libffi.call/call.exp: Likewise.
 +      * testsuite/libffi.call/ffitest.h: Likewise.
 +      * testsuite/libffi.call/closure_fn0.c: Likewise.
 +      * testsuite/libffi.call/closure_fn1.c: Likewise.
 +      * testsuite/libffi.call/closure_fn2.c: Likewise.
 +      * testsuite/libffi.call/closure_fn3.c: Likewise.
 +      * testsuite/libffi.call/cls_1_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_4_1byte.c: Likewise.
 +      * testsuite/libffi.call/cls_2byte.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte1.c: Likewise.
 +      * testsuite/libffi.call/cls_3byte2.c: Likewise.
 +      * testsuite/libffi.call/cls_4byte.c: Likewise.
 +      * testsuite/libffi.call/cls_5byte.c: Likewise.
 +      * testsuite/libffi.call/cls_6byte.c: Likewise.
 +      * testsuite/libffi.call/cls_7byte.c: Likewise.
 +      * testsuite/libffi.call/cls_8byte.c: Likewise.
 +      * testsuite/libffi.call/cls_12byte.c: Likewise.
 +      * testsuite/libffi.call/cls_16byte.c: Likewise.
 +      * testsuite/libffi.call/cls_20byte.c: Likewise.
 +      * testsuite/libffi.call/cls_24byte.c: Likewise.
 +      * testsuite/libffi.call/cls_double.c: Likewise.
 +      * testsuite/libffi.call/cls_float.c: Likewise.
 +      * testsuite/libffi.call/cls_uchar.c: Likewise.
 +      * testsuite/libffi.call/cls_uint.c: Likewise.
 +      * testsuite/libffi.call/cls_ulonglong.c: Likewise.
 +      * testsuite/libffi.call/cls_ushort.c: Likewise.
 +      * testsuite/libffi.call/float.c: Likewise.
 +      * testsuite/libffi.call/float1.c: Likewise.
 +      * testsuite/libffi.call/float2.c: Likewise.
 +      * testsuite/libffi.call/many.c: Likewise.
 +      * testsuite/libffi.call/many_win32.c: Likewise.
 +      * testsuite/libffi.call/nested_struct.c: Likewise.
 +      * testsuite/libffi.call/nested_struct1.c: Likewise.
 +      * testsuite/libffi.call/pyobjc-tc.c: Likewise.
 +      * testsuite/libffi.call/problem1.c: Likewise.
 +      * testsuite/libffi.call/promotion.c: Likewise.
 +      * testsuite/libffi.call/return_ll.c: Likewise.
 +      * testsuite/libffi.call/return_sc.c: Likewise.
 +      * testsuite/libffi.call/return_uc.c: Likewise.
 +      * testsuite/libffi.call/strlen.c: Likewise.
 +      * testsuite/libffi.call/strlen_win32.c: Likewise.
 +      * testsuite/libffi.call/struct1.c: Likewise.
 +      * testsuite/libffi.call/struct2.c: Likewise.
 +      * testsuite/libffi.call/struct3.c: Likewise.
 +      * testsuite/libffi.call/struct4.c: Likewise.
 +      * testsuite/libffi.call/struct5.c: Likewise.
 +      * testsuite/libffi.call/struct6.c: Likewise.
 +      * testsuite/libffi.call/struct7.c: Likewise.
 +      * testsuite/libffi.call/struct8.c: Likewise.
 +      * testsuite/libffi.call/struct9.c: Likewise.
 +      * testsuite/libffi.special/special.exp: New file.
 +      * testsuite/libffi.special/ffitestcxx.h: Likewise.
 +      * testsuite/libffi.special/unwindtest.cc: Likewise.
 +
 +
 +2003-08-13  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/ffi.c (OFS_INT16): Set 0 for little endian case.  Update
 +      copyright years.
 +
 +2003-08-02  Alan Modra  <amodra@bigpond.net.au>
 +
 +      * src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc
 +      structure passing.
 +      (ffi_closure_helper_LINUX64): Likewise.
 +      * src/powerpc/linux64.S: Remove code writing to parm save area.
 +      * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return
 +      address in lr from ffi_closure_helper_LINUX64 call to calculate
 +      table address.  Optimize function tail.
 +
 +2003-07-28  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/sparc/ffi.c: Handle all floating point registers.
 +      * src/sparc/v9.S: Likewise. Fixes second part of PR target/11410.
 +
 +2003-07-11  Gerald Pfeifer  <pfeifer@dbai.tuwien.ac.at>
 +
 +      * README: Note that libffi is not part of GCC.  Update the project
 +      URL and status.
 +
 +2003-06-19  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
 +
 +      * src/powerpc/ppc_closure.S: Include ffi.h.
 +
 +2003-06-13  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives.
 +      Use C style comments.
 +
 +2003-06-13  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
 +
 +      * Makefile.am: Add SHmedia support.  Fix a typo of SH support.
 +      * Makefile.in: Regenerate.
 +      * configure.in (sh64-*-linux*, sh5*-*-linux*): Add target.
 +      * configure: Regenerate.
 +      * include/ffi.h.in: Add SHmedia support.
 +      * src/sh64/ffi.c: New file.
 +      * src/sh64/sysv.S: New file.
 +
 +2003-05-16  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section
 +      should be read-only.
 +      * configure: Rebuilt.
 +      * fficonfig.h.in: Rebuilt.
 +      * include/ffi.h.in (EH_FRAME_FLAGS): Define.
 +      * src/alpha/osf.S: Use EH_FRAME_FLAGS.
 +      * src/powerpc/linux64.S: Likewise.
 +      * src/powerpc/linux64_closure.S: Likewise.  Include ffi.h.
 +      * src/powerpc/sysv.S: Use EH_FRAME_FLAGS.  Use pcrel encoding
 +      if -fpic/-fPIC/-mrelocatable.
 +      * src/powerpc/powerpc_closure.S: Likewise.
 +      * src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include
 +      #write in .eh_frame flags.
 +      * src/sparc/v9.S: Likewise.
 +      * src/x86/unix64.S: Use EH_FRAME_FLAGS.
 +      * src/x86/sysv.S: Likewise.  Use pcrel encoding if -fpic/-fPIC.
 +      * src/s390/sysv.S: Use EH_FRAME_FLAGS.  Include ffi.h.
 +
 +2003-05-07  Jeff Sturm  <jsturm@one-point.com>
 +
 +      Fixes PR bootstrap/10656
 +      * configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler
 +      support for .register pseudo-op.
 +      * src/sparc/v8.S: Use it.
 +      * fficonfig.h.in: Rebuilt.
 +      * configure: Rebuilt.
 +
 +2003-04-18  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * include/ffi.h.in (POWERPC64): Define if 64-bit.
 +      (enum ffi_abi): Add FFI_LINUX64 on POWERPC.
 +      Make it the default on POWERPC64.
 +      (FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64.
 +      * configure.in: Change powerpc-*-linux* into powerpc*-*-linux*.
 +      * configure: Rebuilt.
 +      * src/powerpc/ffi.c (hidden): Define.
 +      (ffi_prep_args_SYSV): Renamed from
 +      ffi_prep_args.  Cast pointers to unsigned long to shut up warnings.
 +      (NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64,
 +      ASM_NEEDS_REGISTERS64): New.
 +      (ffi_prep_args64): New function.
 +      (ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI.
 +      (ffi_call): Likewise.
 +      (ffi_prep_closure): Likewise.
 +      (flush_icache): Surround by #ifndef POWERPC64.
 +      (ffi_dblfl): New union type.
 +      (ffi_closure_helper_SYSV): Use it to avoid aliasing problems.
 +      (ffi_closure_helper_LINUX64): New function.
 +      * src/powerpc/ppc_closure.S: Surround whole file by #ifndef
 +      __powerpc64__.
 +      * src/powerpc/sysv.S: Likewise.
 +      (ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV.
 +      * src/powerpc/linux64.S: New file.
 +      * src/powerpc/linux64_closure.S: New file.
 +      * Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and
 +      src/powerpc/linux64_closure.S.
 +      (TARGET_SRC_POWERPC): Likewise.
 +
 +      * src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2,
 +      closure_test_fn3): Fix result printing on big-endian 64-bit
 +      machines.
 +      (main): Print tst2_arg instead of uninitialized tst2_result.
 +
 +      * src/ffitest.c (main): Hide what closure pointer really points to
 +      from the compiler.
 +
 +2003-04-16  Richard Earnshaw  <rearnsha@arm.com>
 +
 +      * configure.in (arm-*-netbsdelf*): Add configuration.
 +      (configure): Regenerated.
 +
 +2003-04-04  Loren J. Rittle  <ljrittle@acm.org>
 +
 +      * include/Makefile.in: Regenerate.
 +
 +2003-03-21  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 +
 +      * libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32
 +      bit mode.
 +      * libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV):
 +      Receive closure pointer through parameter, read args using
 +      __builtin_dwarf_cfa.
 +      (FFI_INIT_TRAMPOLINE): Send closure reference through eax.
 +
 +2003-03-12  Andreas Schwab  <schwab@suse.de>
 +
 +      * configure.in: Avoid trailing /. in toolexeclibdir.
 +      * configure: Rebuilt.
 +
 +2003-03-03  Andreas Tobler <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/darwin_closure.S: Recode to fit dynamic libraries.
 +
 +2003-02-06  Andreas Tobler <a.tobler@schweiz.ch>
 +
 +      * libffi/src/powerpc/darwin_closure.S:
++      Fix alignment bug, allocate 8 bytes for the result.
 +      * libffi/src/powerpc/aix_closure.S:
 +      Likewise.
 +      * libffi/src/powerpc/ffi_darwin.c:
 +      Update stackframe description for aix/darwin_closure.S.
 +
 +2003-02-06  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility
 +      attribute.
 +
 +2003-01-31  Christian Cornelssen  <ccorn@cs.tu-berlin.de>,
 +          Andreas Schwab  <schwab@suse.de>
 +
 +      * configure.in: Adjust command to source config-ml.in to account
 +      for changes to the libffi_basedir definition.
 +      (libffi_basedir): Remove ${srcdir} from value and include trailing
 +      slash if nonempty.
 +
 +      * configure: Regenerate.
 +
 +2003-01-29  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
 +
 +      * src/powerpc/ppc_closure.S: Recode to fit shared libs.
 +
 +2003-01-28  Andrew Haley  <aph@redhat.com>
 +
 +      * include/ffi.h.in: Enable FFI_CLOSURES for x86_64.
 +      * src/x86/ffi64.c (ffi_prep_closure): New.
 +      (ffi_closure_UNIX64_inner): New.
 +      * src/x86/unix64.S (ffi_closure_UNIX64): New.
 +
 +2003-01-27  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
 +      Remove USE_LIBDIR conditional.
 +      * Makefile.am (toolexecdir, toolexeclibdir): Don't override.
 +      * Makefile.in, configure: Rebuilt.
 +
 +2003-01027  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo.
 +      * Makefile.in: Regenerate.
 +
 +2003-01-22  Andrew Haley  <aph@redhat.com>
 +
 +      * src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to
 +      unwind info.
 +
 +2003-01-21  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/darwin.S: Add unwind info.
 +      * src/powerpc/darwin_closure.S: Likewise.
 +
 +2003-01-14  Andrew Haley  <aph@redhat.com>
 +
 +      * src/x86/ffi64.c (ffi_prep_args): Check for void retval.
 +      (ffi_prep_cif_machdep): Likewise.
 +      * src/x86/unix64.S: Add unwind info.
 +
 +2003-01-14  Andreas Jaeger  <aj@suse.de>
 +
 +      * src/ffitest.c (main): Only use ffi_closures if those are
 +      supported.
 +
 +2003-01-13 Andreas Tobler <a.tobler@schweiz.ch>
 +
 +      * libffi/src/ffitest.c
 +       add closure testcases
 +
 +2003-01-13 Kevin B. Hendricks <khendricks@ivey.uwo.ca>
 +
 +      * libffi/src/powerpc/ffi.c
 +       fix alignment bug for float (4 byte aligned iso 8 byte)
 +
 +2003-01-09  Geoffrey Keating  <geoffk@apple.com>
 +
 +      * src/powerpc/ffi_darwin.c: Remove RCS version string.
 +      * src/powerpc/darwin.S: Remove RCS version string.
 +
 +2003-01-03  Jeff Sturm  <jsturm@one-point.com>
 +
 +      * include/ffi.h.in: Add closure defines for SPARC, SPARC64.
 +      * src/ffitest.c (main): Use static storage for closure.
 +      * src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New.
 +      * src/sparc/v8.S (ffi_closure_v8): New.
 +      * src/sparc/v9.S (ffi_closure_v9): New.
 +
 +2002-11-10  Ranjit Mathew <rmathew@hotmail.com>
 +
 +      * include/ffi.h.in: Added FFI_STDCALL ffi_type
 +        enumeration for X86_WIN32.
 +      * src/x86/win32.S: Added ffi_call_STDCALL function
 +        definition.
 +      * src/x86/ffi.c (ffi_call/ffi_raw_call): Added
 +        switch cases for recognising FFI_STDCALL and
 +        calling ffi_call_STDCALL if target is X86_WIN32.
 +      * src/ffitest.c (my_stdcall_strlen/stdcall_many):
 +        stdcall versions of the "my_strlen" and "many"
 +        test functions (for X86_WIN32).
 +        Added test cases to test stdcall invocation using
 +        these functions.
 +
 +2002-12-02  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * src/sh/sysv.S: Add DWARF2 unwind info.
 +
 +2002-11-27  Ulrich Weigand  <uweigand@de.ibm.com>
 +
 +      * src/s390/sysv.S (.eh_frame section): Make section read-only.
 +
 +2002-11-26  Jim Wilson  <wilson@redhat.com>
 +
 +      * src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64.
 +
 +2002-11-23  H.J. Lu <hjl@gnu.org>
 +
 +      * acinclude.m4: Add dummy AM_PROG_LIBTOOL.
 +      Include ../config/accross.m4.
 +      * aclocal.m4; Rebuild.
 +      * configure: Likewise.
 +
 +2002-11-15  Ulrich Weigand  <uweigand@de.ibm.com>
 +
 +      * src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding.
 +
 +2002-11-11  DJ Delorie  <dj@redhat.com>
 +
 +      * configure.in: Look for common files in the right place.
 +
 +2002-10-08  Ulrich Weigand  <uweigand@de.ibm.com>
 +
 +      * src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret
 +      raw data as _Jv_word values, not ffi_raw.
 +      (ffi_java_ptrarray_to_raw): Likewise.
 +      (ffi_java_rvalue_to_raw): New function.
 +      (ffi_java_raw_call): Call it.
 +      (ffi_java_raw_to_rvalue): New function.
 +      (ffi_java_translate_args): Call it.
 +      * src/ffitest.c (closure_test_fn): Interpret return value
 +      as ffi_arg, not int.
 +      * src/s390/ffi.c (ffi_prep_cif_machdep): Add missing
 +      FFI_TYPE_POINTER case.
 +      (ffi_closure_helper_SYSV): Likewise.  Also, assume return
 +      values extended to word size.
 +
 +2002-10-02  Andreas Jaeger  <aj@suse.de>
 +
 +      * src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output.
 +
 +2002-10-01  Bo Thorsen  <bo@smetana.suse.de>
 +
 +      * include/ffi.h.in: Fix i386 win32 compilation.
 +
 +2002-09-30  Ulrich Weigand  <uweigand@de.ibm.com>
 +
 +      * configure.in: Add s390x-*-linux-* target.
 +      * configure: Regenerate.
 +      * include/ffi.h.in: Define S390X for s390x targets.
 +      (FFI_CLOSURES): Define for s390/s390x.
 +      (FFI_TRAMPOLINE_SIZE): Likewise.
 +      (FFI_NATIVE_RAW_API): Likewise.
 +      * src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390.
 +      * src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x.
 +      * src/s390/ffi.c: Major rework of existing code.  Add support for
 +      s390x targets.  Add closure support.
 +      * src/s390/sysv.S: Likewise.
 +
 +2002-09-29  Richard Earnshaw  <rearnsha@arm.com>
 +
 +      * src/arm/sysv.S: Fix typo.
 +
 +2002-09-28  Richard Earnshaw  <rearnsha@arm.com>
 +
 +      * src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor
 +      has defined __USER_LABEL_PREFIX__, then use it in CNAME.
 +      (ffi_call_SYSV): Handle soft-float.
 +
 +2002-09-27  Bo Thorsen  <bo@suse.de>
 +
 +      * include/ffi.h.in: Fix multilib x86-64 support.
 +
 +2002-09-22  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 +
 +      * Makefile.am (all-multi): Fix multilib parallel build.
 +
 +2002-07-19  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * configure.in (sh[34]*-*-linux*): Add brackets.
 +      * configure: Regenerate.
 +
 +2002-07-18  Kaz Kojima  <kkojima@gcc.gnu.org>
 +
 +      * Makefile.am: Add SH support.
 +      * Makefile.in: Regenerate.
 +      * configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target.
 +      * configure: Regenerate.
 +      * include/ffi.h.in: Add SH support.
 +      * src/sh/ffi.c: New file.
 +      * src/sh/sysv.S: New file.
 +      * src/types.c: Add SH support.
 +
 +2002-07-16  Bo Thorsen  <bo@suse.de>
 +
 +      * src/x86/ffi64.c: New file that adds x86-64 support.
 +      * src/x86/unix64.S: New file that handles argument setup for
 +      x86-64.
 +      * src/x86/sysv.S: Don't use this on x86-64.
 +      * src/x86/ffi.c: Don't use this on x86-64.
 +      Remove unused vars.
 +      * src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation
 +      for x86-64.
 +      * src/ffitest.c (struct6): New test that tests a special case in
 +      the x86-64 ABI.
 +      (struct7): Likewise.
 +      (struct8): Likewise.
 +      (struct9): Likewise.
 +      (closure_test_fn): Silence warning about this when it's not used.
 +      (main): Add the new tests.
 +      (main): Fix a couple of wrong casts and silence some compiler warnings.
 +      * include/ffi.h.in: Add x86-64 ABI definition.
 +      * fficonfig.h.in: Regenerate.
 +      * Makefile.am: Add x86-64 support.
 +      * configure.in: Likewise.
 +      * Makefile.in: Regenerate.
 +      * configure: Likewise.
 +
 +2002-06-24  Bo Thorsen  <bo@suse.de>
 +
 +      * src/types.c: Merge settings for similar architectures.
 +      Add x86-64 sizes and alignments.
 +
 +2002-06-23  Bo Thorsen  <bo@suse.de>
 +
 +      * src/arm/ffi.c (ffi_prep_args): Remove unused vars.
 +      * src/sparc/ffi.c (ffi_prep_args_v8): Likewise.
 +      * src/mips/ffi.c (ffi_prep_args): Likewise.
 +      * src/m68k/ffi.c (ffi_prep_args): Likewise.
 +
 +2002-07-18  H.J. Lu  (hjl@gnu.org)
 +
 +      * Makefile.am (TARGET_SRC_MIPS_LINUX): New.
 +      (libffi_la_SOURCES): Support MIPS_LINUX.
 +      (libffi_convenience_la_SOURCES): Likewise.
 +      * Makefile.in: Regenerated.
 +
 +      * configure.in (mips64*-*): Skip.
 +      (mips*-*-linux*): New.
 +      * configure: Regenerated.
 +
 +      * src/mips/ffi.c: Include <sgidefs.h>.
 +
 +2002-06-06  Ulrich Weigand  <uweigand@de.ibm.com>
 +
 +      * src/s390/sysv.S: Save/restore %r6.  Add DWARF-2 unwind info.
 +
 +2002-05-27  Roger Sayle  <roger@eyesopen.com>
 +
 +      * src/x86/ffi.c (ffi_prep_args): Remove reference to avn.
 +
 +2002-05-27  Bo Thorsen  <bo@suse.de>
 +
 +      * src/x86/ffi.c (ffi_prep_args): Remove unused variable and
 +      fix formatting.
 +
 +2002-05-13  Andreas Tobler  <a.tobler@schweiz.ch>
 +
 +      * src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at
 +      beginning of function (for older apple cc).
 +
 +2002-05-08  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at
 +      script entry, and set LD to it when configuring multilibs.
 +      * configure: Rebuilt.
 +
 +2002-05-05  Jason Thorpe  <thorpej@wasabisystems.com>
 +
 +      * configure.in (sparc64-*-netbsd*): Add target.
 +      (sparc-*-netbsdelf*): Likewise.
 +      * configure: Regenerate.
 +
 +2002-04-28  David S. Miller  <davem@redhat.com>
 +
 +      * configure.in, configure: Fix SPARC test in previous change.
 +
 +2002-04-29  Gerhard Tonn  <GerhardTonn@swol.de>
 +
 +      * Makefile.am: Add Linux for S/390 support.
 +      * Makefile.in: Regenerate.
 +      * configure.in: Add Linux for S/390 support.
 +      * configure: Regenerate.
 +      * include/ffi.h.in: Add Linux for S/390 support.
 +      * src/s390/ffi.c: New file from libffi CVS tree.
 +      * src/s390/sysv.S: New file from libffi CVS tree.
 +
 +2002-04-28  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working
 +      %r_disp32().
 +      * src/sparc/v8.S: Use it.
 +      * src/sparc/v9.S: Likewise.
 +      * fficonfig.h.in: Rebuilt.
 +      * configure: Rebuilt.
 +
 +2002-04-08  Hans Boehm  <Hans_Boehm@hp.com>
 +
 +      * src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE
 +      correctly.
 +      * src/ia64/unix.S: Add unwind information. Fix comments.
 +      Save sp in a way that's compatible with unwind info.
 +      (ffi_call_unix): Correctly restore sp in all cases.
 +      * src/ia64/ffi.c: Add, fix comments.
 +
 +2002-04-08  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * src/sparc/v8.S: Make .eh_frame dependent on target word size.
 +
 +2002-04-06  Jason Thorpe  <thorpej@wasabisystems.com>
 +
 +      * configure.in (alpha*-*-netbsd*): Add target.
 +      * configure: Regenerate.
 +
 +2002-04-04  Jeff Sturm  <jsturm@one-point.com>
 +
 +      * src/sparc/v8.S: Add unwind info.
 +      * src/sparc/v9.S: Likewise.
 +
 +2002-03-30  Krister Walfridsson  <cato@df.lth.se>
 +
 +      * configure.in: Enable i*86-*-netbsdelf*.
 +      * configure: Rebuilt.
 +
 +2002-03-29  David Billinghurst <David.Billinghurst@riotinto.com>
 +
 +      PR other/2620
 +      * src/mips/n32.s: Delete
 +      * src/mips/o32.s: Delete
 +
 +2002-03-21  Loren J. Rittle  <ljrittle@acm.org>
 +
 +      * configure.in: Enable alpha*-*-freebsd*.
 +      * configure: Rebuilt.
 +
 +2002-03-17  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>
 +
 +      * Makefile.am: libfficonvenience -> libffi_convenience.
 +      * Makefile.in: Rebuilt.
 +
 +      * Makefile.am: Define ffitest_OBJECTS.
 +      * Makefile.in: Rebuilt.
 +
 +2002-03-07  Andreas Tobler  <toa@pop.agri.ch>
 +          David Edelsohn  <edelsohn@gnu.org>
 +
 +      * Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files.
 +      (TARGET_SRC_POWERPC_AIX): Add aix_closure.S.
 +      (TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S.
 +      * Makefile.in: Regenerate.
 +      * include/ffi.h.in: Add AIX and Darwin closure definitions.
 +      * src/powerpc/ffi_darwin.c (ffi_prep_closure): New function.
 +      (flush_icache, flush_range): New functions.
 +      (ffi_closure_helper_DARWIN): New function.
 +      * src/powerpc/aix_closure.S: New file.
 +      * src/powerpc/darwin_closure.S: New file.
 +
 +2002-02-24  Jeff Sturm  <jsturm@one-point.com>
 +
 +      * include/ffi.h.in: Add typedef for ffi_arg.
 +      * src/ffitest.c (main): Declare rint with ffi_arg.
 +
 +2002-02-21  Andreas Tobler  <toa@pop.agri.ch>
 +
 +      * src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate
 +      number of GPRs for floating-point arguments.
 +
 +2002-01-31  Anthony Green  <green@redhat.com>
 +
 +      * configure: Rebuilt.
 +      * configure.in: Replace CHECK_SIZEOF and endian tests with
 +      cross-compiler friendly macros.
 +      * aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New
 +      macros.
 +
 +2002-01-18  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * src/powerpc/darwin.S (_ffi_call_AIX): New.
 +      * src/powerpc/aix.S (ffi_call_DARWIN): New.
 +
 +2002-01-17  David Edelsohn  <edelsohn@gnu.org>
 +
 +      * Makefile.am (EXTRA_DIST): Add Darwin and AIX files.
 +      (TARGET_SRC_POWERPC_AIX): New.
 +      (POWERPC_AIX): New stanza.
 +      * Makefile.in: Regenerate.
 +      * configure.in: Add AIX case.
 +      * configure: Regenerate.
 +      * include/ffi.h.in (ffi_abi): Add FFI_AIX.
 +      * src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame
 +      size.  Fix "long double" support.
 +      (ffi_call): Add FFI_AIX case.
 +      * src/powerpc/aix.S: New.
 +
 +2001-10-09  John Hornkvist  <john@toastedmarshmallow.com>
 +
 +      Implement Darwin PowerPC ABI.
 +      * configure.in: Handle powerpc-*-darwin*.
 +      * Makefile.am: Set source files for POWERPC_DARWIN.
 +      * configure: Rebuilt.
 +      * Makefile.in: Rebuilt.
 +      * include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for
 +      POWERPC_DARWIN.
 +      * src/powerpc/darwin.S: New file.
 +      * src/powerpc/ffi_darwin.c: New file.
 +
 +2001-10-07  Joseph S. Myers  <jsm28@cam.ac.uk>
 +
 +      * src/x86/ffi.c: Fix spelling error of "separate" as "seperate".
 +
 +2001-07-16  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * src/x86/sysv.S: Avoid gas-only .balign directive.
 +      Use C style comments.
 +
 +2001-07-16  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic.
 +      Fixes PR bootstrap/3563.
 +
 +2001-06-26  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF.
 +
 +2001-06-25  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 +
 +      * configure.in: Recognize sparc*-sun-* host.
 +      * configure: Regenerate.
 +
 +2001-06-06  Andrew Haley  <aph@redhat.com>
 +
 +      * src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF.
 +
 +2001-06-03  Andrew Haley  <aph@redhat.com>
 +
 +      * src/alpha/osf.S: Add unwind info.
 +      * src/powerpc/sysv.S: Add unwind info.
 +      * src/powerpc/ppc_closure.S: Likewise.
 +
 +2000-05-31  Jeff Sturm  <jsturm@one-point.com>
 +
 +      * configure.in: Fix AC_ARG_ENABLE usage.
 +      * configure: Rebuilt.
 +
 +2001-05-06  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>
 +
 +      * configure.in: Remove warning about beta code.
 +      * configure: Rebuilt.
 +
 +2001-04-25  Hans Boehm <Hans_Boehm@hp.com>
 +
 +      * src/ia64/unix.S: Restore stack pointer when returning from
 +      ffi_closure_UNIX.
 +      * src/ia64/ffi.c: Fix typo in comment.
 +
 +2001-04-18  Jim Wilson  <wilson@redhat.com>
 +
 +      * src/ia64/unix.S: Delete unnecessary increment and decrement of loc2
 +      to eliminate RAW DV.
 +
 +2001-04-12  Bryce McKinlay  <bryce@albatross.co.nz>
 +
 +      * Makefile.am: Make a libtool convenience library.
 +      * Makefile.in: Rebuilt.
 +
 +2001-03-29  Bryce McKinlay  <bryce@albatross.co.nz>
 +
 +      * configure.in: Use different syntax for subdirectory creation.
 +      * configure: Rebuilt.
 +
 +2001-03-27  Jon Beniston  <jon@beniston.com>
 +
 +      * configure.in: Added X86_WIN32 target (Win32, CygWin, MingW).
 +      * configure: Rebuilt.
 +      * Makefile.am: Added X86_WIN32 target support.
 +      * Makefile.in: Rebuilt.
 +
 +      * include/ffi.h.in: Added X86_WIN32 target support.
 +
 +      * src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets.
 +      * src/types.c: Added X86_WIN32 target support.
 +
 +      * src/x86/win32.S: New file. Based on sysv.S, but with EH
 +      stuff removed and made to work with CygWin's gas.
 +
 +2001-03-26  Bryce McKinlay  <bryce@albatross.co.nz>
 +
 +      * configure.in: Make target subdirectory in build dir.
 +      * Makefile.am: Override suffix based rules to specify correct output
 +      subdirectory.
 +      * Makefile.in: Rebuilt.
 +      * configure: Rebuilt.
 +
 +2001-03-23  Kevin B Hendricks  <khendricks@ivey.uwo.ca>
 +
 +      * src/powerpc/ppc_closure.S: New file.
 +      * src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug
 +      involving long long and register pairs.
 +      (ffi_prep_closure): New function.
 +      (flush_icache): Likewise.
 +      (ffi_closure_helper_SYSV): Likewise.
 +      * include/ffi.h.in (FFI_CLOSURES): Define on PPC.
 +      (FFI_TRAMPOLINE_SIZE): Likewise.
 +      (FFI_NATIVE_RAW_API): Likewise.
 +      * Makefile.in: Rebuilt.
 +      * Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S.
 +      (TARGET_SRC_POWERPC): Likewise.
 +
 +2001-03-19  Tom Tromey  <tromey@redhat.com>
 +
 +      * Makefile.in: Rebuilt.
 +      * Makefile.am (ffitest_LDFLAGS): New macro.
 +
 +2001-03-02  Nick Clifton  <nickc@redhat.com>
 +
 +      * include/ffi.h.in: Remove RCS ident string.
 +      * include/ffi_mips.h: Remove RCS ident string.
 +      * src/debug.c: Remove RCS ident string.
 +      * src/ffitest.c: Remove RCS ident string.
 +      * src/prep_cif.c: Remove RCS ident string.
 +      * src/types.c: Remove RCS ident string.
 +      * src/alpha/ffi.c: Remove RCS ident string.
 +      * src/alpha/osf.S: Remove RCS ident string.
 +      * src/arm/ffi.c: Remove RCS ident string.
 +      * src/arm/sysv.S: Remove RCS ident string.
 +      * src/mips/ffi.c: Remove RCS ident string.
 +      * src/mips/n32.S: Remove RCS ident string.
 +      * src/mips/o32.S: Remove RCS ident string.
 +      * src/sparc/ffi.c: Remove RCS ident string.
 +      * src/sparc/v8.S: Remove RCS ident string.
 +      * src/sparc/v9.S: Remove RCS ident string.
 +      * src/x86/ffi.c: Remove RCS ident string.
 +      * src/x86/sysv.S: Remove RCS ident string.
 +
 +2001-02-08  Joseph S. Myers  <jsm28@cam.ac.uk>
 +
 +      * include/ffi.h.in: Change sourceware.cygnus.com references to
 +      gcc.gnu.org.
 +
 +2000-12-09  Richard Henderson  <rth@redhat.com>
 +
 +      * src/alpha/ffi.c (ffi_call): Simplify struct return test.
 +      (ffi_closure_osf_inner): Index rather than increment avalue
 +      and arg_types.  Give ffi_closure_osf the raw return value type.
 +      * src/alpha/osf.S (ffi_closure_osf): Handle return value type
 +      promotion.
 +
 +2000-12-07  Richard Henderson  <rth@redhat.com>
 +
 +      * src/raw_api.c (ffi_translate_args): Fix typo.
 +      (ffi_prep_closure): Likewise.
 +
 +      * include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and
 +      FFI_TRAMPOLINE_SIZE.
 +      * src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal
 +      cif->bytes for new ffi_call_osf implementation.
 +      (ffi_prep_args): Absorb into ...
 +      (ffi_call): ... here.  Do all stack allocation here and
 +      avoid a callback function.
 +      (ffi_prep_closure, ffi_closure_osf_inner): New.
 +      * src/alpha/osf.S (ffi_call_osf): Reimplement with no callback.
 +      (ffi_closure_osf): New.
 +
 +2000-09-10  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * config.guess, config.sub, install-sh: Removed.
 +      * ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise.
 +      * Makefile.in: Rebuilt.
 +
 +      * acinclude.m4: Include libtool macros from the top level.
 +      * aclocal.m4, configure: Rebuilt.
 +
 +2000-08-22  Alexandre Oliva  <aoliva@redhat.com>
 +
 +      * configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set.
 +      * configure: Rebuilt.
 +
 +2000-05-11  Scott Bambrough  <scottb@netwinder.org>
 +
 +      * libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to
 +      memory correctly.  Use conditional instructions, not branches where
 +      possible.
 +
 +2000-05-04  Tom Tromey  <tromey@cygnus.com>
 +
 +      * configure: Rebuilt.
 +      * configure.in: Match `arm*-*-linux-*'.
 +      From Chris Dornan <cdornan@arm.com>.
 +
 +2000-04-28  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * Makefile.am (SUBDIRS): Define.
 +      (AM_MAKEFLAGS): Likewise.
 +      (Multilib support.): Add section.
 +      * Makefile.in: Rebuilt.
 +      * ltconfig (extra_compiler_flags, extra_compiler_flags_value):
 +      New variables. Set for gcc using -print-multi-lib. Export them
 +      to libtool.
 +      (sparc64-*-linux-gnu*): Use libsuff 64 for search paths.
 +      * ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options
 +      for -shared links.
 +      (extra_compiler_flags_value, extra_compiler_flags): Check these
 +      for extra compiler options which need to be passed down in
 +      compiler_flags.
 +
 +2000-04-16  Anthony Green  <green@redhat.com>
 +
 +      * configure: Rebuilt.
 +      * configure.in: Change i*86-pc-linux* to i*86-*-linux*.
 +
 +2000-04-14  Jakub Jelinek  <jakub@redhat.com>
 +
 +      * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds.
 +      Set SPARC FFI_DEFAULT_ABI based on SPARC64 define.
 +      * src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args.
 +      Replace all void * sizeofs with sizeof(int).
 +      Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is
 +      different than DOUBLE.
 +      Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere).
 +      (ffi_prep_args_v9): New function.
 +      (ffi_prep_cif_machdep): Handle V9 ABI and long long on V8.
 +      (ffi_V9_return_struct): New function.
 +      (ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from
 +      32bit code (not yet cross-arch calls).
 +      * src/sparc/v8.S: Add struct return delay nop.
 +      Handle long long.
 +      * src/sparc/v9.S: New file.
 +      * src/prep_cif.c (ffi_prep_cif): Return structure pointer
 +      is used on sparc64 only for structures larger than 32 bytes.
 +      Pass by reference for structures is done for structure arguments
 +      larger than 16 bytes.
 +      * src/ffitest.c (main): Use 64bit rint on sparc64.
 +      Run long long tests on sparc.
 +      * src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and
 +      sparc64.
 +      (FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits
 +      on sparc64.
 +      * configure.in (sparc-*-linux*): New supported target.
 +      (sparc64-*-linux*): Likewise.
 +      * configure: Rebuilt.
 +      * Makefile.am: Add v9.S to SPARC files.
 +      * Makefile.in: Likewise.
 +      (LINK): Surround $(CCLD) into double quotes, so that multilib
 +      compiles work correctly.
 +
 +2000-04-04  Alexandre Petit-Bianco  <apbianco@cygnus.com>
 +
 +      * configure: Rebuilt.
 +      * configure.in: (i*86-*-solaris*): New libffi target. Patch
 +      proposed by Bryce McKinlay.
 +
 +2000-03-20  Tom Tromey  <tromey@cygnus.com>
 +
 +      * Makefile.in: Hand edit for java_raw_api.lo.
 +
 +2000-03-08  Bryce McKinlay  <bryce@albatross.co.nz>
 +
 +      * config.guess, config.sub: Update from the gcc tree.
 +      Fix for PR libgcj/168.
 +
 +2000-03-03  Tom Tromey  <tromey@cygnus.com>
 +
 +      * Makefile.in: Fixed ia64 by hand.
 +
 +      * configure: Rebuilt.
 +      * configure.in (--enable-multilib): New option.
 +      (libffi_basedir): New subst.
 +      (AC_OUTPUT): Added multilib code.
 +
 +2000-03-02  Tom Tromey  <tromey@cygnus.com>
 +
 +      * Makefile.in: Rebuilt.
 +      * Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as
 +      directory name.
 +
 +2000-02-25  Hans Boehm <boehm@acm.org>
 +
 +      * src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New
 +      files.
 +      * src/raw_api.c (ffi_translate_args): Fixed typo in argument
 +      list.
 +      (ffi_prep_raw_closure): Use ffi_translate_args, not
 +      ffi_closure_translate.
 +      * src/java_raw_api.c: New file.
 +      * src/ffitest.c (closure_test_fn): New function.
 +      (main): Define `rint' as long long on IA64.  Added new test when
 +      FFI_CLOSURES is defined.
 +      * include/ffi.h.in (ALIGN): Use size_t, not unsigned.
 +      (ffi_abi): Recognize IA64.
 +      (ffi_raw): Added `flt' field.
 +      Added "Java raw API" code.
 +      * configure.in: Recognize ia64.
 +      * Makefile.am (TARGET_SRC_IA64): New macro.
 +      (libffi_la_common_SOURCES): Added java_raw_api.c.
 +      (libffi_la_SOURCES): Define in IA64 case.
 +
 +2000-01-04  Tom Tromey  <tromey@cygnus.com>
 +
 +      * Makefile.in: Rebuilt with newer automake.
 +
 +1999-12-31  Tom Tromey  <tromey@cygnus.com>
 +
 +      * Makefile.am (INCLUDES): Added -I$(top_srcdir)/src.
 +
 +1999-09-01  Tom Tromey  <tromey@cygnus.com>
 +
 +      * include/ffi.h.in: Removed PACKAGE and VERSION defines and
 +      undefs.
 +      * fficonfig.h.in: Rebuilt.
 +      * configure: Rebuilt.
 +      * configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE.
 +      Use AM_PROG_LIBTOOL (automake 1.4 compatibility).
 +      * acconfig.h: Don't #undef PACKAGE or VERSION.
 +
 +1999-08-09  Anthony Green  <green@cygnus.com>
 +
 +      * include/ffi.h.in: Try to work around messy header problem
 +      with PACKAGE and VERSION.
 +
 +      * configure: Rebuilt.
 +      * configure.in: Change version to 2.00-beta.
 +
 +      * fficonfig.h.in: Rebuilt.
 +      * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define.
 +
 +      * src/x86/ffi.c (ffi_raw_call): Rename.
 +
 +1999-08-02  Kresten Krab Thorup  <krab@dominiq.is.s.u-tokyo.ac.jp>
 +
 +      * src/x86/ffi.c (ffi_closure_SYSV): New function.
 +      (ffi_prep_incoming_args_SYSV): Ditto.
 +      (ffi_prep_closure): Ditto.
 +      (ffi_closure_raw_SYSV): Ditto.
 +      (ffi_prep_raw_closure): More ditto.
 +      (ffi_call_raw): Final ditto.
 +
 +      * include/ffi.h.in: Add definitions for closure and raw API.
 +
 +      * src/x86/ffi.c (ffi_prep_cif_machdep): Added case for
 +      FFI_TYPE_UINT64.
 +
 +      * Makefile.am (libffi_la_common_SOURCES): Added raw_api.c
 +
 +      * src/raw_api.c: New file.
 +
 +      * include/ffi.h.in (ffi_raw): New type.
 +      (UINT_ARG, SINT_ARG): New defines.
 +      (ffi_closure, ffi_raw_closure): New types.
 +      (ffi_prep_closure, ffi_prep_raw_closure): New declarations.
 +
 +      * configure.in: Add check for endianness and sizeof void*.
 +
 +      * src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument,
 +      instead of directly.
 +
 +      * configure: Rebuilt.
 +
 +Thu Jul  8 14:28:42 1999  Anthony Green  <green@cygnus.com>
 +
 +      * configure.in: Add x86 and powerpc BeOS configurations.
 +      From Makoto Kato <m_kato@ga2.so-net.ne.jp>.
 +
 +1999-05-09  Anthony Green  <green@cygnus.com>
 +
 +      * configure.in: Add warning about this being beta code.
 +      Remove src/Makefile.am from the picture.
 +      * configure: Rebuilt.
 +
 +      * Makefile.am: Move logic from src/Makefile.am.  Add changes
 +      to support libffi as a target library.
 +      * Makefile.in: Rebuilt.
 +
 +      * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh:
 +      Upgraded to new autoconf, automake, libtool.
 +
 +      * README: Tweaks.
 +
 +      * LICENSE: Update copyright date.
 +
 +      * src/Makefile.am, src/Makefile.in: Removed.
 +
 +1998-11-29  Anthony Green  <green@cygnus.com>
 +
 +      * include/ChangeLog: Removed.
 +      * src/ChangeLog: Removed.
 +      * src/mips/ChangeLog: Removed.
 +      * src/sparc/ChangeLog: Remboved.
 +      * src/x86/ChangeLog: Removed.
 +
 +      * ChangeLog.v1: Created.
index 783c5c2a6f978852200a8a9d307c11b40761d579,0000000000000000000000000000000000000000..72673a1bc7422fa899938759c0b425c77d230b80
mode 100644,000000..100644
--- /dev/null
@@@ -1,5099 -1,0 +1,5099 @@@
- /* This function supports releasing coalesed segments */
 +/*
 +  This is a version (aka dlmalloc) of malloc/free/realloc written by
 +  Doug Lea and released to the public domain, as explained at
 +  http://creativecommons.org/licenses/publicdomain.  Send questions,
 +  comments, complaints, performance data, etc to dl@cs.oswego.edu
 +
 +* Version 2.8.3 Thu Sep 22 11:16:15 2005  Doug Lea  (dl at gee)
 +
 +   Note: There may be an updated version of this malloc obtainable at
 +           ftp://gee.cs.oswego.edu/pub/misc/malloc.c
 +         Check before installing!
 +
 +* Quickstart
 +
 +  This library is all in one file to simplify the most common usage:
 +  ftp it, compile it (-O3), and link it into another program. All of
 +  the compile-time options default to reasonable values for use on
 +  most platforms.  You might later want to step through various
 +  compile-time and dynamic tuning options.
 +
 +  For convenience, an include file for code using this malloc is at:
 +     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h
 +  You don't really need this .h file unless you call functions not
 +  defined in your system include files.  The .h file contains only the
 +  excerpts from this file needed for using this malloc on ANSI C/C++
 +  systems, so long as you haven't changed compile-time options about
 +  naming and tuning parameters.  If you do, then you can create your
 +  own malloc.h that does include all settings by cutting at the point
 +  indicated below. Note that you may already by default be using a C
 +  library containing a malloc that is based on some version of this
 +  malloc (for example in linux). You might still want to use the one
 +  in this file to customize settings or to avoid overheads associated
 +  with library versions.
 +
 +* Vital statistics:
 +
 +  Supported pointer/size_t representation:       4 or 8 bytes
 +       size_t MUST be an unsigned type of the same width as
 +       pointers. (If you are using an ancient system that declares
 +       size_t as a signed type, or need it to be a different width
 +       than pointers, you can use a previous release of this malloc
 +       (e.g. 2.7.2) supporting these.)
 +
 +  Alignment:                                     8 bytes (default)
 +       This suffices for nearly all current machines and C compilers.
 +       However, you can define MALLOC_ALIGNMENT to be wider than this
 +       if necessary (up to 128bytes), at the expense of using more space.
 +
 +  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)
 +                                          8 or 16 bytes (if 8byte sizes)
 +       Each malloced chunk has a hidden word of overhead holding size
 +       and status information, and additional cross-check word
 +       if FOOTERS is defined.
 +
 +  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)
 +                          8-byte ptrs:  32 bytes    (including overhead)
 +
 +       Even a request for zero bytes (i.e., malloc(0)) returns a
 +       pointer to something of the minimum allocatable size.
 +       The maximum overhead wastage (i.e., number of extra bytes
 +       allocated than were requested in malloc) is less than or equal
 +       to the minimum size, except for requests >= mmap_threshold that
 +       are serviced via mmap(), where the worst case wastage is about
 +       32 bytes plus the remainder from a system page (the minimal
 +       mmap unit); typically 4096 or 8192 bytes.
 +
 +  Security: static-safe; optionally more or less
 +       The "security" of malloc refers to the ability of malicious
 +       code to accentuate the effects of errors (for example, freeing
 +       space that is not currently malloc'ed or overwriting past the
 +       ends of chunks) in code that calls malloc.  This malloc
 +       guarantees not to modify any memory locations below the base of
 +       heap, i.e., static variables, even in the presence of usage
 +       errors.  The routines additionally detect most improper frees
 +       and reallocs.  All this holds as long as the static bookkeeping
 +       for malloc itself is not corrupted by some other means.  This
 +       is only one aspect of security -- these checks do not, and
 +       cannot, detect all possible programming errors.
 +
 +       If FOOTERS is defined nonzero, then each allocated chunk
 +       carries an additional check word to verify that it was malloced
 +       from its space.  These check words are the same within each
 +       execution of a program using malloc, but differ across
 +       executions, so externally crafted fake chunks cannot be
 +       freed. This improves security by rejecting frees/reallocs that
 +       could corrupt heap memory, in addition to the checks preventing
 +       writes to statics that are always on.  This may further improve
 +       security at the expense of time and space overhead.  (Note that
 +       FOOTERS may also be worth using with MSPACES.)
 +
 +       By default detected errors cause the program to abort (calling
 +       "abort()"). You can override this to instead proceed past
 +       errors by defining PROCEED_ON_ERROR.  In this case, a bad free
 +       has no effect, and a malloc that encounters a bad address
 +       caused by user overwrites will ignore the bad address by
 +       dropping pointers and indices to all known memory. This may
 +       be appropriate for programs that should continue if at all
 +       possible in the face of programming errors, although they may
 +       run out of memory because dropped memory is never reclaimed.
 +
 +       If you don't like either of these options, you can define
 +       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
 +       else. And if if you are sure that your program using malloc has
 +       no errors or vulnerabilities, you can define INSECURE to 1,
 +       which might (or might not) provide a small performance improvement.
 +
 +  Thread-safety: NOT thread-safe unless USE_LOCKS defined
 +       When USE_LOCKS is defined, each public call to malloc, free,
 +       etc is surrounded with either a pthread mutex or a win32
 +       spinlock (depending on WIN32). This is not especially fast, and
 +       can be a major bottleneck.  It is designed only to provide
 +       minimal protection in concurrent environments, and to provide a
 +       basis for extensions.  If you are using malloc in a concurrent
 +       program, consider instead using ptmalloc, which is derived from
 +       a version of this malloc. (See http://www.malloc.de).
 +
 +  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
 +       This malloc can use unix sbrk or any emulation (invoked using
 +       the CALL_MORECORE macro) and/or mmap/munmap or any emulation
 +       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
 +       memory.  On most unix systems, it tends to work best if both
 +       MORECORE and MMAP are enabled.  On Win32, it uses emulations
 +       based on VirtualAlloc. It also uses common C library functions
 +       like memset.
 +
 +  Compliance: I believe it is compliant with the Single Unix Specification
 +       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
 +       others as well.
 +
 +* Overview of algorithms
 +
 +  This is not the fastest, most space-conserving, most portable, or
 +  most tunable malloc ever written. However it is among the fastest
 +  while also being among the most space-conserving, portable and
 +  tunable.  Consistent balance across these factors results in a good
 +  general-purpose allocator for malloc-intensive programs.
 +
 +  In most ways, this malloc is a best-fit allocator. Generally, it
 +  chooses the best-fitting existing chunk for a request, with ties
 +  broken in approximately least-recently-used order. (This strategy
 +  normally maintains low fragmentation.) However, for requests less
 +  than 256bytes, it deviates from best-fit when there is not an
 +  exactly fitting available chunk by preferring to use space adjacent
 +  to that used for the previous small request, as well as by breaking
 +  ties in approximately most-recently-used order. (These enhance
 +  locality of series of small allocations.)  And for very large requests
 +  (>= 256Kb by default), it relies on system memory mapping
 +  facilities, if supported.  (This helps avoid carrying around and
 +  possibly fragmenting memory used only for large chunks.)
 +
 +  All operations (except malloc_stats and mallinfo) have execution
 +  times that are bounded by a constant factor of the number of bits in
 +  a size_t, not counting any clearing in calloc or copying in realloc,
 +  or actions surrounding MORECORE and MMAP that have times
 +  proportional to the number of non-contiguous regions returned by
 +  system allocation routines, which is often just 1.
 +
 +  The implementation is not very modular and seriously overuses
 +  macros. Perhaps someday all C compilers will do as good a job
 +  inlining modular code as can now be done by brute-force expansion,
 +  but now, enough of them seem not to.
 +
 +  Some compilers issue a lot of warnings about code that is
 +  dead/unreachable only on some platforms, and also about intentional
 +  uses of negation on unsigned types. All known cases of each can be
 +  ignored.
 +
 +  For a longer but out of date high-level description, see
 +     http://gee.cs.oswego.edu/dl/html/malloc.html
 +
 +* MSPACES
 +  If MSPACES is defined, then in addition to malloc, free, etc.,
 +  this file also defines mspace_malloc, mspace_free, etc. These
 +  are versions of malloc routines that take an "mspace" argument
 +  obtained using create_mspace, to control all internal bookkeeping.
 +  If ONLY_MSPACES is defined, only these versions are compiled.
 +  So if you would like to use this allocator for only some allocations,
 +  and your system malloc for others, you can compile with
 +  ONLY_MSPACES and then do something like...
 +    static mspace mymspace = create_mspace(0,0); // for example
 +    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)
 +
 +  (Note: If you only need one instance of an mspace, you can instead
 +  use "USE_DL_PREFIX" to relabel the global malloc.)
 +
 +  You can similarly create thread-local allocators by storing
 +  mspaces as thread-locals. For example:
 +    static __thread mspace tlms = 0;
 +    void*  tlmalloc(size_t bytes) {
 +      if (tlms == 0) tlms = create_mspace(0, 0);
 +      return mspace_malloc(tlms, bytes);
 +    }
 +    void  tlfree(void* mem) { mspace_free(tlms, mem); }
 +
 +  Unless FOOTERS is defined, each mspace is completely independent.
 +  You cannot allocate from one and free to another (although
 +  conformance is only weakly checked, so usage errors are not always
 +  caught). If FOOTERS is defined, then each chunk carries around a tag
 +  indicating its originating mspace, and frees are directed to their
 +  originating spaces.
 +
 + -------------------------  Compile-time options ---------------------------
 +
 +Be careful in setting #define values for numerical constants of type
 +size_t. On some systems, literal values are not automatically extended
 +to size_t precision unless they are explicitly casted.
 +
 +WIN32                    default: defined if _WIN32 defined
 +  Defining WIN32 sets up defaults for MS environment and compilers.
 +  Otherwise defaults are for unix.
 +
 +MALLOC_ALIGNMENT         default: (size_t)8
 +  Controls the minimum alignment for malloc'ed chunks.  It must be a
 +  power of two and at least 8, even on machines for which smaller
 +  alignments would suffice. It may be defined as larger than this
 +  though. Note however that code and data structures are optimized for
 +  the case of 8-byte alignment.
 +
 +MSPACES                  default: 0 (false)
 +  If true, compile in support for independent allocation spaces.
 +  This is only supported if HAVE_MMAP is true.
 +
 +ONLY_MSPACES             default: 0 (false)
 +  If true, only compile in mspace versions, not regular versions.
 +
 +USE_LOCKS                default: 0 (false)
 +  Causes each call to each public routine to be surrounded with
 +  pthread or WIN32 mutex lock/unlock. (If set true, this can be
 +  overridden on a per-mspace basis for mspace versions.)
 +
 +FOOTERS                  default: 0
 +  If true, provide extra checking and dispatching by placing
 +  information in the footers of allocated chunks. This adds
 +  space and time overhead.
 +
 +INSECURE                 default: 0
 +  If true, omit checks for usage errors and heap space overwrites.
 +
 +USE_DL_PREFIX            default: NOT defined
 +  Causes compiler to prefix all public routines with the string 'dl'.
 +  This can be useful when you only want to use this malloc in one part
 +  of a program, using your regular system malloc elsewhere.
 +
 +ABORT                    default: defined as abort()
 +  Defines how to abort on failed checks.  On most systems, a failed
 +  check cannot die with an "assert" or even print an informative
 +  message, because the underlying print routines in turn call malloc,
 +  which will fail again.  Generally, the best policy is to simply call
 +  abort(). It's not very useful to do more than this because many
 +  errors due to overwriting will show up as address faults (null, odd
 +  addresses etc) rather than malloc-triggered checks, so will also
 +  abort.  Also, most compilers know that abort() does not return, so
 +  can better optimize code conditionally calling it.
 +
 +PROCEED_ON_ERROR           default: defined as 0 (false)
 +  Controls whether detected bad addresses cause them to bypassed
 +  rather than aborting. If set, detected bad arguments to free and
 +  realloc are ignored. And all bookkeeping information is zeroed out
 +  upon a detected overwrite of freed heap space, thus losing the
 +  ability to ever return it from malloc again, but enabling the
 +  application to proceed. If PROCEED_ON_ERROR is defined, the
 +  static variable malloc_corruption_error_count is compiled in
 +  and can be examined to see if errors have occurred. This option
 +  generates slower code than the default abort policy.
 +
 +DEBUG                    default: NOT defined
 +  The DEBUG setting is mainly intended for people trying to modify
 +  this code or diagnose problems when porting to new platforms.
 +  However, it may also be able to better isolate user errors than just
 +  using runtime checks.  The assertions in the check routines spell
 +  out in more detail the assumptions and invariants underlying the
 +  algorithms.  The checking is fairly extensive, and will slow down
 +  execution noticeably. Calling malloc_stats or mallinfo with DEBUG
 +  set will attempt to check every non-mmapped allocated and free chunk
 +  in the course of computing the summaries.
 +
 +ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)
 +  Debugging assertion failures can be nearly impossible if your
 +  version of the assert macro causes malloc to be called, which will
 +  lead to a cascade of further failures, blowing the runtime stack.
 +  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
 +  which will usually make debugging easier.
 +
 +MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32
 +  The action to take before "return 0" when malloc fails to be able to
 +  return memory because there is none available.
 +
 +HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES
 +  True if this system supports sbrk or an emulation of it.
 +
 +MORECORE                  default: sbrk
 +  The name of the sbrk-style system routine to call to obtain more
 +  memory.  See below for guidance on writing custom MORECORE
 +  functions. The type of the argument to sbrk/MORECORE varies across
 +  systems.  It cannot be size_t, because it supports negative
 +  arguments, so it is normally the signed type of the same width as
 +  size_t (sometimes declared as "intptr_t").  It doesn't much matter
 +  though. Internally, we only call it with arguments less than half
 +  the max value of a size_t, which should work across all reasonable
 +  possibilities, although sometimes generating compiler warnings.  See
 +  near the end of this file for guidelines for creating a custom
 +  version of MORECORE.
 +
 +MORECORE_CONTIGUOUS       default: 1 (true)
 +  If true, take advantage of fact that consecutive calls to MORECORE
 +  with positive arguments always return contiguous increasing
 +  addresses.  This is true of unix sbrk. It does not hurt too much to
 +  set it true anyway, since malloc copes with non-contiguities.
 +  Setting it false when definitely non-contiguous saves time
 +  and possibly wasted space it would take to discover this though.
 +
 +MORECORE_CANNOT_TRIM      default: NOT defined
 +  True if MORECORE cannot release space back to the system when given
 +  negative arguments. This is generally necessary only if you are
 +  using a hand-crafted MORECORE function that cannot handle negative
 +  arguments.
 +
 +HAVE_MMAP                 default: 1 (true)
 +  True if this system supports mmap or an emulation of it.  If so, and
 +  HAVE_MORECORE is not true, MMAP is used for all system
 +  allocation. If set and HAVE_MORECORE is true as well, MMAP is
 +  primarily used to directly allocate very large blocks. It is also
 +  used as a backup strategy in cases where MORECORE fails to provide
 +  space from system. Note: A single call to MUNMAP is assumed to be
 +  able to unmap memory that may have be allocated using multiple calls
 +  to MMAP, so long as they are adjacent.
 +
 +HAVE_MREMAP               default: 1 on linux, else 0
 +  If true realloc() uses mremap() to re-allocate large blocks and
 +  extend or shrink allocation spaces.
 +
 +MMAP_CLEARS               default: 1 on unix
 +  True if mmap clears memory so calloc doesn't need to. This is true
 +  for standard unix mmap using /dev/zero.
 +
 +USE_BUILTIN_FFS            default: 0 (i.e., not used)
 +  Causes malloc to use the builtin ffs() function to compute indices.
 +  Some compilers may recognize and intrinsify ffs to be faster than the
 +  supplied C version. Also, the case of x86 using gcc is special-cased
 +  to an asm instruction, so is already as fast as it can be, and so
 +  this setting has no effect. (On most x86s, the asm version is only
 +  slightly faster than the C version.)
 +
 +malloc_getpagesize         default: derive from system includes, or 4096.
 +  The system page size. To the extent possible, this malloc manages
 +  memory from the system in page-size units.  This may be (and
 +  usually is) a function rather than a constant. This is ignored
 +  if WIN32, where page size is determined using getSystemInfo during
 +  initialization.
 +
 +USE_DEV_RANDOM             default: 0 (i.e., not used)
 +  Causes malloc to use /dev/random to initialize secure magic seed for
 +  stamping footers. Otherwise, the current time is used.
 +
 +NO_MALLINFO                default: 0
 +  If defined, don't compile "mallinfo". This can be a simple way
 +  of dealing with mismatches between system declarations and
 +  those in this file.
 +
 +MALLINFO_FIELD_TYPE        default: size_t
 +  The type of the fields in the mallinfo struct. This was originally
 +  defined as "int" in SVID etc, but is more usefully defined as
 +  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set
 +
 +REALLOC_ZERO_BYTES_FREES    default: not defined
 +  This should be set if a call to realloc with zero bytes should 
 +  be the same as a call to free. Some people think it should. Otherwise, 
 +  since this malloc returns a unique pointer for malloc(0), so does 
 +  realloc(p, 0).
 +
 +LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
 +LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H
 +LACKS_STDLIB_H                default: NOT defined unless on WIN32
 +  Define these if your system does not have these header files.
 +  You might need to manually insert some of the declarations they provide.
 +
 +DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,
 +                                system_info.dwAllocationGranularity in WIN32,
 +                                otherwise 64K.
 +      Also settable using mallopt(M_GRANULARITY, x)
 +  The unit for allocating and deallocating memory from the system.  On
 +  most systems with contiguous MORECORE, there is no reason to
 +  make this more than a page. However, systems with MMAP tend to
 +  either require or encourage larger granularities.  You can increase
 +  this value to prevent system allocation functions to be called so
 +  often, especially if they are slow.  The value must be at least one
 +  page and must be a power of two.  Setting to 0 causes initialization
 +  to either page size or win32 region size.  (Note: In previous
 +  versions of malloc, the equivalent of this option was called
 +  "TOP_PAD")
 +
 +DEFAULT_TRIM_THRESHOLD    default: 2MB
 +      Also settable using mallopt(M_TRIM_THRESHOLD, x)
 +  The maximum amount of unused top-most memory to keep before
 +  releasing via malloc_trim in free().  Automatic trimming is mainly
 +  useful in long-lived programs using contiguous MORECORE.  Because
 +  trimming via sbrk can be slow on some systems, and can sometimes be
 +  wasteful (in cases where programs immediately afterward allocate
 +  more large chunks) the value should be high enough so that your
 +  overall system performance would improve by releasing this much
 +  memory.  As a rough guide, you might set to a value close to the
 +  average size of a process (program) running on your system.
 +  Releasing this much memory would allow such a process to run in
 +  memory.  Generally, it is worth tuning trim thresholds when a
 +  program undergoes phases where several large chunks are allocated
 +  and released in ways that can reuse each other's storage, perhaps
 +  mixed with phases where there are no such chunks at all. The trim
 +  value must be greater than page size to have any useful effect.  To
 +  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
 +  some people use of mallocing a huge space and then freeing it at
 +  program startup, in an attempt to reserve system memory, doesn't
 +  have the intended effect under automatic trimming, since that memory
 +  will immediately be returned to the system.
 +
 +DEFAULT_MMAP_THRESHOLD       default: 256K
 +      Also settable using mallopt(M_MMAP_THRESHOLD, x)
 +  The request size threshold for using MMAP to directly service a
 +  request. Requests of at least this size that cannot be allocated
 +  using already-existing space will be serviced via mmap.  (If enough
 +  normal freed space already exists it is used instead.)  Using mmap
 +  segregates relatively large chunks of memory so that they can be
 +  individually obtained and released from the host system. A request
 +  serviced through mmap is never reused by any other request (at least
 +  not directly; the system may just so happen to remap successive
 +  requests to the same locations).  Segregating space in this way has
 +  the benefits that: Mmapped space can always be individually released
 +  back to the system, which helps keep the system level memory demands
 +  of a long-lived program low.  Also, mapped memory doesn't become
 +  `locked' between other chunks, as can happen with normally allocated
 +  chunks, which means that even trimming via malloc_trim would not
 +  release them.  However, it has the disadvantage that the space
 +  cannot be reclaimed, consolidated, and then used to service later
 +  requests, as happens with normal chunks.  The advantages of mmap
 +  nearly always outweigh disadvantages for "large" chunks, but the
 +  value of "large" may vary across systems.  The default is an
 +  empirically derived value that works well in most systems. You can
 +  disable mmap by setting to MAX_SIZE_T.
 +
 +*/
 +
 +#ifndef WIN32
 +#ifdef _WIN32
 +#define WIN32 1
 +#endif  /* _WIN32 */
 +#endif  /* WIN32 */
 +#ifdef WIN32
 +#define WIN32_LEAN_AND_MEAN
 +#include <windows.h>
 +#define HAVE_MMAP 1
 +#define HAVE_MORECORE 0
 +#define LACKS_UNISTD_H
 +#define LACKS_SYS_PARAM_H
 +#define LACKS_SYS_MMAN_H
 +#define LACKS_STRING_H
 +#define LACKS_STRINGS_H
 +#define LACKS_SYS_TYPES_H
 +#define LACKS_ERRNO_H
 +#define MALLOC_FAILURE_ACTION
 +#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */
 +#endif  /* WIN32 */
 +
 +#if defined(DARWIN) || defined(_DARWIN)
 +/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
 +#ifndef HAVE_MORECORE
 +#define HAVE_MORECORE 0
 +#define HAVE_MMAP 1
 +#endif  /* HAVE_MORECORE */
 +#endif  /* DARWIN */
 +
 +#ifndef LACKS_SYS_TYPES_H
 +#include <sys/types.h>  /* For size_t */
 +#endif  /* LACKS_SYS_TYPES_H */
 +
 +/* The maximum possible size_t value has all bits set */
 +#define MAX_SIZE_T           (~(size_t)0)
 +
 +#ifndef ONLY_MSPACES
 +#define ONLY_MSPACES 0
 +#endif  /* ONLY_MSPACES */
 +#ifndef MSPACES
 +#if ONLY_MSPACES
 +#define MSPACES 1
 +#else   /* ONLY_MSPACES */
 +#define MSPACES 0
 +#endif  /* ONLY_MSPACES */
 +#endif  /* MSPACES */
 +#ifndef MALLOC_ALIGNMENT
 +#define MALLOC_ALIGNMENT ((size_t)8U)
 +#endif  /* MALLOC_ALIGNMENT */
 +#ifndef FOOTERS
 +#define FOOTERS 0
 +#endif  /* FOOTERS */
 +#ifndef ABORT
 +#define ABORT  abort()
 +#endif  /* ABORT */
 +#ifndef ABORT_ON_ASSERT_FAILURE
 +#define ABORT_ON_ASSERT_FAILURE 1
 +#endif  /* ABORT_ON_ASSERT_FAILURE */
 +#ifndef PROCEED_ON_ERROR
 +#define PROCEED_ON_ERROR 0
 +#endif  /* PROCEED_ON_ERROR */
 +#ifndef USE_LOCKS
 +#define USE_LOCKS 0
 +#endif  /* USE_LOCKS */
 +#ifndef INSECURE
 +#define INSECURE 0
 +#endif  /* INSECURE */
 +#ifndef HAVE_MMAP
 +#define HAVE_MMAP 1
 +#endif  /* HAVE_MMAP */
 +#ifndef MMAP_CLEARS
 +#define MMAP_CLEARS 1
 +#endif  /* MMAP_CLEARS */
 +#ifndef HAVE_MREMAP
 +#ifdef linux
 +#define HAVE_MREMAP 1
 +#else   /* linux */
 +#define HAVE_MREMAP 0
 +#endif  /* linux */
 +#endif  /* HAVE_MREMAP */
 +#ifndef MALLOC_FAILURE_ACTION
 +#define MALLOC_FAILURE_ACTION  errno = ENOMEM;
 +#endif  /* MALLOC_FAILURE_ACTION */
 +#ifndef HAVE_MORECORE
 +#if ONLY_MSPACES
 +#define HAVE_MORECORE 0
 +#else   /* ONLY_MSPACES */
 +#define HAVE_MORECORE 1
 +#endif  /* ONLY_MSPACES */
 +#endif  /* HAVE_MORECORE */
 +#if !HAVE_MORECORE
 +#define MORECORE_CONTIGUOUS 0
 +#else   /* !HAVE_MORECORE */
 +#ifndef MORECORE
 +#define MORECORE sbrk
 +#endif  /* MORECORE */
 +#ifndef MORECORE_CONTIGUOUS
 +#define MORECORE_CONTIGUOUS 1
 +#endif  /* MORECORE_CONTIGUOUS */
 +#endif  /* HAVE_MORECORE */
 +#ifndef DEFAULT_GRANULARITY
 +#if MORECORE_CONTIGUOUS
 +#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */
 +#else   /* MORECORE_CONTIGUOUS */
 +#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
 +#endif  /* MORECORE_CONTIGUOUS */
 +#endif  /* DEFAULT_GRANULARITY */
 +#ifndef DEFAULT_TRIM_THRESHOLD
 +#ifndef MORECORE_CANNOT_TRIM
 +#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
 +#else   /* MORECORE_CANNOT_TRIM */
 +#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
 +#endif  /* MORECORE_CANNOT_TRIM */
 +#endif  /* DEFAULT_TRIM_THRESHOLD */
 +#ifndef DEFAULT_MMAP_THRESHOLD
 +#if HAVE_MMAP
 +#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
 +#else   /* HAVE_MMAP */
 +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
 +#endif  /* HAVE_MMAP */
 +#endif  /* DEFAULT_MMAP_THRESHOLD */
 +#ifndef USE_BUILTIN_FFS
 +#define USE_BUILTIN_FFS 0
 +#endif  /* USE_BUILTIN_FFS */
 +#ifndef USE_DEV_RANDOM
 +#define USE_DEV_RANDOM 0
 +#endif  /* USE_DEV_RANDOM */
 +#ifndef NO_MALLINFO
 +#define NO_MALLINFO 0
 +#endif  /* NO_MALLINFO */
 +#ifndef MALLINFO_FIELD_TYPE
 +#define MALLINFO_FIELD_TYPE size_t
 +#endif  /* MALLINFO_FIELD_TYPE */
 +
 +/*
 +  mallopt tuning options.  SVID/XPG defines four standard parameter
 +  numbers for mallopt, normally defined in malloc.h.  None of these
 +  are used in this malloc, so setting them has no effect. But this
 +  malloc does support the following options.
 +*/
 +
 +#define M_TRIM_THRESHOLD     (-1)
 +#define M_GRANULARITY        (-2)
 +#define M_MMAP_THRESHOLD     (-3)
 +
 +/* ------------------------ Mallinfo declarations ------------------------ */
 +
 +#if !NO_MALLINFO
 +/*
 +  This version of malloc supports the standard SVID/XPG mallinfo
 +  routine that returns a struct containing usage properties and
 +  statistics. It should work on any system that has a
 +  /usr/include/malloc.h defining struct mallinfo.  The main
 +  declaration needed is the mallinfo struct that is returned (by-copy)
 +  by mallinfo().  The malloinfo struct contains a bunch of fields that
 +  are not even meaningful in this version of malloc.  These fields are
 +  are instead filled by mallinfo() with other numbers that might be of
 +  interest.
 +
 +  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
 +  /usr/include/malloc.h file that includes a declaration of struct
 +  mallinfo.  If so, it is included; else a compliant version is
 +  declared below.  These must be precisely the same for mallinfo() to
 +  work.  The original SVID version of this struct, defined on most
 +  systems with mallinfo, declares all fields as ints. But some others
 +  define as unsigned long. If your system defines the fields using a
 +  type of different width than listed here, you MUST #include your
 +  system version and #define HAVE_USR_INCLUDE_MALLOC_H.
 +*/
 +
 +/* #define HAVE_USR_INCLUDE_MALLOC_H */
 +
 +#ifdef HAVE_USR_INCLUDE_MALLOC_H
 +#include "/usr/include/malloc.h"
 +#else /* HAVE_USR_INCLUDE_MALLOC_H */
 +
 +struct mallinfo {
 +  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
 +  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
 +  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
 +  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
 +  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
 +  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
 +  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
 +  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
 +  MALLINFO_FIELD_TYPE fordblks; /* total free space */
 +  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
 +};
 +
 +#endif /* HAVE_USR_INCLUDE_MALLOC_H */
 +#endif /* NO_MALLINFO */
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif /* __cplusplus */
 +
 +#if !ONLY_MSPACES
 +
 +/* ------------------- Declarations of public routines ------------------- */
 +
 +#ifndef USE_DL_PREFIX
 +#define dlcalloc               calloc
 +#define dlfree                 free
 +#define dlmalloc               malloc
 +#define dlmemalign             memalign
 +#define dlrealloc              realloc
 +#define dlvalloc               valloc
 +#define dlpvalloc              pvalloc
 +#define dlmallinfo             mallinfo
 +#define dlmallopt              mallopt
 +#define dlmalloc_trim          malloc_trim
 +#define dlmalloc_stats         malloc_stats
 +#define dlmalloc_usable_size   malloc_usable_size
 +#define dlmalloc_footprint     malloc_footprint
 +#define dlmalloc_max_footprint malloc_max_footprint
 +#define dlindependent_calloc   independent_calloc
 +#define dlindependent_comalloc independent_comalloc
 +#endif /* USE_DL_PREFIX */
 +
 +
 +/*
 +  malloc(size_t n)
 +  Returns a pointer to a newly allocated chunk of at least n bytes, or
 +  null if no space is available, in which case errno is set to ENOMEM
 +  on ANSI C systems.
 +
 +  If n is zero, malloc returns a minimum-sized chunk. (The minimum
 +  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
 +  systems.)  Note that size_t is an unsigned type, so calls with
 +  arguments that would be negative if signed are interpreted as
 +  requests for huge amounts of space, which will often fail. The
 +  maximum supported value of n differs across systems, but is in all
 +  cases less than the maximum representable value of a size_t.
 +*/
 +void* dlmalloc(size_t);
 +
 +/*
 +  free(void* p)
 +  Releases the chunk of memory pointed to by p, that had been previously
 +  allocated using malloc or a related routine such as realloc.
 +  It has no effect if p is null. If p was not malloced or already
 +  freed, free(p) will by default cause the current program to abort.
 +*/
 +void  dlfree(void*);
 +
 +/*
 +  calloc(size_t n_elements, size_t element_size);
 +  Returns a pointer to n_elements * element_size bytes, with all locations
 +  set to zero.
 +*/
 +void* dlcalloc(size_t, size_t);
 +
 +/*
 +  realloc(void* p, size_t n)
 +  Returns a pointer to a chunk of size n that contains the same data
 +  as does chunk p up to the minimum of (n, p's size) bytes, or null
 +  if no space is available.
 +
 +  The returned pointer may or may not be the same as p. The algorithm
 +  prefers extending p in most cases when possible, otherwise it
 +  employs the equivalent of a malloc-copy-free sequence.
 +
 +  If p is null, realloc is equivalent to malloc.
 +
 +  If space is not available, realloc returns null, errno is set (if on
 +  ANSI) and p is NOT freed.
 +
 +  if n is for fewer bytes than already held by p, the newly unused
 +  space is lopped off and freed if possible.  realloc with a size
 +  argument of zero (re)allocates a minimum-sized chunk.
 +
 +  The old unix realloc convention of allowing the last-free'd chunk
 +  to be used as an argument to realloc is not supported.
 +*/
 +
 +void* dlrealloc(void*, size_t);
 +
 +/*
 +  memalign(size_t alignment, size_t n);
 +  Returns a pointer to a newly allocated chunk of n bytes, aligned
 +  in accord with the alignment argument.
 +
 +  The alignment argument should be a power of two. If the argument is
 +  not a power of two, the nearest greater power is used.
 +  8-byte alignment is guaranteed by normal malloc calls, so don't
 +  bother calling memalign with an argument of 8 or less.
 +
 +  Overreliance on memalign is a sure way to fragment space.
 +*/
 +void* dlmemalign(size_t, size_t);
 +
 +/*
 +  valloc(size_t n);
 +  Equivalent to memalign(pagesize, n), where pagesize is the page
 +  size of the system. If the pagesize is unknown, 4096 is used.
 +*/
 +void* dlvalloc(size_t);
 +
 +/*
 +  mallopt(int parameter_number, int parameter_value)
 +  Sets tunable parameters The format is to provide a
 +  (parameter-number, parameter-value) pair.  mallopt then sets the
 +  corresponding parameter to the argument value if it can (i.e., so
 +  long as the value is meaningful), and returns 1 if successful else
 +  0.  SVID/XPG/ANSI defines four standard param numbers for mallopt,
 +  normally defined in malloc.h.  None of these are use in this malloc,
 +  so setting them has no effect. But this malloc also supports other
 +  options in mallopt. See below for details.  Briefly, supported
 +  parameters are as follows (listed defaults are for "typical"
 +  configurations).
 +
 +  Symbol            param #  default    allowed param values
 +  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (MAX_SIZE_T disables)
 +  M_GRANULARITY        -2     page size   any power of 2 >= page size
 +  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
 +*/
 +int dlmallopt(int, int);
 +
 +/*
 +  malloc_footprint();
 +  Returns the number of bytes obtained from the system.  The total
 +  number of bytes allocated by malloc, realloc etc., is less than this
 +  value. Unlike mallinfo, this function returns only a precomputed
 +  result, so can be called frequently to monitor memory consumption.
 +  Even if locks are otherwise defined, this function does not use them,
 +  so results might not be up to date.
 +*/
 +size_t dlmalloc_footprint(void);
 +
 +/*
 +  malloc_max_footprint();
 +  Returns the maximum number of bytes obtained from the system. This
 +  value will be greater than current footprint if deallocated space
 +  has been reclaimed by the system. The peak number of bytes allocated
 +  by malloc, realloc etc., is less than this value. Unlike mallinfo,
 +  this function returns only a precomputed result, so can be called
 +  frequently to monitor memory consumption.  Even if locks are
 +  otherwise defined, this function does not use them, so results might
 +  not be up to date.
 +*/
 +size_t dlmalloc_max_footprint(void);
 +
 +#if !NO_MALLINFO
 +/*
 +  mallinfo()
 +  Returns (by copy) a struct containing various summary statistics:
 +
 +  arena:     current total non-mmapped bytes allocated from system
 +  ordblks:   the number of free chunks
 +  smblks:    always zero.
 +  hblks:     current number of mmapped regions
 +  hblkhd:    total bytes held in mmapped regions
 +  usmblks:   the maximum total allocated space. This will be greater
 +                than current total if trimming has occurred.
 +  fsmblks:   always zero
 +  uordblks:  current total allocated space (normal or mmapped)
 +  fordblks:  total free space
 +  keepcost:  the maximum number of bytes that could ideally be released
 +               back to system via malloc_trim. ("ideally" means that
 +               it ignores page restrictions etc.)
 +
 +  Because these fields are ints, but internal bookkeeping may
 +  be kept as longs, the reported values may wrap around zero and
 +  thus be inaccurate.
 +*/
 +struct mallinfo dlmallinfo(void);
 +#endif /* NO_MALLINFO */
 +
 +/*
 +  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
 +
 +  independent_calloc is similar to calloc, but instead of returning a
 +  single cleared space, it returns an array of pointers to n_elements
 +  independent elements that can hold contents of size elem_size, each
 +  of which starts out cleared, and can be independently freed,
 +  realloc'ed etc. The elements are guaranteed to be adjacently
 +  allocated (this is not guaranteed to occur with multiple callocs or
 +  mallocs), which may also improve cache locality in some
 +  applications.
 +
 +  The "chunks" argument is optional (i.e., may be null, which is
 +  probably the most typical usage). If it is null, the returned array
 +  is itself dynamically allocated and should also be freed when it is
 +  no longer needed. Otherwise, the chunks array must be of at least
 +  n_elements in length. It is filled in with the pointers to the
 +  chunks.
 +
 +  In either case, independent_calloc returns this pointer array, or
 +  null if the allocation failed.  If n_elements is zero and "chunks"
 +  is null, it returns a chunk representing an array with zero elements
 +  (which should be freed if not wanted).
 +
 +  Each element must be individually freed when it is no longer
 +  needed. If you'd like to instead be able to free all at once, you
 +  should instead use regular calloc and assign pointers into this
 +  space to represent elements.  (In this case though, you cannot
 +  independently free elements.)
 +
 +  independent_calloc simplifies and speeds up implementations of many
 +  kinds of pools.  It may also be useful when constructing large data
 +  structures that initially have a fixed number of fixed-sized nodes,
 +  but the number is not known at compile time, and some of the nodes
 +  may later need to be freed. For example:
 +
 +  struct Node { int item; struct Node* next; };
 +
 +  struct Node* build_list() {
 +    struct Node** pool;
 +    int n = read_number_of_nodes_needed();
 +    if (n <= 0) return 0;
 +    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
 +    if (pool == 0) die();
 +    // organize into a linked list...
 +    struct Node* first = pool[0];
 +    for (i = 0; i < n-1; ++i)
 +      pool[i]->next = pool[i+1];
 +    free(pool);     // Can now free the array (or not, if it is needed later)
 +    return first;
 +  }
 +*/
 +void** dlindependent_calloc(size_t, size_t, void**);
 +
 +/*
 +  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
 +
 +  independent_comalloc allocates, all at once, a set of n_elements
 +  chunks with sizes indicated in the "sizes" array.    It returns
 +  an array of pointers to these elements, each of which can be
 +  independently freed, realloc'ed etc. The elements are guaranteed to
 +  be adjacently allocated (this is not guaranteed to occur with
 +  multiple callocs or mallocs), which may also improve cache locality
 +  in some applications.
 +
 +  The "chunks" argument is optional (i.e., may be null). If it is null
 +  the returned array is itself dynamically allocated and should also
 +  be freed when it is no longer needed. Otherwise, the chunks array
 +  must be of at least n_elements in length. It is filled in with the
 +  pointers to the chunks.
 +
 +  In either case, independent_comalloc returns this pointer array, or
 +  null if the allocation failed.  If n_elements is zero and chunks is
 +  null, it returns a chunk representing an array with zero elements
 +  (which should be freed if not wanted).
 +
 +  Each element must be individually freed when it is no longer
 +  needed. If you'd like to instead be able to free all at once, you
 +  should instead use a single regular malloc, and assign pointers at
 +  particular offsets in the aggregate space. (In this case though, you
 +  cannot independently free elements.)
 +
 +  independent_comallac differs from independent_calloc in that each
 +  element may have a different size, and also that it does not
 +  automatically clear elements.
 +
 +  independent_comalloc can be used to speed up allocation in cases
 +  where several structs or objects must always be allocated at the
 +  same time.  For example:
 +
 +  struct Head { ... }
 +  struct Foot { ... }
 +
 +  void send_message(char* msg) {
 +    int msglen = strlen(msg);
 +    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
 +    void* chunks[3];
 +    if (independent_comalloc(3, sizes, chunks) == 0)
 +      die();
 +    struct Head* head = (struct Head*)(chunks[0]);
 +    char*        body = (char*)(chunks[1]);
 +    struct Foot* foot = (struct Foot*)(chunks[2]);
 +    // ...
 +  }
 +
 +  In general though, independent_comalloc is worth using only for
 +  larger values of n_elements. For small values, you probably won't
 +  detect enough difference from series of malloc calls to bother.
 +
 +  Overuse of independent_comalloc can increase overall memory usage,
 +  since it cannot reuse existing noncontiguous small chunks that
 +  might be available for some of the elements.
 +*/
 +void** dlindependent_comalloc(size_t, size_t*, void**);
 +
 +
 +/*
 +  pvalloc(size_t n);
 +  Equivalent to valloc(minimum-page-that-holds(n)), that is,
 +  round up n to nearest pagesize.
 + */
 +void*  dlpvalloc(size_t);
 +
 +/*
 +  malloc_trim(size_t pad);
 +
 +  If possible, gives memory back to the system (via negative arguments
 +  to sbrk) if there is unused memory at the `high' end of the malloc
 +  pool or in unused MMAP segments. You can call this after freeing
 +  large blocks of memory to potentially reduce the system-level memory
 +  requirements of a program. However, it cannot guarantee to reduce
 +  memory. Under some allocation patterns, some large free blocks of
 +  memory will be locked between two used chunks, so they cannot be
 +  given back to the system.
 +
 +  The `pad' argument to malloc_trim represents the amount of free
 +  trailing space to leave untrimmed. If this argument is zero, only
 +  the minimum amount of memory to maintain internal data structures
 +  will be left. Non-zero arguments can be supplied to maintain enough
 +  trailing space to service future expected allocations without having
 +  to re-obtain memory from the system.
 +
 +  Malloc_trim returns 1 if it actually released any memory, else 0.
 +*/
 +int  dlmalloc_trim(size_t);
 +
 +/*
 +  malloc_usable_size(void* p);
 +
 +  Returns the number of bytes you can actually use in
 +  an allocated chunk, which may be more than you requested (although
 +  often not) due to alignment and minimum size constraints.
 +  You can use this many bytes without worrying about
 +  overwriting other allocated objects. This is not a particularly great
 +  programming practice. malloc_usable_size can be more useful in
 +  debugging and assertions, for example:
 +
 +  p = malloc(n);
 +  assert(malloc_usable_size(p) >= 256);
 +*/
 +size_t dlmalloc_usable_size(void*);
 +
 +/*
 +  malloc_stats();
 +  Prints on stderr the amount of space obtained from the system (both
 +  via sbrk and mmap), the maximum amount (which may be more than
 +  current if malloc_trim and/or munmap got called), and the current
 +  number of bytes allocated via malloc (or realloc, etc) but not yet
 +  freed. Note that this is the number of bytes allocated, not the
 +  number requested. It will be larger than the number requested
 +  because of alignment and bookkeeping overhead. Because it includes
 +  alignment wastage as being in use, this figure may be greater than
 +  zero even when no user-level chunks are allocated.
 +
 +  The reported current and maximum system memory can be inaccurate if
 +  a program makes other calls to system memory allocation functions
 +  (normally sbrk) outside of malloc.
 +
 +  malloc_stats prints only the most commonly interesting statistics.
 +  More information can be obtained by calling mallinfo.
 +*/
 +void  dlmalloc_stats(void);
 +
 +#endif /* ONLY_MSPACES */
 +
 +#if MSPACES
 +
 +/*
 +  mspace is an opaque type representing an independent
 +  region of space that supports mspace_malloc, etc.
 +*/
 +typedef void* mspace;
 +
 +/*
 +  create_mspace creates and returns a new independent space with the
 +  given initial capacity, or, if 0, the default granularity size.  It
 +  returns null if there is no system memory available to create the
 +  space.  If argument locked is non-zero, the space uses a separate
 +  lock to control access. The capacity of the space will grow
 +  dynamically as needed to service mspace_malloc requests.  You can
 +  control the sizes of incremental increases of this space by
 +  compiling with a different DEFAULT_GRANULARITY or dynamically
 +  setting with mallopt(M_GRANULARITY, value).
 +*/
 +mspace create_mspace(size_t capacity, int locked);
 +
 +/*
 +  destroy_mspace destroys the given space, and attempts to return all
 +  of its memory back to the system, returning the total number of
 +  bytes freed. After destruction, the results of access to all memory
 +  used by the space become undefined.
 +*/
 +size_t destroy_mspace(mspace msp);
 +
 +/*
 +  create_mspace_with_base uses the memory supplied as the initial base
 +  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
 +  space is used for bookkeeping, so the capacity must be at least this
 +  large. (Otherwise 0 is returned.) When this initial space is
 +  exhausted, additional memory will be obtained from the system.
 +  Destroying this space will deallocate all additionally allocated
 +  space (if possible) but not the initial base.
 +*/
 +mspace create_mspace_with_base(void* base, size_t capacity, int locked);
 +
 +/*
 +  mspace_malloc behaves as malloc, but operates within
 +  the given space.
 +*/
 +void* mspace_malloc(mspace msp, size_t bytes);
 +
 +/*
 +  mspace_free behaves as free, but operates within
 +  the given space.
 +
 +  If compiled with FOOTERS==1, mspace_free is not actually needed.
 +  free may be called instead of mspace_free because freed chunks from
 +  any space are handled by their originating spaces.
 +*/
 +void mspace_free(mspace msp, void* mem);
 +
 +/*
 +  mspace_realloc behaves as realloc, but operates within
 +  the given space.
 +
 +  If compiled with FOOTERS==1, mspace_realloc is not actually
 +  needed.  realloc may be called instead of mspace_realloc because
 +  realloced chunks from any space are handled by their originating
 +  spaces.
 +*/
 +void* mspace_realloc(mspace msp, void* mem, size_t newsize);
 +
 +/*
 +  mspace_calloc behaves as calloc, but operates within
 +  the given space.
 +*/
 +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
 +
 +/*
 +  mspace_memalign behaves as memalign, but operates within
 +  the given space.
 +*/
 +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
 +
 +/*
 +  mspace_independent_calloc behaves as independent_calloc, but
 +  operates within the given space.
 +*/
 +void** mspace_independent_calloc(mspace msp, size_t n_elements,
 +                                 size_t elem_size, void* chunks[]);
 +
 +/*
 +  mspace_independent_comalloc behaves as independent_comalloc, but
 +  operates within the given space.
 +*/
 +void** mspace_independent_comalloc(mspace msp, size_t n_elements,
 +                                   size_t sizes[], void* chunks[]);
 +
 +/*
 +  mspace_footprint() returns the number of bytes obtained from the
 +  system for this space.
 +*/
 +size_t mspace_footprint(mspace msp);
 +
 +/*
 +  mspace_max_footprint() returns the peak number of bytes obtained from the
 +  system for this space.
 +*/
 +size_t mspace_max_footprint(mspace msp);
 +
 +
 +#if !NO_MALLINFO
 +/*
 +  mspace_mallinfo behaves as mallinfo, but reports properties of
 +  the given space.
 +*/
 +struct mallinfo mspace_mallinfo(mspace msp);
 +#endif /* NO_MALLINFO */
 +
 +/*
 +  mspace_malloc_stats behaves as malloc_stats, but reports
 +  properties of the given space.
 +*/
 +void mspace_malloc_stats(mspace msp);
 +
 +/*
 +  mspace_trim behaves as malloc_trim, but
 +  operates within the given space.
 +*/
 +int mspace_trim(mspace msp, size_t pad);
 +
 +/*
 +  An alias for mallopt.
 +*/
 +int mspace_mallopt(int, int);
 +
 +#endif /* MSPACES */
 +
 +#ifdef __cplusplus
 +};  /* end of extern "C" */
 +#endif /* __cplusplus */
 +
 +/*
 +  ========================================================================
 +  To make a fully customizable malloc.h header file, cut everything
 +  above this line, put into file malloc.h, edit to suit, and #include it
 +  on the next line, as well as in programs that use this malloc.
 +  ========================================================================
 +*/
 +
 +/* #include "malloc.h" */
 +
 +/*------------------------------ internal #includes ---------------------- */
 +
 +#ifdef _MSC_VER
 +#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
 +#endif /* _MSC_VER */
 +
 +#include <stdio.h>       /* for printing in malloc_stats */
 +
 +#ifndef LACKS_ERRNO_H
 +#include <errno.h>       /* for MALLOC_FAILURE_ACTION */
 +#endif /* LACKS_ERRNO_H */
 +#if FOOTERS
 +#include <time.h>        /* for magic initialization */
 +#endif /* FOOTERS */
 +#ifndef LACKS_STDLIB_H
 +#include <stdlib.h>      /* for abort() */
 +#endif /* LACKS_STDLIB_H */
 +#ifdef DEBUG
 +#if ABORT_ON_ASSERT_FAILURE
 +#define assert(x) if(!(x)) ABORT
 +#else /* ABORT_ON_ASSERT_FAILURE */
 +#include <assert.h>
 +#endif /* ABORT_ON_ASSERT_FAILURE */
 +#else  /* DEBUG */
 +#define assert(x)
 +#endif /* DEBUG */
 +#ifndef LACKS_STRING_H
 +#include <string.h>      /* for memset etc */
 +#endif  /* LACKS_STRING_H */
 +#if USE_BUILTIN_FFS
 +#ifndef LACKS_STRINGS_H
 +#include <strings.h>     /* for ffs */
 +#endif /* LACKS_STRINGS_H */
 +#endif /* USE_BUILTIN_FFS */
 +#if HAVE_MMAP
 +#ifndef LACKS_SYS_MMAN_H
 +#include <sys/mman.h>    /* for mmap */
 +#endif /* LACKS_SYS_MMAN_H */
 +#ifndef LACKS_FCNTL_H
 +#include <fcntl.h>
 +#endif /* LACKS_FCNTL_H */
 +#endif /* HAVE_MMAP */
 +#if HAVE_MORECORE
 +#ifndef LACKS_UNISTD_H
 +#include <unistd.h>     /* for sbrk */
 +#else /* LACKS_UNISTD_H */
 +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
 +extern void*     sbrk(ptrdiff_t);
 +#endif /* FreeBSD etc */
 +#endif /* LACKS_UNISTD_H */
 +#endif /* HAVE_MMAP */
 +
 +#ifndef WIN32
 +#ifndef malloc_getpagesize
 +#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
 +#    ifndef _SC_PAGE_SIZE
 +#      define _SC_PAGE_SIZE _SC_PAGESIZE
 +#    endif
 +#  endif
 +#  ifdef _SC_PAGE_SIZE
 +#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
 +#  else
 +#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
 +       extern size_t getpagesize();
 +#      define malloc_getpagesize getpagesize()
 +#    else
 +#      ifdef WIN32 /* use supplied emulation of getpagesize */
 +#        define malloc_getpagesize getpagesize()
 +#      else
 +#        ifndef LACKS_SYS_PARAM_H
 +#          include <sys/param.h>
 +#        endif
 +#        ifdef EXEC_PAGESIZE
 +#          define malloc_getpagesize EXEC_PAGESIZE
 +#        else
 +#          ifdef NBPG
 +#            ifndef CLSIZE
 +#              define malloc_getpagesize NBPG
 +#            else
 +#              define malloc_getpagesize (NBPG * CLSIZE)
 +#            endif
 +#          else
 +#            ifdef NBPC
 +#              define malloc_getpagesize NBPC
 +#            else
 +#              ifdef PAGESIZE
 +#                define malloc_getpagesize PAGESIZE
 +#              else /* just guess */
 +#                define malloc_getpagesize ((size_t)4096U)
 +#              endif
 +#            endif
 +#          endif
 +#        endif
 +#      endif
 +#    endif
 +#  endif
 +#endif
 +#endif
 +
 +/* ------------------- size_t and alignment properties -------------------- */
 +
 +/* The byte and bit size of a size_t */
 +#define SIZE_T_SIZE         (sizeof(size_t))
 +#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)
 +
 +/* Some constants coerced to size_t */
 +/* Annoying but necessary to avoid errors on some plaftorms */
 +#define SIZE_T_ZERO         ((size_t)0)
 +#define SIZE_T_ONE          ((size_t)1)
 +#define SIZE_T_TWO          ((size_t)2)
 +#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)
 +#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)
 +#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
 +#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)
 +
 +/* The bit mask value corresponding to MALLOC_ALIGNMENT */
 +#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)
 +
 +/* True if address a has acceptable alignment */
 +#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
 +
 +/* the number of bytes to offset an address to align it */
 +#define align_offset(A)\
 + ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
 +  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
 +
 +/* -------------------------- MMAP preliminaries ------------------------- */
 +
 +/*
 +   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
 +   checks to fail so compiler optimizer can delete code rather than
 +   using so many "#if"s.
 +*/
 +
 +
 +/* MORECORE and MMAP must return MFAIL on failure */
 +#define MFAIL                ((void*)(MAX_SIZE_T))
 +#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */
 +
 +#if !HAVE_MMAP
 +#define IS_MMAPPED_BIT       (SIZE_T_ZERO)
 +#define USE_MMAP_BIT         (SIZE_T_ZERO)
 +#define CALL_MMAP(s)         MFAIL
 +#define CALL_MUNMAP(a, s)    (-1)
 +#define DIRECT_MMAP(s)       MFAIL
 +
 +#else /* HAVE_MMAP */
 +#define IS_MMAPPED_BIT       (SIZE_T_ONE)
 +#define USE_MMAP_BIT         (SIZE_T_ONE)
 +
 +#ifndef WIN32
 +#define CALL_MUNMAP(a, s)    munmap((a), (s))
 +#define MMAP_PROT            (PROT_READ|PROT_WRITE)
 +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
 +#define MAP_ANONYMOUS        MAP_ANON
 +#endif /* MAP_ANON */
 +#ifdef MAP_ANONYMOUS
 +#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)
 +#define CALL_MMAP(s)         mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
 +#else /* MAP_ANONYMOUS */
 +/*
 +   Nearly all versions of mmap support MAP_ANONYMOUS, so the following
 +   is unlikely to be needed, but is supplied just in case.
 +*/
 +#define MMAP_FLAGS           (MAP_PRIVATE)
 +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
 +#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \
 +           (dev_zero_fd = open("/dev/zero", O_RDWR), \
 +            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
 +            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
 +#endif /* MAP_ANONYMOUS */
 +
 +#define DIRECT_MMAP(s)       CALL_MMAP(s)
 +#else /* WIN32 */
 +
 +/* Win32 MMAP via VirtualAlloc */
 +static void* win32mmap(size_t size) {
 +  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 +  return (ptr != 0)? ptr: MFAIL;
 +}
 +
 +/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
 +static void* win32direct_mmap(size_t size) {
 +  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
 +                           PAGE_EXECUTE_READWRITE);
 +  return (ptr != 0)? ptr: MFAIL;
 +}
 +
- /* mstate bit set if continguous morecore disabled or failed */
++/* This function supports releasing coalesced segments */
 +static int win32munmap(void* ptr, size_t size) {
 +  MEMORY_BASIC_INFORMATION minfo;
 +  char* cptr = ptr;
 +  while (size) {
 +    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
 +      return -1;
 +    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
 +        minfo.State != MEM_COMMIT || minfo.RegionSize > size)
 +      return -1;
 +    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
 +      return -1;
 +    cptr += minfo.RegionSize;
 +    size -= minfo.RegionSize;
 +  }
 +  return 0;
 +}
 +
 +#define CALL_MMAP(s)         win32mmap(s)
 +#define CALL_MUNMAP(a, s)    win32munmap((a), (s))
 +#define DIRECT_MMAP(s)       win32direct_mmap(s)
 +#endif /* WIN32 */
 +#endif /* HAVE_MMAP */
 +
 +#if HAVE_MMAP && HAVE_MREMAP
 +#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
 +#else  /* HAVE_MMAP && HAVE_MREMAP */
 +#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL
 +#endif /* HAVE_MMAP && HAVE_MREMAP */
 +
 +#if HAVE_MORECORE
 +#define CALL_MORECORE(S)     MORECORE(S)
 +#else  /* HAVE_MORECORE */
 +#define CALL_MORECORE(S)     MFAIL
 +#endif /* HAVE_MORECORE */
 +
++/* mstate bit set if contiguous morecore disabled or failed */
 +#define USE_NONCONTIGUOUS_BIT (4U)
 +
 +/* segment bit set in create_mspace_with_base */
 +#define EXTERN_BIT            (8U)
 +
 +
 +/* --------------------------- Lock preliminaries ------------------------ */
 +
 +#if USE_LOCKS
 +
 +/*
 +  When locks are defined, there are up to two global locks:
 +
 +  * If HAVE_MORECORE, morecore_mutex protects sequences of calls to
 +    MORECORE.  In many cases sys_alloc requires two calls, that should
 +    not be interleaved with calls by other threads.  This does not
 +    protect against direct calls to MORECORE by other threads not
 +    using this lock, so there is still code to cope the best we can on
 +    interference.
 +
 +  * magic_init_mutex ensures that mparams.magic and other
 +    unique mparams values are initialized only once.
 +*/
 +
 +#ifndef WIN32
 +/* By default use posix locks */
 +#include <pthread.h>
 +#define MLOCK_T pthread_mutex_t
 +#define INITIAL_LOCK(l)      pthread_mutex_init(l, NULL)
 +#define ACQUIRE_LOCK(l)      pthread_mutex_lock(l)
 +#define RELEASE_LOCK(l)      pthread_mutex_unlock(l)
 +
 +#if HAVE_MORECORE
 +static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER;
 +#endif /* HAVE_MORECORE */
 +
 +static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER;
 +
 +#else /* WIN32 */
 +/*
 +   Because lock-protected regions have bounded times, and there
 +   are no recursive lock calls, we can use simple spinlocks.
 +*/
 +
 +#define MLOCK_T long
 +static int win32_acquire_lock (MLOCK_T *sl) {
 +  for (;;) {
 +#ifdef InterlockedCompareExchangePointer
 +    if (!InterlockedCompareExchange(sl, 1, 0))
 +      return 0;
 +#else  /* Use older void* version */
 +    if (!InterlockedCompareExchange((void**)sl, (void*)1, (void*)0))
 +      return 0;
 +#endif /* InterlockedCompareExchangePointer */
 +    Sleep (0);
 +  }
 +}
 +
 +static void win32_release_lock (MLOCK_T *sl) {
 +  InterlockedExchange (sl, 0);
 +}
 +
 +#define INITIAL_LOCK(l)      *(l)=0
 +#define ACQUIRE_LOCK(l)      win32_acquire_lock(l)
 +#define RELEASE_LOCK(l)      win32_release_lock(l)
 +#if HAVE_MORECORE
 +static MLOCK_T morecore_mutex;
 +#endif /* HAVE_MORECORE */
 +static MLOCK_T magic_init_mutex;
 +#endif /* WIN32 */
 +
 +#define USE_LOCK_BIT               (2U)
 +#else  /* USE_LOCKS */
 +#define USE_LOCK_BIT               (0U)
 +#define INITIAL_LOCK(l)
 +#endif /* USE_LOCKS */
 +
 +#if USE_LOCKS && HAVE_MORECORE
 +#define ACQUIRE_MORECORE_LOCK()    ACQUIRE_LOCK(&morecore_mutex);
 +#define RELEASE_MORECORE_LOCK()    RELEASE_LOCK(&morecore_mutex);
 +#else /* USE_LOCKS && HAVE_MORECORE */
 +#define ACQUIRE_MORECORE_LOCK()
 +#define RELEASE_MORECORE_LOCK()
 +#endif /* USE_LOCKS && HAVE_MORECORE */
 +
 +#if USE_LOCKS
 +#define ACQUIRE_MAGIC_INIT_LOCK()  ACQUIRE_LOCK(&magic_init_mutex);
 +#define RELEASE_MAGIC_INIT_LOCK()  RELEASE_LOCK(&magic_init_mutex);
 +#else  /* USE_LOCKS */
 +#define ACQUIRE_MAGIC_INIT_LOCK()
 +#define RELEASE_MAGIC_INIT_LOCK()
 +#endif /* USE_LOCKS */
 +
 +
 +/* -----------------------  Chunk representations ------------------------ */
 +
 +/*
 +  (The following includes lightly edited explanations by Colin Plumb.)
 +
 +  The malloc_chunk declaration below is misleading (but accurate and
 +  necessary).  It declares a "view" into memory allowing access to
 +  necessary fields at known offsets from a given base.
 +
 +  Chunks of memory are maintained using a `boundary tag' method as
 +  originally described by Knuth.  (See the paper by Paul Wilson
 +  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
 +  techniques.)  Sizes of free chunks are stored both in the front of
 +  each chunk and at the end.  This makes consolidating fragmented
 +  chunks into bigger chunks fast.  The head fields also hold bits
 +  representing whether chunks are free or in use.
 +
 +  Here are some pictures to make it clearer.  They are "exploded" to
 +  show that the state of a chunk can be thought of as extending from
 +  the high 31 bits of the head field of its header through the
 +  prev_foot and PINUSE_BIT bit of the following chunk header.
 +
 +  A chunk that's in use looks like:
 +
 +   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +           | Size of previous chunk (if P = 1)                             |
 +           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
 +         | Size of this chunk                                         1| +-+
 +   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +         |                                                               |
 +         +-                                                             -+
 +         |                                                               |
 +         +-                                                             -+
 +         |                                                               :
 +         +-      size - sizeof(size_t) available payload bytes          -+
 +         :                                                               |
 + chunk-> +-                                                             -+
 +         |                                                               |
 +         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
 +       | Size of next chunk (may or may not be in use)               | +-+
 + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +
 +    And if it's free, it looks like this:
 +
 +   chunk-> +-                                                             -+
 +           | User payload (must be in use, or we would have merged!)       |
 +           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
 +         | Size of this chunk                                         0| +-+
 +   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +         | Next pointer                                                  |
 +         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +         | Prev pointer                                                  |
 +         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +         |                                                               :
 +         +-      size - sizeof(struct chunk) unused bytes               -+
 +         :                                                               |
 + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +         | Size of this chunk                                            |
 +         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
 +       | Size of next chunk (must be in use, or we would have merged)| +-+
 + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +       |                                                               :
 +       +- User payload                                                -+
 +       :                                                               |
 +       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +                                                                     |0|
 +                                                                     +-+
 +  Note that since we always merge adjacent free chunks, the chunks
 +  adjacent to a free chunk must be in use.
 +
 +  Given a pointer to a chunk (which can be derived trivially from the
 +  payload pointer) we can, in O(1) time, find out whether the adjacent
 +  chunks are free, and if so, unlink them from the lists that they
 +  are on and merge them with the current chunk.
 +
 +  Chunks always begin on even word boundaries, so the mem portion
 +  (which is returned to the user) is also on an even word boundary, and
 +  thus at least double-word aligned.
 +
 +  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
 +  chunk size (which is always a multiple of two words), is an in-use
 +  bit for the *previous* chunk.  If that bit is *clear*, then the
 +  word before the current chunk size contains the previous chunk
 +  size, and can be used to find the front of the previous chunk.
 +  The very first chunk allocated always has this bit set, preventing
 +  access to non-existent (or non-owned) memory. If pinuse is set for
 +  any given chunk, then you CANNOT determine the size of the
 +  previous chunk, and might even get a memory addressing fault when
 +  trying to do so.
 +
 +  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
 +  the chunk size redundantly records whether the current chunk is
 +  inuse. This redundancy enables usage checks within free and realloc,
 +  and reduces indirection when freeing and consolidating chunks.
 +
 +  Each freshly allocated chunk must have both cinuse and pinuse set.
 +  That is, each allocated chunk borders either a previously allocated
 +  and still in-use chunk, or the base of its memory arena. This is
 +  ensured by making all allocations from the the `lowest' part of any
 +  found chunk.  Further, no free chunk physically borders another one,
 +  so each free chunk is known to be preceded and followed by either
 +  inuse chunks or the ends of memory.
 +
 +  Note that the `foot' of the current chunk is actually represented
 +  as the prev_foot of the NEXT chunk. This makes it easier to
 +  deal with alignments etc but can be very confusing when trying
 +  to extend or adapt this code.
 +
 +  The exceptions to all this are
 +
 +     1. The special chunk `top' is the top-most available chunk (i.e.,
 +        the one bordering the end of available memory). It is treated
 +        specially.  Top is never included in any bin, is used only if
 +        no other chunk is available, and is released back to the
 +        system if it is very large (see M_TRIM_THRESHOLD).  In effect,
 +        the top chunk is treated as larger (and thus less well
 +        fitting) than any other available chunk.  The top chunk
 +        doesn't update its trailing size field since there is no next
 +        contiguous chunk that would have to index off it. However,
 +        space is still allocated for it (TOP_FOOT_SIZE) to enable
 +        separation or merging when space is extended.
 +
 +     3. Chunks allocated via mmap, which have the lowest-order bit
 +        (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set
 +        PINUSE_BIT in their head fields.  Because they are allocated
 +        one-by-one, each must carry its own prev_foot field, which is
 +        also used to hold the offset this chunk has within its mmapped
 +        region, which is needed to preserve alignment. Each mmapped
 +        chunk is trailed by the first two fields of a fake next-chunk
 +        for sake of usage checks.
 +
 +*/
 +
 +struct malloc_chunk {
 +  size_t               prev_foot;  /* Size of previous chunk (if free).  */
 +  size_t               head;       /* Size and inuse bits. */
 +  struct malloc_chunk* fd;         /* double links -- used only if free. */
 +  struct malloc_chunk* bk;
 +};
 +
 +typedef struct malloc_chunk  mchunk;
 +typedef struct malloc_chunk* mchunkptr;
 +typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */
 +typedef unsigned int bindex_t;         /* Described below */
 +typedef unsigned int binmap_t;         /* Described below */
 +typedef unsigned int flag_t;           /* The type of various bit flag sets */
 +
 +/* ------------------- Chunks sizes and alignments ----------------------- */
 +
 +#define MCHUNK_SIZE         (sizeof(mchunk))
 +
 +#if FOOTERS
 +#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)
 +#else /* FOOTERS */
 +#define CHUNK_OVERHEAD      (SIZE_T_SIZE)
 +#endif /* FOOTERS */
 +
 +/* MMapped chunks need a second word of overhead ... */
 +#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
 +/* ... and additional padding for fake next-chunk at foot */
 +#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)
 +
 +/* The smallest size we can malloc is an aligned minimal chunk */
 +#define MIN_CHUNK_SIZE\
 +  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
 +
 +/* conversion from malloc headers to user pointers, and back */
 +#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))
 +#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
 +/* chunk associated with aligned address A */
 +#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))
 +
 +/* Bounds on request (not chunk) sizes. */
 +#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)
 +#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
 +
 +/* pad request bytes into a usable size */
 +#define pad_request(req) \
 +   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
 +
 +/* pad request, checking for minimum (but not maximum) */
 +#define request2size(req) \
 +  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
 +
 +
 +/* ------------------ Operations on head and foot fields ----------------- */
 +
 +/*
 +  The head field of a chunk is or'ed with PINUSE_BIT when previous
 +  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
 +  use. If the chunk was obtained with mmap, the prev_foot field has
 +  IS_MMAPPED_BIT set, otherwise holding the offset of the base of the
 +  mmapped region to the base of the chunk.
 +*/
 +
 +#define PINUSE_BIT          (SIZE_T_ONE)
 +#define CINUSE_BIT          (SIZE_T_TWO)
 +#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)
 +
 +/* Head value for fenceposts */
 +#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)
 +
 +/* extraction of fields from head words */
 +#define cinuse(p)           ((p)->head & CINUSE_BIT)
 +#define pinuse(p)           ((p)->head & PINUSE_BIT)
 +#define chunksize(p)        ((p)->head & ~(INUSE_BITS))
 +
 +#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)
 +#define clear_cinuse(p)     ((p)->head &= ~CINUSE_BIT)
 +
 +/* Treat space at ptr +/- offset as a chunk */
 +#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
 +#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
 +
 +/* Ptr to next or previous physical malloc_chunk. */
 +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS)))
 +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
 +
 +/* extract next chunk's pinuse bit */
 +#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)
 +
 +/* Get/set size at footer */
 +#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)
 +#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
 +
 +/* Set size, pinuse bit, and foot */
 +#define set_size_and_pinuse_of_free_chunk(p, s)\
 +  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
 +
 +/* Set size, pinuse bit, foot, and clear next pinuse */
 +#define set_free_with_pinuse(p, s, n)\
 +  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
 +
 +#define is_mmapped(p)\
 +  (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT))
 +
 +/* Get the internal overhead associated with chunk p */
 +#define overhead_for(p)\
 + (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
 +
 +/* Return true if malloced space is not necessarily cleared */
 +#if MMAP_CLEARS
 +#define calloc_must_clear(p) (!is_mmapped(p))
 +#else /* MMAP_CLEARS */
 +#define calloc_must_clear(p) (1)
 +#endif /* MMAP_CLEARS */
 +
 +/* ---------------------- Overlaid data structures ----------------------- */
 +
 +/*
 +  When chunks are not in use, they are treated as nodes of either
 +  lists or trees.
 +
 +  "Small"  chunks are stored in circular doubly-linked lists, and look
 +  like this:
 +
 +    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Size of previous chunk                            |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +    `head:' |             Size of chunk, in bytes                         |P|
 +      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Forward pointer to next chunk in list             |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Back pointer to previous chunk in list            |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Unused space (may be 0 bytes long)                .
 +            .                                                               .
 +            .                                                               |
 +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +    `foot:' |             Size of chunk, in bytes                           |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +
 +  Larger chunks are kept in a form of bitwise digital trees (aka
 +  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for
 +  free chunks greater than 256 bytes, their size doesn't impose any
 +  constraints on user chunk sizes.  Each node looks like:
 +
 +    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Size of previous chunk                            |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +    `head:' |             Size of chunk, in bytes                         |P|
 +      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Forward pointer to next chunk of same size        |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Back pointer to previous chunk of same size       |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Pointer to left child (child[0])                  |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Pointer to right child (child[1])                 |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Pointer to parent                                 |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             bin index of this chunk                           |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +            |             Unused space                                      .
 +            .                                                               |
 +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +    `foot:' |             Size of chunk, in bytes                           |
 +            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 +
 +  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks
 +  of the same size are arranged in a circularly-linked list, with only
 +  the oldest chunk (the next to be used, in our FIFO ordering)
 +  actually in the tree.  (Tree members are distinguished by a non-null
 +  parent pointer.)  If a chunk with the same size an an existing node
 +  is inserted, it is linked off the existing node using pointers that
 +  work in the same way as fd/bk pointers of small chunks.
 +
 +  Each tree contains a power of 2 sized range of chunk sizes (the
 +  smallest is 0x100 <= x < 0x180), which is is divided in half at each
 +  tree level, with the chunks in the smaller half of the range (0x100
 +  <= x < 0x140 for the top nose) in the left subtree and the larger
 +  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,
 +  done by inspecting individual bits.
 +
 +  Using these rules, each node's left subtree contains all smaller
 +  sizes than its right subtree.  However, the node at the root of each
 +  subtree has no particular ordering relationship to either.  (The
 +  dividing line between the subtree sizes is based on trie relation.)
 +  If we remove the last chunk of a given size from the interior of the
 +  tree, we need to replace it with a leaf node.  The tree ordering
 +  rules permit a node to be replaced by any leaf below it.
 +
 +  The smallest chunk in a tree (a common operation in a best-fit
 +  allocator) can be found by walking a path to the leftmost leaf in
 +  the tree.  Unlike a usual binary tree, where we follow left child
 +  pointers until we reach a null, here we follow the right child
 +  pointer any time the left one is null, until we reach a leaf with
 +  both child pointers null. The smallest chunk in the tree will be
 +  somewhere along that path.
 +
 +  The worst case number of steps to add, find, or remove a node is
 +  bounded by the number of bits differentiating chunks within
 +  bins. Under current bin calculations, this ranges from 6 up to 21
 +  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
 +  is of course much better.
 +*/
 +
 +struct malloc_tree_chunk {
 +  /* The first four fields must be compatible with malloc_chunk */
 +  size_t                    prev_foot;
 +  size_t                    head;
 +  struct malloc_tree_chunk* fd;
 +  struct malloc_tree_chunk* bk;
 +
 +  struct malloc_tree_chunk* child[2];
 +  struct malloc_tree_chunk* parent;
 +  bindex_t                  index;
 +};
 +
 +typedef struct malloc_tree_chunk  tchunk;
 +typedef struct malloc_tree_chunk* tchunkptr;
 +typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
 +
 +/* A little helper macro for trees */
 +#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
 +
 +/* ----------------------------- Segments -------------------------------- */
 +
 +/*
 +  Each malloc space may include non-contiguous segments, held in a
 +  list headed by an embedded malloc_segment record representing the
 +  top-most space. Segments also include flags holding properties of
 +  the space. Large chunks that are directly allocated by mmap are not
 +  included in this list. They are instead independently created and
 +  destroyed without otherwise keeping track of them.
 +
 +  Segment management mainly comes into play for spaces allocated by
 +  MMAP.  Any call to MMAP might or might not return memory that is
 +  adjacent to an existing segment.  MORECORE normally contiguously
 +  extends the current space, so this space is almost always adjacent,
 +  which is simpler and faster to deal with. (This is why MORECORE is
 +  used preferentially to MMAP when both are available -- see
 +  sys_alloc.)  When allocating using MMAP, we don't use any of the
 +  hinting mechanisms (inconsistently) supported in various
 +  implementations of unix mmap, or distinguish reserving from
 +  committing memory. Instead, we just ask for space, and exploit
 +  contiguity when we get it.  It is probably possible to do
 +  better than this on some systems, but no general scheme seems
 +  to be significantly better.
 +
 +  Management entails a simpler variant of the consolidation scheme
 +  used for chunks to reduce fragmentation -- new adjacent memory is
 +  normally prepended or appended to an existing segment. However,
 +  there are limitations compared to chunk consolidation that mostly
 +  reflect the fact that segment processing is relatively infrequent
 +  (occurring only when getting memory from system) and that we
 +  don't expect to have huge numbers of segments:
 +
 +  * Segments are not indexed, so traversal requires linear scans.  (It
 +    would be possible to index these, but is not worth the extra
 +    overhead and complexity for most programs on most platforms.)
 +  * New segments are only appended to old ones when holding top-most
 +    memory; if they cannot be prepended to others, they are held in
 +    different segments.
 +
 +  Except for the top-most segment of an mstate, each segment record
 +  is kept at the tail of its segment. Segments are added by pushing
 +  segment records onto the list headed by &mstate.seg for the
 +  containing mstate.
 +
 +  Segment flags control allocation/merge/deallocation policies:
 +  * If EXTERN_BIT set, then we did not allocate this segment,
 +    and so should not try to deallocate or merge with others.
 +    (This currently holds only for the initial segment passed
 +    into create_mspace_with_base.)
 +  * If IS_MMAPPED_BIT set, the segment may be merged with
 +    other surrounding mmapped segments and trimmed/de-allocated
 +    using munmap.
 +  * If neither bit is set, then the segment was obtained using
 +    MORECORE so can be merged with surrounding MORECORE'd segments
 +    and deallocated/trimmed using MORECORE with negative arguments.
 +*/
 +
 +struct malloc_segment {
 +  char*        base;             /* base address */
 +  size_t       size;             /* allocated size */
 +  struct malloc_segment* next;   /* ptr to next segment */
 +#if FFI_MMAP_EXEC_WRIT
 +  /* The mmap magic is supposed to store the address of the executable
 +     segment at the very end of the requested block.  */
 +
 +# define mmap_exec_offset(b,s) (*(ptrdiff_t*)((b)+(s)-sizeof(ptrdiff_t)))
 +
 +  /* We can only merge segments if their corresponding executable
 +     segments are at identical offsets.  */
 +# define check_segment_merge(S,b,s) \
 +  (mmap_exec_offset((b),(s)) == (S)->exec_offset)
 +
 +# define add_segment_exec_offset(p,S) ((char*)(p) + (S)->exec_offset)
 +# define sub_segment_exec_offset(p,S) ((char*)(p) - (S)->exec_offset)
 +
 +  /* The removal of sflags only works with HAVE_MORECORE == 0.  */
 +
 +# define get_segment_flags(S)   (IS_MMAPPED_BIT)
 +# define set_segment_flags(S,v) \
 +  (((v) != IS_MMAPPED_BIT) ? (ABORT, (v)) :                           \
 +   (((S)->exec_offset =                                                       \
 +     mmap_exec_offset((S)->base, (S)->size)),                         \
 +    (mmap_exec_offset((S)->base + (S)->exec_offset, (S)->size) !=     \
 +     (S)->exec_offset) ? (ABORT, (v)) :                                       \
 +   (mmap_exec_offset((S)->base, (S)->size) = 0), (v)))
 +
 +  /* We use an offset here, instead of a pointer, because then, when
 +     base changes, we don't have to modify this.  On architectures
 +     with segmented addresses, this might not work.  */
 +  ptrdiff_t    exec_offset;
 +#else
 +
 +# define get_segment_flags(S)   ((S)->sflags)
 +# define set_segment_flags(S,v) ((S)->sflags = (v))
 +# define check_segment_merge(S,b,s) (1)
 +
 +  flag_t       sflags;           /* mmap and extern flag */
 +#endif
 +};
 +
 +#define is_mmapped_segment(S)  (get_segment_flags(S) & IS_MMAPPED_BIT)
 +#define is_extern_segment(S)   (get_segment_flags(S) & EXTERN_BIT)
 +
 +typedef struct malloc_segment  msegment;
 +typedef struct malloc_segment* msegmentptr;
 +
 +/* ---------------------------- malloc_state ----------------------------- */
 +
 +/*
 +   A malloc_state holds all of the bookkeeping for a space.
 +   The main fields are:
 +
 +  Top
 +    The topmost chunk of the currently active segment. Its size is
 +    cached in topsize.  The actual size of topmost space is
 +    topsize+TOP_FOOT_SIZE, which includes space reserved for adding
 +    fenceposts and segment records if necessary when getting more
 +    space from the system.  The size at which to autotrim top is
 +    cached from mparams in trim_check, except that it is disabled if
 +    an autotrim fails.
 +
 +  Designated victim (dv)
 +    This is the preferred chunk for servicing small requests that
 +    don't have exact fits.  It is normally the chunk split off most
 +    recently to service another small request.  Its size is cached in
 +    dvsize. The link fields of this chunk are not maintained since it
 +    is not kept in a bin.
 +
 +  SmallBins
 +    An array of bin headers for free chunks.  These bins hold chunks
 +    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
 +    chunks of all the same size, spaced 8 bytes apart.  To simplify
 +    use in double-linked lists, each bin header acts as a malloc_chunk
 +    pointing to the real first node, if it exists (else pointing to
 +    itself).  This avoids special-casing for headers.  But to avoid
 +    waste, we allocate only the fd/bk pointers of bins, and then use
 +    repositioning tricks to treat these as the fields of a chunk.
 +
 +  TreeBins
 +    Treebins are pointers to the roots of trees holding a range of
 +    sizes. There are 2 equally spaced treebins for each power of two
 +    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
 +    larger.
 +
 +  Bin maps
 +    There is one bit map for small bins ("smallmap") and one for
 +    treebins ("treemap).  Each bin sets its bit when non-empty, and
 +    clears the bit when empty.  Bit operations are then used to avoid
 +    bin-by-bin searching -- nearly all "search" is done without ever
 +    looking at bins that won't be selected.  The bit maps
 +    conservatively use 32 bits per map word, even if on 64bit system.
 +    For a good description of some of the bit-based techniques used
 +    here, see Henry S. Warren Jr's book "Hacker's Delight" (and
 +    supplement at http://hackersdelight.org/). Many of these are
 +    intended to reduce the branchiness of paths through malloc etc, as
 +    well as to reduce the number of memory locations read or written.
 +
 +  Segments
 +    A list of segments headed by an embedded malloc_segment record
 +    representing the initial space.
 +
 +  Address check support
 +    The least_addr field is the least address ever obtained from
 +    MORECORE or MMAP. Attempted frees and reallocs of any address less
 +    than this are trapped (unless INSECURE is defined).
 +
 +  Magic tag
 +    A cross-check field that should always hold same value as mparams.magic.
 +
 +  Flags
 +    Bits recording whether to use MMAP, locks, or contiguous MORECORE
 +
 +  Statistics
 +    Each space keeps track of current and maximum system memory
 +    obtained via MORECORE or MMAP.
 +
 +  Locking
 +    If USE_LOCKS is defined, the "mutex" lock is acquired and released
 +    around every public call using this mspace.
 +*/
 +
 +/* Bin types, widths and sizes */
 +#define NSMALLBINS        (32U)
 +#define NTREEBINS         (32U)
 +#define SMALLBIN_SHIFT    (3U)
 +#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)
 +#define TREEBIN_SHIFT     (8U)
 +#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)
 +#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)
 +#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
 +
 +struct malloc_state {
 +  binmap_t   smallmap;
 +  binmap_t   treemap;
 +  size_t     dvsize;
 +  size_t     topsize;
 +  char*      least_addr;
 +  mchunkptr  dv;
 +  mchunkptr  top;
 +  size_t     trim_check;
 +  size_t     magic;
 +  mchunkptr  smallbins[(NSMALLBINS+1)*2];
 +  tbinptr    treebins[NTREEBINS];
 +  size_t     footprint;
 +  size_t     max_footprint;
 +  flag_t     mflags;
 +#if USE_LOCKS
 +  MLOCK_T    mutex;     /* locate lock among fields that rarely change */
 +#endif /* USE_LOCKS */
 +  msegment   seg;
 +};
 +
 +typedef struct malloc_state*    mstate;
 +
 +/* ------------- Global malloc_state and malloc_params ------------------- */
 +
 +/*
 +  malloc_params holds global properties, including those that can be
 +  dynamically set using mallopt. There is a single instance, mparams,
 +  initialized in init_mparams.
 +*/
 +
 +struct malloc_params {
 +  size_t magic;
 +  size_t page_size;
 +  size_t granularity;
 +  size_t mmap_threshold;
 +  size_t trim_threshold;
 +  flag_t default_mflags;
 +};
 +
 +static struct malloc_params mparams;
 +
 +/* The global malloc_state used for all non-"mspace" calls */
 +static struct malloc_state _gm_;
 +#define gm                 (&_gm_)
 +#define is_global(M)       ((M) == &_gm_)
 +#define is_initialized(M)  ((M)->top != 0)
 +
 +/* -------------------------- system alloc setup ------------------------- */
 +
 +/* Operations on mflags */
 +
 +#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)
 +#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)
 +#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)
 +
 +#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)
 +#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)
 +#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)
 +
 +#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)
 +#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)
 +
 +#define set_lock(M,L)\
 + ((M)->mflags = (L)?\
 +  ((M)->mflags | USE_LOCK_BIT) :\
 +  ((M)->mflags & ~USE_LOCK_BIT))
 +
 +/* page-align a size */
 +#define page_align(S)\
 + (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE))
 +
 +/* granularity-align a size */
 +#define granularity_align(S)\
 +  (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE))
 +
 +#define is_page_aligned(S)\
 +   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
 +#define is_granularity_aligned(S)\
 +   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
 +
 +/*  True if segment S holds address A */
 +#define segment_holds(S, A)\
 +  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
 +
 +/* Return segment holding given address */
 +static msegmentptr segment_holding(mstate m, char* addr) {
 +  msegmentptr sp = &m->seg;
 +  for (;;) {
 +    if (addr >= sp->base && addr < sp->base + sp->size)
 +      return sp;
 +    if ((sp = sp->next) == 0)
 +      return 0;
 +  }
 +}
 +
 +/* Return true if segment contains a segment link */
 +static int has_segment_link(mstate m, msegmentptr ss) {
 +  msegmentptr sp = &m->seg;
 +  for (;;) {
 +    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
 +      return 1;
 +    if ((sp = sp->next) == 0)
 +      return 0;
 +  }
 +}
 +
 +#ifndef MORECORE_CANNOT_TRIM
 +#define should_trim(M,s)  ((s) > (M)->trim_check)
 +#else  /* MORECORE_CANNOT_TRIM */
 +#define should_trim(M,s)  (0)
 +#endif /* MORECORE_CANNOT_TRIM */
 +
 +/*
 +  TOP_FOOT_SIZE is padding at the end of a segment, including space
 +  that may be needed to place segment records and fenceposts when new
 +  noncontiguous segments are added.
 +*/
 +#define TOP_FOOT_SIZE\
 +  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
 +
 +
 +/* -------------------------------  Hooks -------------------------------- */
 +
 +/*
 +  PREACTION should be defined to return 0 on success, and nonzero on
 +  failure. If you are not using locking, you can redefine these to do
 +  anything you like.
 +*/
 +
 +#if USE_LOCKS
 +
 +/* Ensure locks are initialized */
 +#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams())
 +
 +#define PREACTION(M)  ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
 +#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
 +#else /* USE_LOCKS */
 +
 +#ifndef PREACTION
 +#define PREACTION(M) (0)
 +#endif  /* PREACTION */
 +
 +#ifndef POSTACTION
 +#define POSTACTION(M)
 +#endif  /* POSTACTION */
 +
 +#endif /* USE_LOCKS */
 +
 +/*
 +  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
 +  USAGE_ERROR_ACTION is triggered on detected bad frees and
 +  reallocs. The argument p is an address that might have triggered the
 +  fault. It is ignored by the two predefined actions, but might be
 +  useful in custom actions that try to help diagnose errors.
 +*/
 +
 +#if PROCEED_ON_ERROR
 +
 +/* A count of the number of corruption errors causing resets */
 +int malloc_corruption_error_count;
 +
 +/* default corruption action */
 +static void reset_on_error(mstate m);
 +
 +#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)
 +#define USAGE_ERROR_ACTION(m, p)
 +
 +#else /* PROCEED_ON_ERROR */
 +
 +#ifndef CORRUPTION_ERROR_ACTION
 +#define CORRUPTION_ERROR_ACTION(m) ABORT
 +#endif /* CORRUPTION_ERROR_ACTION */
 +
 +#ifndef USAGE_ERROR_ACTION
 +#define USAGE_ERROR_ACTION(m,p) ABORT
 +#endif /* USAGE_ERROR_ACTION */
 +
 +#endif /* PROCEED_ON_ERROR */
 +
 +/* -------------------------- Debugging setup ---------------------------- */
 +
 +#if ! DEBUG
 +
 +#define check_free_chunk(M,P)
 +#define check_inuse_chunk(M,P)
 +#define check_malloced_chunk(M,P,N)
 +#define check_mmapped_chunk(M,P)
 +#define check_malloc_state(M)
 +#define check_top_chunk(M,P)
 +
 +#else /* DEBUG */
 +#define check_free_chunk(M,P)       do_check_free_chunk(M,P)
 +#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)
 +#define check_top_chunk(M,P)        do_check_top_chunk(M,P)
 +#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
 +#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)
 +#define check_malloc_state(M)       do_check_malloc_state(M)
 +
 +static void   do_check_any_chunk(mstate m, mchunkptr p);
 +static void   do_check_top_chunk(mstate m, mchunkptr p);
 +static void   do_check_mmapped_chunk(mstate m, mchunkptr p);
 +static void   do_check_inuse_chunk(mstate m, mchunkptr p);
 +static void   do_check_free_chunk(mstate m, mchunkptr p);
 +static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);
 +static void   do_check_tree(mstate m, tchunkptr t);
 +static void   do_check_treebin(mstate m, bindex_t i);
 +static void   do_check_smallbin(mstate m, bindex_t i);
 +static void   do_check_malloc_state(mstate m);
 +static int    bin_find(mstate m, mchunkptr x);
 +static size_t traverse_and_check(mstate m);
 +#endif /* DEBUG */
 +
 +/* ---------------------------- Indexing Bins ---------------------------- */
 +
 +#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
 +#define small_index(s)      ((s)  >> SMALLBIN_SHIFT)
 +#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)
 +#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))
 +
 +/* addressing by index. See above about smallbin repositioning */
 +#define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
 +#define treebin_at(M,i)     (&((M)->treebins[i]))
 +
 +/* assign tree index for size S to variable I */
 +#if defined(__GNUC__) && defined(i386)
 +#define compute_tree_index(S, I)\
 +{\
 +  size_t X = S >> TREEBIN_SHIFT;\
 +  if (X == 0)\
 +    I = 0;\
 +  else if (X > 0xFFFF)\
 +    I = NTREEBINS-1;\
 +  else {\
 +    unsigned int K;\
 +    __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm"  (X));\
 +    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
 +  }\
 +}
 +#else /* GNUC */
 +#define compute_tree_index(S, I)\
 +{\
 +  size_t X = S >> TREEBIN_SHIFT;\
 +  if (X == 0)\
 +    I = 0;\
 +  else if (X > 0xFFFF)\
 +    I = NTREEBINS-1;\
 +  else {\
 +    unsigned int Y = (unsigned int)X;\
 +    unsigned int N = ((Y - 0x100) >> 16) & 8;\
 +    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
 +    N += K;\
 +    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
 +    K = 14 - N + ((Y <<= K) >> 15);\
 +    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
 +  }\
 +}
 +#endif /* GNUC */
 +
 +/* Bit representing maximum resolved size in a treebin at i */
 +#define bit_for_tree_index(i) \
 +   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
 +
 +/* Shift placing maximum resolved bit in a treebin at i as sign bit */
 +#define leftshift_for_tree_index(i) \
 +   ((i == NTREEBINS-1)? 0 : \
 +    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
 +
 +/* The size of the smallest chunk held in bin with index i */
 +#define minsize_for_tree_index(i) \
 +   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \
 +   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
 +
 +
 +/* ------------------------ Operations on bin maps ----------------------- */
 +
 +/* bit corresponding to given index */
 +#define idx2bit(i)              ((binmap_t)(1) << (i))
 +
 +/* Mark/Clear bits with given index */
 +#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))
 +#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))
 +#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))
 +
 +#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))
 +#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))
 +#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))
 +
 +/* index corresponding to given bit */
 +
 +#if defined(__GNUC__) && defined(i386)
 +#define compute_bit2idx(X, I)\
 +{\
 +  unsigned int J;\
 +  __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\
 +  I = (bindex_t)J;\
 +}
 +
 +#else /* GNUC */
 +#if  USE_BUILTIN_FFS
 +#define compute_bit2idx(X, I) I = ffs(X)-1
 +
 +#else /* USE_BUILTIN_FFS */
 +#define compute_bit2idx(X, I)\
 +{\
 +  unsigned int Y = X - 1;\
 +  unsigned int K = Y >> (16-4) & 16;\
 +  unsigned int N = K;        Y >>= K;\
 +  N += K = Y >> (8-3) &  8;  Y >>= K;\
 +  N += K = Y >> (4-2) &  4;  Y >>= K;\
 +  N += K = Y >> (2-1) &  2;  Y >>= K;\
 +  N += K = Y >> (1-0) &  1;  Y >>= K;\
 +  I = (bindex_t)(N + Y);\
 +}
 +#endif /* USE_BUILTIN_FFS */
 +#endif /* GNUC */
 +
 +/* isolate the least set bit of a bitmap */
 +#define least_bit(x)         ((x) & -(x))
 +
 +/* mask with all bits to left of least bit of x on */
 +#define left_bits(x)         ((x<<1) | -(x<<1))
 +
 +/* mask with all bits to left of or equal to least bit of x on */
 +#define same_or_left_bits(x) ((x) | -(x))
 +
 +
 +/* ----------------------- Runtime Check Support ------------------------- */
 +
 +/*
 +  For security, the main invariant is that malloc/free/etc never
 +  writes to a static address other than malloc_state, unless static
 +  malloc_state itself has been corrupted, which cannot occur via
 +  malloc (because of these checks). In essence this means that we
 +  believe all pointers, sizes, maps etc held in malloc_state, but
 +  check all of those linked or offsetted from other embedded data
 +  structures.  These checks are interspersed with main code in a way
 +  that tends to minimize their run-time cost.
 +
 +  When FOOTERS is defined, in addition to range checking, we also
 +  verify footer fields of inuse chunks, which can be used guarantee
 +  that the mstate controlling malloc/free is intact.  This is a
 +  streamlined version of the approach described by William Robertson
 +  et al in "Run-time Detection of Heap-based Overflows" LISA'03
 +  http://www.usenix.org/events/lisa03/tech/robertson.html The footer
 +  of an inuse chunk holds the xor of its mstate and a random seed,
 +  that is checked upon calls to free() and realloc().  This is
 +  (probablistically) unguessable from outside the program, but can be
 +  computed by any code successfully malloc'ing any chunk, so does not
 +  itself provide protection against code that has already broken
 +  security through some other means.  Unlike Robertson et al, we
 +  always dynamically check addresses of all offset chunks (previous,
 +  next, etc). This turns out to be cheaper than relying on hashes.
 +*/
 +
 +#if !INSECURE
 +/* Check if address a is at least as high as any from MORECORE or MMAP */
 +#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
 +/* Check if address of next chunk n is higher than base chunk p */
 +#define ok_next(p, n)    ((char*)(p) < (char*)(n))
 +/* Check if p has its cinuse bit on */
 +#define ok_cinuse(p)     cinuse(p)
 +/* Check if p has its pinuse bit on */
 +#define ok_pinuse(p)     pinuse(p)
 +
 +#else /* !INSECURE */
 +#define ok_address(M, a) (1)
 +#define ok_next(b, n)    (1)
 +#define ok_cinuse(p)     (1)
 +#define ok_pinuse(p)     (1)
 +#endif /* !INSECURE */
 +
 +#if (FOOTERS && !INSECURE)
 +/* Check if (alleged) mstate m has expected magic field */
 +#define ok_magic(M)      ((M)->magic == mparams.magic)
 +#else  /* (FOOTERS && !INSECURE) */
 +#define ok_magic(M)      (1)
 +#endif /* (FOOTERS && !INSECURE) */
 +
 +
 +/* In gcc, use __builtin_expect to minimize impact of checks */
 +#if !INSECURE
 +#if defined(__GNUC__) && __GNUC__ >= 3
 +#define RTCHECK(e)  __builtin_expect(e, 1)
 +#else /* GNUC */
 +#define RTCHECK(e)  (e)
 +#endif /* GNUC */
 +#else /* !INSECURE */
 +#define RTCHECK(e)  (1)
 +#endif /* !INSECURE */
 +
 +/* macros to set up inuse chunks with or without footers */
 +
 +#if !FOOTERS
 +
 +#define mark_inuse_foot(M,p,s)
 +
 +/* Set cinuse bit and pinuse bit of next chunk */
 +#define set_inuse(M,p,s)\
 +  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
 +  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
 +
 +/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
 +#define set_inuse_and_pinuse(M,p,s)\
 +  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
 +  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
 +
 +/* Set size, cinuse and pinuse bit of this chunk */
 +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
 +  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
 +
 +#else /* FOOTERS */
 +
 +/* Set foot of inuse chunk to be xor of mstate and seed */
 +#define mark_inuse_foot(M,p,s)\
 +  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
 +
 +#define get_mstate_for(p)\
 +  ((mstate)(((mchunkptr)((char*)(p) +\
 +    (chunksize(p))))->prev_foot ^ mparams.magic))
 +
 +#define set_inuse(M,p,s)\
 +  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
 +  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
 +  mark_inuse_foot(M,p,s))
 +
 +#define set_inuse_and_pinuse(M,p,s)\
 +  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
 +  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
 + mark_inuse_foot(M,p,s))
 +
 +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
 +  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
 +  mark_inuse_foot(M, p, s))
 +
 +#endif /* !FOOTERS */
 +
 +/* ---------------------------- setting mparams -------------------------- */
 +
 +/* Initialize mparams */
 +static int init_mparams(void) {
 +  if (mparams.page_size == 0) {
 +    size_t s;
 +
 +    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
 +    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
 +#if MORECORE_CONTIGUOUS
 +    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
 +#else  /* MORECORE_CONTIGUOUS */
 +    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
 +#endif /* MORECORE_CONTIGUOUS */
 +
 +#if (FOOTERS && !INSECURE)
 +    {
 +#if USE_DEV_RANDOM
 +      int fd;
 +      unsigned char buf[sizeof(size_t)];
 +      /* Try to use /dev/urandom, else fall back on using time */
 +      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
 +          read(fd, buf, sizeof(buf)) == sizeof(buf)) {
 +        s = *((size_t *) buf);
 +        close(fd);
 +      }
 +      else
 +#endif /* USE_DEV_RANDOM */
 +        s = (size_t)(time(0) ^ (size_t)0x55555555U);
 +
 +      s |= (size_t)8U;    /* ensure nonzero */
 +      s &= ~(size_t)7U;   /* improve chances of fault for bad values */
 +
 +    }
 +#else /* (FOOTERS && !INSECURE) */
 +    s = (size_t)0x58585858U;
 +#endif /* (FOOTERS && !INSECURE) */
 +    ACQUIRE_MAGIC_INIT_LOCK();
 +    if (mparams.magic == 0) {
 +      mparams.magic = s;
 +      /* Set up lock for main malloc area */
 +      INITIAL_LOCK(&gm->mutex);
 +      gm->mflags = mparams.default_mflags;
 +    }
 +    RELEASE_MAGIC_INIT_LOCK();
 +
 +#ifndef WIN32
 +    mparams.page_size = malloc_getpagesize;
 +    mparams.granularity = ((DEFAULT_GRANULARITY != 0)?
 +                           DEFAULT_GRANULARITY : mparams.page_size);
 +#else /* WIN32 */
 +    {
 +      SYSTEM_INFO system_info;
 +      GetSystemInfo(&system_info);
 +      mparams.page_size = system_info.dwPageSize;
 +      mparams.granularity = system_info.dwAllocationGranularity;
 +    }
 +#endif /* WIN32 */
 +
 +    /* Sanity-check configuration:
 +       size_t must be unsigned and as wide as pointer type.
 +       ints must be at least 4 bytes.
 +       alignment must be at least 8.
 +       Alignment, min chunk size, and page size must all be powers of 2.
 +    */
 +    if ((sizeof(size_t) != sizeof(char*)) ||
 +        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||
 +        (sizeof(int) < 4)  ||
 +        (MALLOC_ALIGNMENT < (size_t)8U) ||
 +        ((MALLOC_ALIGNMENT    & (MALLOC_ALIGNMENT-SIZE_T_ONE))    != 0) ||
 +        ((MCHUNK_SIZE         & (MCHUNK_SIZE-SIZE_T_ONE))         != 0) ||
 +        ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) ||
 +        ((mparams.page_size   & (mparams.page_size-SIZE_T_ONE))   != 0))
 +      ABORT;
 +  }
 +  return 0;
 +}
 +
 +/* support for mallopt */
 +static int change_mparam(int param_number, int value) {
 +  size_t val = (size_t)value;
 +  init_mparams();
 +  switch(param_number) {
 +  case M_TRIM_THRESHOLD:
 +    mparams.trim_threshold = val;
 +    return 1;
 +  case M_GRANULARITY:
 +    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
 +      mparams.granularity = val;
 +      return 1;
 +    }
 +    else
 +      return 0;
 +  case M_MMAP_THRESHOLD:
 +    mparams.mmap_threshold = val;
 +    return 1;
 +  default:
 +    return 0;
 +  }
 +}
 +
 +#if DEBUG
 +/* ------------------------- Debugging Support --------------------------- */
 +
 +/* Check properties of any chunk, whether free, inuse, mmapped etc  */
 +static void do_check_any_chunk(mstate m, mchunkptr p) {
 +  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
 +  assert(ok_address(m, p));
 +}
 +
 +/* Check properties of top chunk */
 +static void do_check_top_chunk(mstate m, mchunkptr p) {
 +  msegmentptr sp = segment_holding(m, (char*)p);
 +  size_t  sz = chunksize(p);
 +  assert(sp != 0);
 +  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
 +  assert(ok_address(m, p));
 +  assert(sz == m->topsize);
 +  assert(sz > 0);
 +  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
 +  assert(pinuse(p));
 +  assert(!next_pinuse(p));
 +}
 +
 +/* Check properties of (inuse) mmapped chunks */
 +static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
 +  size_t  sz = chunksize(p);
 +  size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD);
 +  assert(is_mmapped(p));
 +  assert(use_mmap(m));
 +  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
 +  assert(ok_address(m, p));
 +  assert(!is_small(sz));
 +  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
 +  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
 +  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
 +}
 +
 +/* Check properties of inuse chunks */
 +static void do_check_inuse_chunk(mstate m, mchunkptr p) {
 +  do_check_any_chunk(m, p);
 +  assert(cinuse(p));
 +  assert(next_pinuse(p));
 +  /* If not pinuse and not mmapped, previous chunk has OK offset */
 +  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
 +  if (is_mmapped(p))
 +    do_check_mmapped_chunk(m, p);
 +}
 +
 +/* Check properties of free chunks */
 +static void do_check_free_chunk(mstate m, mchunkptr p) {
 +  size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);
 +  mchunkptr next = chunk_plus_offset(p, sz);
 +  do_check_any_chunk(m, p);
 +  assert(!cinuse(p));
 +  assert(!next_pinuse(p));
 +  assert (!is_mmapped(p));
 +  if (p != m->dv && p != m->top) {
 +    if (sz >= MIN_CHUNK_SIZE) {
 +      assert((sz & CHUNK_ALIGN_MASK) == 0);
 +      assert(is_aligned(chunk2mem(p)));
 +      assert(next->prev_foot == sz);
 +      assert(pinuse(p));
 +      assert (next == m->top || cinuse(next));
 +      assert(p->fd->bk == p);
 +      assert(p->bk->fd == p);
 +    }
 +    else  /* markers are always of size SIZE_T_SIZE */
 +      assert(sz == SIZE_T_SIZE);
 +  }
 +}
 +
 +/* Check properties of malloced chunks at the point they are malloced */
 +static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
 +  if (mem != 0) {
 +    mchunkptr p = mem2chunk(mem);
 +    size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);
 +    do_check_inuse_chunk(m, p);
 +    assert((sz & CHUNK_ALIGN_MASK) == 0);
 +    assert(sz >= MIN_CHUNK_SIZE);
 +    assert(sz >= s);
 +    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
 +    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
 +  }
 +}
 +
 +/* Check a tree and its subtrees.  */
 +static void do_check_tree(mstate m, tchunkptr t) {
 +  tchunkptr head = 0;
 +  tchunkptr u = t;
 +  bindex_t tindex = t->index;
 +  size_t tsize = chunksize(t);
 +  bindex_t idx;
 +  compute_tree_index(tsize, idx);
 +  assert(tindex == idx);
 +  assert(tsize >= MIN_LARGE_SIZE);
 +  assert(tsize >= minsize_for_tree_index(idx));
 +  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
 +
 +  do { /* traverse through chain of same-sized nodes */
 +    do_check_any_chunk(m, ((mchunkptr)u));
 +    assert(u->index == tindex);
 +    assert(chunksize(u) == tsize);
 +    assert(!cinuse(u));
 +    assert(!next_pinuse(u));
 +    assert(u->fd->bk == u);
 +    assert(u->bk->fd == u);
 +    if (u->parent == 0) {
 +      assert(u->child[0] == 0);
 +      assert(u->child[1] == 0);
 +    }
 +    else {
 +      assert(head == 0); /* only one node on chain has parent */
 +      head = u;
 +      assert(u->parent != u);
 +      assert (u->parent->child[0] == u ||
 +              u->parent->child[1] == u ||
 +              *((tbinptr*)(u->parent)) == u);
 +      if (u->child[0] != 0) {
 +        assert(u->child[0]->parent == u);
 +        assert(u->child[0] != u);
 +        do_check_tree(m, u->child[0]);
 +      }
 +      if (u->child[1] != 0) {
 +        assert(u->child[1]->parent == u);
 +        assert(u->child[1] != u);
 +        do_check_tree(m, u->child[1]);
 +      }
 +      if (u->child[0] != 0 && u->child[1] != 0) {
 +        assert(chunksize(u->child[0]) < chunksize(u->child[1]));
 +      }
 +    }
 +    u = u->fd;
 +  } while (u != t);
 +  assert(head != 0);
 +}
 +
 +/*  Check all the chunks in a treebin.  */
 +static void do_check_treebin(mstate m, bindex_t i) {
 +  tbinptr* tb = treebin_at(m, i);
 +  tchunkptr t = *tb;
 +  int empty = (m->treemap & (1U << i)) == 0;
 +  if (t == 0)
 +    assert(empty);
 +  if (!empty)
 +    do_check_tree(m, t);
 +}
 +
 +/*  Check all the chunks in a smallbin.  */
 +static void do_check_smallbin(mstate m, bindex_t i) {
 +  sbinptr b = smallbin_at(m, i);
 +  mchunkptr p = b->bk;
 +  unsigned int empty = (m->smallmap & (1U << i)) == 0;
 +  if (p == b)
 +    assert(empty);
 +  if (!empty) {
 +    for (; p != b; p = p->bk) {
 +      size_t size = chunksize(p);
 +      mchunkptr q;
 +      /* each chunk claims to be free */
 +      do_check_free_chunk(m, p);
 +      /* chunk belongs in bin */
 +      assert(small_index(size) == i);
 +      assert(p->bk == b || chunksize(p->bk) == chunksize(p));
 +      /* chunk is followed by an inuse chunk */
 +      q = next_chunk(p);
 +      if (q->head != FENCEPOST_HEAD)
 +        do_check_inuse_chunk(m, q);
 +    }
 +  }
 +}
 +
 +/* Find x in a bin. Used in other check functions. */
 +static int bin_find(mstate m, mchunkptr x) {
 +  size_t size = chunksize(x);
 +  if (is_small(size)) {
 +    bindex_t sidx = small_index(size);
 +    sbinptr b = smallbin_at(m, sidx);
 +    if (smallmap_is_marked(m, sidx)) {
 +      mchunkptr p = b;
 +      do {
 +        if (p == x)
 +          return 1;
 +      } while ((p = p->fd) != b);
 +    }
 +  }
 +  else {
 +    bindex_t tidx;
 +    compute_tree_index(size, tidx);
 +    if (treemap_is_marked(m, tidx)) {
 +      tchunkptr t = *treebin_at(m, tidx);
 +      size_t sizebits = size << leftshift_for_tree_index(tidx);
 +      while (t != 0 && chunksize(t) != size) {
 +        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
 +        sizebits <<= 1;
 +      }
 +      if (t != 0) {
 +        tchunkptr u = t;
 +        do {
 +          if (u == (tchunkptr)x)
 +            return 1;
 +        } while ((u = u->fd) != t);
 +      }
 +    }
 +  }
 +  return 0;
 +}
 +
 +/* Traverse each chunk and check it; return total */
 +static size_t traverse_and_check(mstate m) {
 +  size_t sum = 0;
 +  if (is_initialized(m)) {
 +    msegmentptr s = &m->seg;
 +    sum += m->topsize + TOP_FOOT_SIZE;
 +    while (s != 0) {
 +      mchunkptr q = align_as_chunk(s->base);
 +      mchunkptr lastq = 0;
 +      assert(pinuse(q));
 +      while (segment_holds(s, q) &&
 +             q != m->top && q->head != FENCEPOST_HEAD) {
 +        sum += chunksize(q);
 +        if (cinuse(q)) {
 +          assert(!bin_find(m, q));
 +          do_check_inuse_chunk(m, q);
 +        }
 +        else {
 +          assert(q == m->dv || bin_find(m, q));
 +          assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */
 +          do_check_free_chunk(m, q);
 +        }
 +        lastq = q;
 +        q = next_chunk(q);
 +      }
 +      s = s->next;
 +    }
 +  }
 +  return sum;
 +}
 +
 +/* Check all properties of malloc_state. */
 +static void do_check_malloc_state(mstate m) {
 +  bindex_t i;
 +  size_t total;
 +  /* check bins */
 +  for (i = 0; i < NSMALLBINS; ++i)
 +    do_check_smallbin(m, i);
 +  for (i = 0; i < NTREEBINS; ++i)
 +    do_check_treebin(m, i);
 +
 +  if (m->dvsize != 0) { /* check dv chunk */
 +    do_check_any_chunk(m, m->dv);
 +    assert(m->dvsize == chunksize(m->dv));
 +    assert(m->dvsize >= MIN_CHUNK_SIZE);
 +    assert(bin_find(m, m->dv) == 0);
 +  }
 +
 +  if (m->top != 0) {   /* check top chunk */
 +    do_check_top_chunk(m, m->top);
 +    assert(m->topsize == chunksize(m->top));
 +    assert(m->topsize > 0);
 +    assert(bin_find(m, m->top) == 0);
 +  }
 +
 +  total = traverse_and_check(m);
 +  assert(total <= m->footprint);
 +  assert(m->footprint <= m->max_footprint);
 +}
 +#endif /* DEBUG */
 +
 +/* ----------------------------- statistics ------------------------------ */
 +
 +#if !NO_MALLINFO
 +static struct mallinfo internal_mallinfo(mstate m) {
 +  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 +  if (!PREACTION(m)) {
 +    check_malloc_state(m);
 +    if (is_initialized(m)) {
 +      size_t nfree = SIZE_T_ONE; /* top always free */
 +      size_t mfree = m->topsize + TOP_FOOT_SIZE;
 +      size_t sum = mfree;
 +      msegmentptr s = &m->seg;
 +      while (s != 0) {
 +        mchunkptr q = align_as_chunk(s->base);
 +        while (segment_holds(s, q) &&
 +               q != m->top && q->head != FENCEPOST_HEAD) {
 +          size_t sz = chunksize(q);
 +          sum += sz;
 +          if (!cinuse(q)) {
 +            mfree += sz;
 +            ++nfree;
 +          }
 +          q = next_chunk(q);
 +        }
 +        s = s->next;
 +      }
 +
 +      nm.arena    = sum;
 +      nm.ordblks  = nfree;
 +      nm.hblkhd   = m->footprint - sum;
 +      nm.usmblks  = m->max_footprint;
 +      nm.uordblks = m->footprint - mfree;
 +      nm.fordblks = mfree;
 +      nm.keepcost = m->topsize;
 +    }
 +
 +    POSTACTION(m);
 +  }
 +  return nm;
 +}
 +#endif /* !NO_MALLINFO */
 +
 +static void internal_malloc_stats(mstate m) {
 +  if (!PREACTION(m)) {
 +    size_t maxfp = 0;
 +    size_t fp = 0;
 +    size_t used = 0;
 +    check_malloc_state(m);
 +    if (is_initialized(m)) {
 +      msegmentptr s = &m->seg;
 +      maxfp = m->max_footprint;
 +      fp = m->footprint;
 +      used = fp - (m->topsize + TOP_FOOT_SIZE);
 +
 +      while (s != 0) {
 +        mchunkptr q = align_as_chunk(s->base);
 +        while (segment_holds(s, q) &&
 +               q != m->top && q->head != FENCEPOST_HEAD) {
 +          if (!cinuse(q))
 +            used -= chunksize(q);
 +          q = next_chunk(q);
 +        }
 +        s = s->next;
 +      }
 +    }
 +
 +    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
 +    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));
 +    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));
 +
 +    POSTACTION(m);
 +  }
 +}
 +
 +/* ----------------------- Operations on smallbins ----------------------- */
 +
 +/*
 +  Various forms of linking and unlinking are defined as macros.  Even
 +  the ones for trees, which are very long but have very short typical
 +  paths.  This is ugly but reduces reliance on inlining support of
 +  compilers.
 +*/
 +
 +/* Link a free chunk into a smallbin  */
 +#define insert_small_chunk(M, P, S) {\
 +  bindex_t I  = small_index(S);\
 +  mchunkptr B = smallbin_at(M, I);\
 +  mchunkptr F = B;\
 +  assert(S >= MIN_CHUNK_SIZE);\
 +  if (!smallmap_is_marked(M, I))\
 +    mark_smallmap(M, I);\
 +  else if (RTCHECK(ok_address(M, B->fd)))\
 +    F = B->fd;\
 +  else {\
 +    CORRUPTION_ERROR_ACTION(M);\
 +  }\
 +  B->fd = P;\
 +  F->bk = P;\
 +  P->fd = F;\
 +  P->bk = B;\
 +}
 +
 +/* Unlink a chunk from a smallbin  */
 +#define unlink_small_chunk(M, P, S) {\
 +  mchunkptr F = P->fd;\
 +  mchunkptr B = P->bk;\
 +  bindex_t I = small_index(S);\
 +  assert(P != B);\
 +  assert(P != F);\
 +  assert(chunksize(P) == small_index2size(I));\
 +  if (F == B)\
 +    clear_smallmap(M, I);\
 +  else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\
 +                   (B == smallbin_at(M,I) || ok_address(M, B)))) {\
 +    F->bk = B;\
 +    B->fd = F;\
 +  }\
 +  else {\
 +    CORRUPTION_ERROR_ACTION(M);\
 +  }\
 +}
 +
 +/* Unlink the first chunk from a smallbin */
 +#define unlink_first_small_chunk(M, B, P, I) {\
 +  mchunkptr F = P->fd;\
 +  assert(P != B);\
 +  assert(P != F);\
 +  assert(chunksize(P) == small_index2size(I));\
 +  if (B == F)\
 +    clear_smallmap(M, I);\
 +  else if (RTCHECK(ok_address(M, F))) {\
 +    B->fd = F;\
 +    F->bk = B;\
 +  }\
 +  else {\
 +    CORRUPTION_ERROR_ACTION(M);\
 +  }\
 +}
 +
 +/* Replace dv node, binning the old one */
 +/* Used only when dvsize known to be small */
 +#define replace_dv(M, P, S) {\
 +  size_t DVS = M->dvsize;\
 +  if (DVS != 0) {\
 +    mchunkptr DV = M->dv;\
 +    assert(is_small(DVS));\
 +    insert_small_chunk(M, DV, DVS);\
 +  }\
 +  M->dvsize = S;\
 +  M->dv = P;\
 +}
 +
 +/* ------------------------- Operations on trees ------------------------- */
 +
 +/* Insert chunk into tree */
 +#define insert_large_chunk(M, X, S) {\
 +  tbinptr* H;\
 +  bindex_t I;\
 +  compute_tree_index(S, I);\
 +  H = treebin_at(M, I);\
 +  X->index = I;\
 +  X->child[0] = X->child[1] = 0;\
 +  if (!treemap_is_marked(M, I)) {\
 +    mark_treemap(M, I);\
 +    *H = X;\
 +    X->parent = (tchunkptr)H;\
 +    X->fd = X->bk = X;\
 +  }\
 +  else {\
 +    tchunkptr T = *H;\
 +    size_t K = S << leftshift_for_tree_index(I);\
 +    for (;;) {\
 +      if (chunksize(T) != S) {\
 +        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
 +        K <<= 1;\
 +        if (*C != 0)\
 +          T = *C;\
 +        else if (RTCHECK(ok_address(M, C))) {\
 +          *C = X;\
 +          X->parent = T;\
 +          X->fd = X->bk = X;\
 +          break;\
 +        }\
 +        else {\
 +          CORRUPTION_ERROR_ACTION(M);\
 +          break;\
 +        }\
 +      }\
 +      else {\
 +        tchunkptr F = T->fd;\
 +        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
 +          T->fd = F->bk = X;\
 +          X->fd = F;\
 +          X->bk = T;\
 +          X->parent = 0;\
 +          break;\
 +        }\
 +        else {\
 +          CORRUPTION_ERROR_ACTION(M);\
 +          break;\
 +        }\
 +      }\
 +    }\
 +  }\
 +}
 +
 +/*
 +  Unlink steps:
 +
 +  1. If x is a chained node, unlink it from its same-sized fd/bk links
 +     and choose its bk node as its replacement.
 +  2. If x was the last node of its size, but not a leaf node, it must
 +     be replaced with a leaf node (not merely one with an open left or
 +     right), to make sure that lefts and rights of descendents
 +     correspond properly to bit masks.  We use the rightmost descendent
 +     of x.  We could use any other leaf, but this is easy to locate and
 +     tends to counteract removal of leftmosts elsewhere, and so keeps
 +     paths shorter than minimally guaranteed.  This doesn't loop much
 +     because on average a node in a tree is near the bottom.
 +  3. If x is the base of a chain (i.e., has parent links) relink
 +     x's parent and children to x's replacement (or null if none).
 +*/
 +
 +#define unlink_large_chunk(M, X) {\
 +  tchunkptr XP = X->parent;\
 +  tchunkptr R;\
 +  if (X->bk != X) {\
 +    tchunkptr F = X->fd;\
 +    R = X->bk;\
 +    if (RTCHECK(ok_address(M, F))) {\
 +      F->bk = R;\
 +      R->fd = F;\
 +    }\
 +    else {\
 +      CORRUPTION_ERROR_ACTION(M);\
 +    }\
 +  }\
 +  else {\
 +    tchunkptr* RP;\
 +    if (((R = *(RP = &(X->child[1]))) != 0) ||\
 +        ((R = *(RP = &(X->child[0]))) != 0)) {\
 +      tchunkptr* CP;\
 +      while ((*(CP = &(R->child[1])) != 0) ||\
 +             (*(CP = &(R->child[0])) != 0)) {\
 +        R = *(RP = CP);\
 +      }\
 +      if (RTCHECK(ok_address(M, RP)))\
 +        *RP = 0;\
 +      else {\
 +        CORRUPTION_ERROR_ACTION(M);\
 +      }\
 +    }\
 +  }\
 +  if (XP != 0) {\
 +    tbinptr* H = treebin_at(M, X->index);\
 +    if (X == *H) {\
 +      if ((*H = R) == 0) \
 +        clear_treemap(M, X->index);\
 +    }\
 +    else if (RTCHECK(ok_address(M, XP))) {\
 +      if (XP->child[0] == X) \
 +        XP->child[0] = R;\
 +      else \
 +        XP->child[1] = R;\
 +    }\
 +    else\
 +      CORRUPTION_ERROR_ACTION(M);\
 +    if (R != 0) {\
 +      if (RTCHECK(ok_address(M, R))) {\
 +        tchunkptr C0, C1;\
 +        R->parent = XP;\
 +        if ((C0 = X->child[0]) != 0) {\
 +          if (RTCHECK(ok_address(M, C0))) {\
 +            R->child[0] = C0;\
 +            C0->parent = R;\
 +          }\
 +          else\
 +            CORRUPTION_ERROR_ACTION(M);\
 +        }\
 +        if ((C1 = X->child[1]) != 0) {\
 +          if (RTCHECK(ok_address(M, C1))) {\
 +            R->child[1] = C1;\
 +            C1->parent = R;\
 +          }\
 +          else\
 +            CORRUPTION_ERROR_ACTION(M);\
 +        }\
 +      }\
 +      else\
 +        CORRUPTION_ERROR_ACTION(M);\
 +    }\
 +  }\
 +}
 +
 +/* Relays to large vs small bin operations */
 +
 +#define insert_chunk(M, P, S)\
 +  if (is_small(S)) insert_small_chunk(M, P, S)\
 +  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
 +
 +#define unlink_chunk(M, P, S)\
 +  if (is_small(S)) unlink_small_chunk(M, P, S)\
 +  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
 +
 +
 +/* Relays to internal calls to malloc/free from realloc, memalign etc */
 +
 +#if ONLY_MSPACES
 +#define internal_malloc(m, b) mspace_malloc(m, b)
 +#define internal_free(m, mem) mspace_free(m,mem);
 +#else /* ONLY_MSPACES */
 +#if MSPACES
 +#define internal_malloc(m, b)\
 +   (m == gm)? dlmalloc(b) : mspace_malloc(m, b)
 +#define internal_free(m, mem)\
 +   if (m == gm) dlfree(mem); else mspace_free(m,mem);
 +#else /* MSPACES */
 +#define internal_malloc(m, b) dlmalloc(b)
 +#define internal_free(m, mem) dlfree(mem)
 +#endif /* MSPACES */
 +#endif /* ONLY_MSPACES */
 +
 +/* -----------------------  Direct-mmapping chunks ----------------------- */
 +
 +/*
 +  Directly mmapped chunks are set up with an offset to the start of
 +  the mmapped region stored in the prev_foot field of the chunk. This
 +  allows reconstruction of the required argument to MUNMAP when freed,
 +  and also allows adjustment of the returned chunk to meet alignment
 +  requirements (especially in memalign).  There is also enough space
 +  allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain
 +  the PINUSE bit so frees can be checked.
 +*/
 +
 +/* Malloc using mmap */
 +static void* mmap_alloc(mstate m, size_t nb) {
 +  size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
 +  if (mmsize > nb) {     /* Check for wrap around 0 */
 +    char* mm = (char*)(DIRECT_MMAP(mmsize));
 +    if (mm != CMFAIL) {
 +      size_t offset = align_offset(chunk2mem(mm));
 +      size_t psize = mmsize - offset - MMAP_FOOT_PAD;
 +      mchunkptr p = (mchunkptr)(mm + offset);
 +      p->prev_foot = offset | IS_MMAPPED_BIT;
 +      (p)->head = (psize|CINUSE_BIT);
 +      mark_inuse_foot(m, p, psize);
 +      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
 +      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
 +
 +      if (mm < m->least_addr)
 +        m->least_addr = mm;
 +      if ((m->footprint += mmsize) > m->max_footprint)
 +        m->max_footprint = m->footprint;
 +      assert(is_aligned(chunk2mem(p)));
 +      check_mmapped_chunk(m, p);
 +      return chunk2mem(p);
 +    }
 +  }
 +  return 0;
 +}
 +
 +/* Realloc using mmap */
 +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) {
 +  size_t oldsize = chunksize(oldp);
 +  if (is_small(nb)) /* Can't shrink mmap regions below small size */
 +    return 0;
 +  /* Keep old chunk if big enough but not too big */
 +  if (oldsize >= nb + SIZE_T_SIZE &&
 +      (oldsize - nb) <= (mparams.granularity << 1))
 +    return oldp;
 +  else {
 +    size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT;
 +    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
 +    size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES +
 +                                         CHUNK_ALIGN_MASK);
 +    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
 +                                  oldmmsize, newmmsize, 1);
 +    if (cp != CMFAIL) {
 +      mchunkptr newp = (mchunkptr)(cp + offset);
 +      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
 +      newp->head = (psize|CINUSE_BIT);
 +      mark_inuse_foot(m, newp, psize);
 +      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
 +      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
 +
 +      if (cp < m->least_addr)
 +        m->least_addr = cp;
 +      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
 +        m->max_footprint = m->footprint;
 +      check_mmapped_chunk(m, newp);
 +      return newp;
 +    }
 +  }
 +  return 0;
 +}
 +
 +/* -------------------------- mspace management -------------------------- */
 +
 +/* Initialize top chunk and its size */
 +static void init_top(mstate m, mchunkptr p, size_t psize) {
 +  /* Ensure alignment */
 +  size_t offset = align_offset(chunk2mem(p));
 +  p = (mchunkptr)((char*)p + offset);
 +  psize -= offset;
 +
 +  m->top = p;
 +  m->topsize = psize;
 +  p->head = psize | PINUSE_BIT;
 +  /* set size of fake trailing chunk holding overhead space only once */
 +  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
 +  m->trim_check = mparams.trim_threshold; /* reset on each update */
 +}
 +
 +/* Initialize bins for a new mstate that is otherwise zeroed out */
 +static void init_bins(mstate m) {
 +  /* Establish circular links for smallbins */
 +  bindex_t i;
 +  for (i = 0; i < NSMALLBINS; ++i) {
 +    sbinptr bin = smallbin_at(m,i);
 +    bin->fd = bin->bk = bin;
 +  }
 +}
 +
 +#if PROCEED_ON_ERROR
 +
 +/* default corruption action */
 +static void reset_on_error(mstate m) {
 +  int i;
 +  ++malloc_corruption_error_count;
 +  /* Reinitialize fields to forget about all memory */
 +  m->smallbins = m->treebins = 0;
 +  m->dvsize = m->topsize = 0;
 +  m->seg.base = 0;
 +  m->seg.size = 0;
 +  m->seg.next = 0;
 +  m->top = m->dv = 0;
 +  for (i = 0; i < NTREEBINS; ++i)
 +    *treebin_at(m, i) = 0;
 +  init_bins(m);
 +}
 +#endif /* PROCEED_ON_ERROR */
 +
 +/* Allocate chunk and prepend remainder with chunk in successor base. */
 +static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
 +                           size_t nb) {
 +  mchunkptr p = align_as_chunk(newbase);
 +  mchunkptr oldfirst = align_as_chunk(oldbase);
 +  size_t psize = (char*)oldfirst - (char*)p;
 +  mchunkptr q = chunk_plus_offset(p, nb);
 +  size_t qsize = psize - nb;
 +  set_size_and_pinuse_of_inuse_chunk(m, p, nb);
 +
 +  assert((char*)oldfirst > (char*)q);
 +  assert(pinuse(oldfirst));
 +  assert(qsize >= MIN_CHUNK_SIZE);
 +
 +  /* consolidate remainder with first chunk of old base */
 +  if (oldfirst == m->top) {
 +    size_t tsize = m->topsize += qsize;
 +    m->top = q;
 +    q->head = tsize | PINUSE_BIT;
 +    check_top_chunk(m, q);
 +  }
 +  else if (oldfirst == m->dv) {
 +    size_t dsize = m->dvsize += qsize;
 +    m->dv = q;
 +    set_size_and_pinuse_of_free_chunk(q, dsize);
 +  }
 +  else {
 +    if (!cinuse(oldfirst)) {
 +      size_t nsize = chunksize(oldfirst);
 +      unlink_chunk(m, oldfirst, nsize);
 +      oldfirst = chunk_plus_offset(oldfirst, nsize);
 +      qsize += nsize;
 +    }
 +    set_free_with_pinuse(q, qsize, oldfirst);
 +    insert_chunk(m, q, qsize);
 +    check_free_chunk(m, q);
 +  }
 +
 +  check_malloced_chunk(m, chunk2mem(p), nb);
 +  return chunk2mem(p);
 +}
 +
 +
 +/* Add a segment to hold a new noncontiguous region */
 +static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
 +  /* Determine locations and sizes of segment, fenceposts, old top */
 +  char* old_top = (char*)m->top;
 +  msegmentptr oldsp = segment_holding(m, old_top);
 +  char* old_end = oldsp->base + oldsp->size;
 +  size_t ssize = pad_request(sizeof(struct malloc_segment));
 +  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
 +  size_t offset = align_offset(chunk2mem(rawsp));
 +  char* asp = rawsp + offset;
 +  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
 +  mchunkptr sp = (mchunkptr)csp;
 +  msegmentptr ss = (msegmentptr)(chunk2mem(sp));
 +  mchunkptr tnext = chunk_plus_offset(sp, ssize);
 +  mchunkptr p = tnext;
 +  int nfences = 0;
 +
 +  /* reset top to new space */
 +  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
 +
 +  /* Set up segment record */
 +  assert(is_aligned(ss));
 +  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
 +  *ss = m->seg; /* Push current record */
 +  m->seg.base = tbase;
 +  m->seg.size = tsize;
 +  set_segment_flags(&m->seg, mmapped);
 +  m->seg.next = ss;
 +
 +  /* Insert trailing fenceposts */
 +  for (;;) {
 +    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
 +    p->head = FENCEPOST_HEAD;
 +    ++nfences;
 +    if ((char*)(&(nextp->head)) < old_end)
 +      p = nextp;
 +    else
 +      break;
 +  }
 +  assert(nfences >= 2);
 +
 +  /* Insert the rest of old top into a bin as an ordinary free chunk */
 +  if (csp != old_top) {
 +    mchunkptr q = (mchunkptr)old_top;
 +    size_t psize = csp - old_top;
 +    mchunkptr tn = chunk_plus_offset(q, psize);
 +    set_free_with_pinuse(q, psize, tn);
 +    insert_chunk(m, q, psize);
 +  }
 +
 +  check_top_chunk(m, m->top);
 +}
 +
 +/* -------------------------- System allocation -------------------------- */
 +
 +/* Get memory from system using MORECORE or MMAP */
 +static void* sys_alloc(mstate m, size_t nb) {
 +  char* tbase = CMFAIL;
 +  size_t tsize = 0;
 +  flag_t mmap_flag = 0;
 +
 +  init_mparams();
 +
 +  /* Directly map large chunks */
 +  if (use_mmap(m) && nb >= mparams.mmap_threshold) {
 +    void* mem = mmap_alloc(m, nb);
 +    if (mem != 0)
 +      return mem;
 +  }
 +
 +  /*
 +    Try getting memory in any of three ways (in most-preferred to
 +    least-preferred order):
 +    1. A call to MORECORE that can normally contiguously extend memory.
 +       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
 +       or main space is mmapped or a previous contiguous call failed)
 +    2. A call to MMAP new space (disabled if not HAVE_MMAP).
 +       Note that under the default settings, if MORECORE is unable to
 +       fulfill a request, and HAVE_MMAP is true, then mmap is
 +       used as a noncontiguous system allocator. This is a useful backup
 +       strategy for systems with holes in address spaces -- in this case
 +       sbrk cannot contiguously expand the heap, but mmap may be able to
 +       find space.
 +    3. A call to MORECORE that cannot usually contiguously extend memory.
 +       (disabled if not HAVE_MORECORE)
 +  */
 +
 +  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
 +    char* br = CMFAIL;
 +    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
 +    size_t asize = 0;
 +    ACQUIRE_MORECORE_LOCK();
 +
 +    if (ss == 0) {  /* First time through or recovery */
 +      char* base = (char*)CALL_MORECORE(0);
 +      if (base != CMFAIL) {
 +        asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);
 +        /* Adjust to end on a page boundary */
 +        if (!is_page_aligned(base))
 +          asize += (page_align((size_t)base) - (size_t)base);
 +        /* Can't call MORECORE if size is negative when treated as signed */
 +        if (asize < HALF_MAX_SIZE_T &&
 +            (br = (char*)(CALL_MORECORE(asize))) == base) {
 +          tbase = base;
 +          tsize = asize;
 +        }
 +      }
 +    }
 +    else {
 +      /* Subtract out existing available top space from MORECORE request. */
 +      asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE);
 +      /* Use mem here only if it did continuously extend old space */
 +      if (asize < HALF_MAX_SIZE_T &&
 +          (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) {
 +        tbase = br;
 +        tsize = asize;
 +      }
 +    }
 +
 +    if (tbase == CMFAIL) {    /* Cope with partial failure */
 +      if (br != CMFAIL) {    /* Try to use/extend the space we did get */
 +        if (asize < HALF_MAX_SIZE_T &&
 +            asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) {
 +          size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize);
 +          if (esize < HALF_MAX_SIZE_T) {
 +            char* end = (char*)CALL_MORECORE(esize);
 +            if (end != CMFAIL)
 +              asize += esize;
 +            else {            /* Can't use; try to release */
 +              (void)CALL_MORECORE(-asize);
 +              br = CMFAIL;
 +            }
 +          }
 +        }
 +      }
 +      if (br != CMFAIL) {    /* Use the space we did get */
 +        tbase = br;
 +        tsize = asize;
 +      }
 +      else
 +        disable_contiguous(m); /* Don't try contiguous path in the future */
 +    }
 +
 +    RELEASE_MORECORE_LOCK();
 +  }
 +
 +  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */
 +    size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE;
 +    size_t rsize = granularity_align(req);
 +    if (rsize > nb) { /* Fail if wraps around zero */
 +      char* mp = (char*)(CALL_MMAP(rsize));
 +      if (mp != CMFAIL) {
 +        tbase = mp;
 +        tsize = rsize;
 +        mmap_flag = IS_MMAPPED_BIT;
 +      }
 +    }
 +  }
 +
 +  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
 +    size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);
 +    if (asize < HALF_MAX_SIZE_T) {
 +      char* br = CMFAIL;
 +      char* end = CMFAIL;
 +      ACQUIRE_MORECORE_LOCK();
 +      br = (char*)(CALL_MORECORE(asize));
 +      end = (char*)(CALL_MORECORE(0));
 +      RELEASE_MORECORE_LOCK();
 +      if (br != CMFAIL && end != CMFAIL && br < end) {
 +        size_t ssize = end - br;
 +        if (ssize > nb + TOP_FOOT_SIZE) {
 +          tbase = br;
 +          tsize = ssize;
 +        }
 +      }
 +    }
 +  }
 +
 +  if (tbase != CMFAIL) {
 +
 +    if ((m->footprint += tsize) > m->max_footprint)
 +      m->max_footprint = m->footprint;
 +
 +    if (!is_initialized(m)) { /* first-time initialization */
 +      m->seg.base = m->least_addr = tbase;
 +      m->seg.size = tsize;
 +      set_segment_flags(&m->seg, mmap_flag);
 +      m->magic = mparams.magic;
 +      init_bins(m);
 +      if (is_global(m)) 
 +        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
 +      else {
 +        /* Offset top by embedded malloc_state */
 +        mchunkptr mn = next_chunk(mem2chunk(m));
 +        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
 +      }
 +    }
 +
 +    else {
 +      /* Try to merge with an existing segment */
 +      msegmentptr sp = &m->seg;
 +      while (sp != 0 && tbase != sp->base + sp->size)
 +        sp = sp->next;
 +      if (sp != 0 &&
 +          !is_extern_segment(sp) &&
 +        check_segment_merge(sp, tbase, tsize) &&
 +          (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag &&
 +          segment_holds(sp, m->top)) { /* append */
 +        sp->size += tsize;
 +        init_top(m, m->top, m->topsize + tsize);
 +      }
 +      else {
 +        if (tbase < m->least_addr)
 +          m->least_addr = tbase;
 +        sp = &m->seg;
 +        while (sp != 0 && sp->base != tbase + tsize)
 +          sp = sp->next;
 +        if (sp != 0 &&
 +            !is_extern_segment(sp) &&
 +          check_segment_merge(sp, tbase, tsize) &&
 +            (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag) {
 +          char* oldbase = sp->base;
 +          sp->base = tbase;
 +          sp->size += tsize;
 +          return prepend_alloc(m, tbase, oldbase, nb);
 +        }
 +        else
 +          add_segment(m, tbase, tsize, mmap_flag);
 +      }
 +    }
 +
 +    if (nb < m->topsize) { /* Allocate from new or extended top space */
 +      size_t rsize = m->topsize -= nb;
 +      mchunkptr p = m->top;
 +      mchunkptr r = m->top = chunk_plus_offset(p, nb);
 +      r->head = rsize | PINUSE_BIT;
 +      set_size_and_pinuse_of_inuse_chunk(m, p, nb);
 +      check_top_chunk(m, m->top);
 +      check_malloced_chunk(m, chunk2mem(p), nb);
 +      return chunk2mem(p);
 +    }
 +  }
 +
 +  MALLOC_FAILURE_ACTION;
 +  return 0;
 +}
 +
 +/* -----------------------  system deallocation -------------------------- */
 +
 +/* Unmap and unlink any mmapped segments that don't contain used chunks */
 +static size_t release_unused_segments(mstate m) {
 +  size_t released = 0;
 +  msegmentptr pred = &m->seg;
 +  msegmentptr sp = pred->next;
 +  while (sp != 0) {
 +    char* base = sp->base;
 +    size_t size = sp->size;
 +    msegmentptr next = sp->next;
 +    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
 +      mchunkptr p = align_as_chunk(base);
 +      size_t psize = chunksize(p);
 +      /* Can unmap if first chunk holds entire segment and not pinned */
 +      if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
 +        tchunkptr tp = (tchunkptr)p;
 +        assert(segment_holds(sp, (char*)sp));
 +        if (p == m->dv) {
 +          m->dv = 0;
 +          m->dvsize = 0;
 +        }
 +        else {
 +          unlink_large_chunk(m, tp);
 +        }
 +        if (CALL_MUNMAP(base, size) == 0) {
 +          released += size;
 +          m->footprint -= size;
 +          /* unlink obsoleted record */
 +          sp = pred;
 +          sp->next = next;
 +        }
 +        else { /* back out if cannot unmap */
 +          insert_large_chunk(m, tp, psize);
 +        }
 +      }
 +    }
 +    pred = sp;
 +    sp = next;
 +  }
 +  return released;
 +}
 +
 +static int sys_trim(mstate m, size_t pad) {
 +  size_t released = 0;
 +  if (pad < MAX_REQUEST && is_initialized(m)) {
 +    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
 +
 +    if (m->topsize > pad) {
 +      /* Shrink top space in granularity-size units, keeping at least one */
 +      size_t unit = mparams.granularity;
 +      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
 +                      SIZE_T_ONE) * unit;
 +      msegmentptr sp = segment_holding(m, (char*)m->top);
 +
 +      if (!is_extern_segment(sp)) {
 +        if (is_mmapped_segment(sp)) {
 +          if (HAVE_MMAP &&
 +              sp->size >= extra &&
 +              !has_segment_link(m, sp)) { /* can't shrink if pinned */
 +            size_t newsize = sp->size - extra;
 +            /* Prefer mremap, fall back to munmap */
 +            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
 +                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
 +              released = extra;
 +            }
 +          }
 +        }
 +        else if (HAVE_MORECORE) {
 +          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
 +            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
 +          ACQUIRE_MORECORE_LOCK();
 +          {
 +            /* Make sure end of memory is where we last set it. */
 +            char* old_br = (char*)(CALL_MORECORE(0));
 +            if (old_br == sp->base + sp->size) {
 +              char* rel_br = (char*)(CALL_MORECORE(-extra));
 +              char* new_br = (char*)(CALL_MORECORE(0));
 +              if (rel_br != CMFAIL && new_br < old_br)
 +                released = old_br - new_br;
 +            }
 +          }
 +          RELEASE_MORECORE_LOCK();
 +        }
 +      }
 +
 +      if (released != 0) {
 +        sp->size -= released;
 +        m->footprint -= released;
 +        init_top(m, m->top, m->topsize - released);
 +        check_top_chunk(m, m->top);
 +      }
 +    }
 +
 +    /* Unmap any unused mmapped segments */
 +    if (HAVE_MMAP) 
 +      released += release_unused_segments(m);
 +
 +    /* On failure, disable autotrim to avoid repeated failed future calls */
 +    if (released == 0)
 +      m->trim_check = MAX_SIZE_T;
 +  }
 +
 +  return (released != 0)? 1 : 0;
 +}
 +
 +/* ---------------------------- malloc support --------------------------- */
 +
 +/* allocate a large request from the best fitting chunk in a treebin */
 +static void* tmalloc_large(mstate m, size_t nb) {
 +  tchunkptr v = 0;
 +  size_t rsize = -nb; /* Unsigned negation */
 +  tchunkptr t;
 +  bindex_t idx;
 +  compute_tree_index(nb, idx);
 +
 +  if ((t = *treebin_at(m, idx)) != 0) {
 +    /* Traverse tree for this bin looking for node with size == nb */
 +    size_t sizebits = nb << leftshift_for_tree_index(idx);
 +    tchunkptr rst = 0;  /* The deepest untaken right subtree */
 +    for (;;) {
 +      tchunkptr rt;
 +      size_t trem = chunksize(t) - nb;
 +      if (trem < rsize) {
 +        v = t;
 +        if ((rsize = trem) == 0)
 +          break;
 +      }
 +      rt = t->child[1];
 +      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
 +      if (rt != 0 && rt != t)
 +        rst = rt;
 +      if (t == 0) {
 +        t = rst; /* set t to least subtree holding sizes > nb */
 +        break;
 +      }
 +      sizebits <<= 1;
 +    }
 +  }
 +
 +  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
 +    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
 +    if (leftbits != 0) {
 +      bindex_t i;
 +      binmap_t leastbit = least_bit(leftbits);
 +      compute_bit2idx(leastbit, i);
 +      t = *treebin_at(m, i);
 +    }
 +  }
 +
 +  while (t != 0) { /* find smallest of tree or subtree */
 +    size_t trem = chunksize(t) - nb;
 +    if (trem < rsize) {
 +      rsize = trem;
 +      v = t;
 +    }
 +    t = leftmost_child(t);
 +  }
 +
 +  /*  If dv is a better fit, return 0 so malloc will use it */
 +  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
 +    if (RTCHECK(ok_address(m, v))) { /* split */
 +      mchunkptr r = chunk_plus_offset(v, nb);
 +      assert(chunksize(v) == rsize + nb);
 +      if (RTCHECK(ok_next(v, r))) {
 +        unlink_large_chunk(m, v);
 +        if (rsize < MIN_CHUNK_SIZE)
 +          set_inuse_and_pinuse(m, v, (rsize + nb));
 +        else {
 +          set_size_and_pinuse_of_inuse_chunk(m, v, nb);
 +          set_size_and_pinuse_of_free_chunk(r, rsize);
 +          insert_chunk(m, r, rsize);
 +        }
 +        return chunk2mem(v);
 +      }
 +    }
 +    CORRUPTION_ERROR_ACTION(m);
 +  }
 +  return 0;
 +}
 +
 +/* allocate a small request from the best fitting chunk in a treebin */
 +static void* tmalloc_small(mstate m, size_t nb) {
 +  tchunkptr t, v;
 +  size_t rsize;
 +  bindex_t i;
 +  binmap_t leastbit = least_bit(m->treemap);
 +  compute_bit2idx(leastbit, i);
 +
 +  v = t = *treebin_at(m, i);
 +  rsize = chunksize(t) - nb;
 +
 +  while ((t = leftmost_child(t)) != 0) {
 +    size_t trem = chunksize(t) - nb;
 +    if (trem < rsize) {
 +      rsize = trem;
 +      v = t;
 +    }
 +  }
 +
 +  if (RTCHECK(ok_address(m, v))) {
 +    mchunkptr r = chunk_plus_offset(v, nb);
 +    assert(chunksize(v) == rsize + nb);
 +    if (RTCHECK(ok_next(v, r))) {
 +      unlink_large_chunk(m, v);
 +      if (rsize < MIN_CHUNK_SIZE)
 +        set_inuse_and_pinuse(m, v, (rsize + nb));
 +      else {
 +        set_size_and_pinuse_of_inuse_chunk(m, v, nb);
 +        set_size_and_pinuse_of_free_chunk(r, rsize);
 +        replace_dv(m, r, rsize);
 +      }
 +      return chunk2mem(v);
 +    }
 +  }
 +
 +  CORRUPTION_ERROR_ACTION(m);
 +  return 0;
 +}
 +
 +/* --------------------------- realloc support --------------------------- */
 +
 +static void* internal_realloc(mstate m, void* oldmem, size_t bytes) {
 +  if (bytes >= MAX_REQUEST) {
 +    MALLOC_FAILURE_ACTION;
 +    return 0;
 +  }
 +  if (!PREACTION(m)) {
 +    mchunkptr oldp = mem2chunk(oldmem);
 +    size_t oldsize = chunksize(oldp);
 +    mchunkptr next = chunk_plus_offset(oldp, oldsize);
 +    mchunkptr newp = 0;
 +    void* extra = 0;
 +
 +    /* Try to either shrink or extend into top. Else malloc-copy-free */
 +
 +    if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) &&
 +                ok_next(oldp, next) && ok_pinuse(next))) {
 +      size_t nb = request2size(bytes);
 +      if (is_mmapped(oldp))
 +        newp = mmap_resize(m, oldp, nb);
 +      else if (oldsize >= nb) { /* already big enough */
 +        size_t rsize = oldsize - nb;
 +        newp = oldp;
 +        if (rsize >= MIN_CHUNK_SIZE) {
 +          mchunkptr remainder = chunk_plus_offset(newp, nb);
 +          set_inuse(m, newp, nb);
 +          set_inuse(m, remainder, rsize);
 +          extra = chunk2mem(remainder);
 +        }
 +      }
 +      else if (next == m->top && oldsize + m->topsize > nb) {
 +        /* Expand into top */
 +        size_t newsize = oldsize + m->topsize;
 +        size_t newtopsize = newsize - nb;
 +        mchunkptr newtop = chunk_plus_offset(oldp, nb);
 +        set_inuse(m, oldp, nb);
 +        newtop->head = newtopsize |PINUSE_BIT;
 +        m->top = newtop;
 +        m->topsize = newtopsize;
 +        newp = oldp;
 +      }
 +    }
 +    else {
 +      USAGE_ERROR_ACTION(m, oldmem);
 +      POSTACTION(m);
 +      return 0;
 +    }
 +
 +    POSTACTION(m);
 +
 +    if (newp != 0) {
 +      if (extra != 0) {
 +        internal_free(m, extra);
 +      }
 +      check_inuse_chunk(m, newp);
 +      return chunk2mem(newp);
 +    }
 +    else {
 +      void* newmem = internal_malloc(m, bytes);
 +      if (newmem != 0) {
 +        size_t oc = oldsize - overhead_for(oldp);
 +        memcpy(newmem, oldmem, (oc < bytes)? oc : bytes);
 +        internal_free(m, oldmem);
 +      }
 +      return newmem;
 +    }
 +  }
 +  return 0;
 +}
 +
 +/* --------------------------- memalign support -------------------------- */
 +
 +static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
 +  if (alignment <= MALLOC_ALIGNMENT)    /* Can just use malloc */
 +    return internal_malloc(m, bytes);
 +  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
 +    alignment = MIN_CHUNK_SIZE;
 +  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
 +    size_t a = MALLOC_ALIGNMENT << 1;
 +    while (a < alignment) a <<= 1;
 +    alignment = a;
 +  }
 +  
 +  if (bytes >= MAX_REQUEST - alignment) {
 +    if (m != 0)  { /* Test isn't needed but avoids compiler warning */
 +      MALLOC_FAILURE_ACTION;
 +    }
 +  }
 +  else {
 +    size_t nb = request2size(bytes);
 +    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
 +    char* mem = (char*)internal_malloc(m, req);
 +    if (mem != 0) {
 +      void* leader = 0;
 +      void* trailer = 0;
 +      mchunkptr p = mem2chunk(mem);
 +
 +      if (PREACTION(m)) return 0;
 +      if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */
 +        /*
 +          Find an aligned spot inside chunk.  Since we need to give
 +          back leading space in a chunk of at least MIN_CHUNK_SIZE, if
 +          the first calculation places us at a spot with less than
 +          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
 +          We've allocated enough total room so that this is always
 +          possible.
 +        */
 +        char* br = (char*)mem2chunk((size_t)(((size_t)(mem +
 +                                                       alignment -
 +                                                       SIZE_T_ONE)) &
 +                                             -alignment));
 +        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
 +          br : br+alignment;
 +        mchunkptr newp = (mchunkptr)pos;
 +        size_t leadsize = pos - (char*)(p);
 +        size_t newsize = chunksize(p) - leadsize;
 +
 +        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
 +          newp->prev_foot = p->prev_foot + leadsize;
 +          newp->head = (newsize|CINUSE_BIT);
 +        }
 +        else { /* Otherwise, give back leader, use the rest */
 +          set_inuse(m, newp, newsize);
 +          set_inuse(m, p, leadsize);
 +          leader = chunk2mem(p);
 +        }
 +        p = newp;
 +      }
 +
 +      /* Give back spare room at the end */
 +      if (!is_mmapped(p)) {
 +        size_t size = chunksize(p);
 +        if (size > nb + MIN_CHUNK_SIZE) {
 +          size_t remainder_size = size - nb;
 +          mchunkptr remainder = chunk_plus_offset(p, nb);
 +          set_inuse(m, p, nb);
 +          set_inuse(m, remainder, remainder_size);
 +          trailer = chunk2mem(remainder);
 +        }
 +      }
 +
 +      assert (chunksize(p) >= nb);
 +      assert((((size_t)(chunk2mem(p))) % alignment) == 0);
 +      check_inuse_chunk(m, p);
 +      POSTACTION(m);
 +      if (leader != 0) {
 +        internal_free(m, leader);
 +      }
 +      if (trailer != 0) {
 +        internal_free(m, trailer);
 +      }
 +      return chunk2mem(p);
 +    }
 +  }
 +  return 0;
 +}
 +
 +/* ------------------------ comalloc/coalloc support --------------------- */
 +
 +static void** ialloc(mstate m,
 +                     size_t n_elements,
 +                     size_t* sizes,
 +                     int opts,
 +                     void* chunks[]) {
 +  /*
 +    This provides common support for independent_X routines, handling
 +    all of the combinations that can result.
 +
 +    The opts arg has:
 +    bit 0 set if all elements are same size (using sizes[0])
 +    bit 1 set if elements should be zeroed
 +  */
 +
 +  size_t    element_size;   /* chunksize of each element, if all same */
 +  size_t    contents_size;  /* total size of elements */
 +  size_t    array_size;     /* request size of pointer array */
 +  void*     mem;            /* malloced aggregate space */
 +  mchunkptr p;              /* corresponding chunk */
 +  size_t    remainder_size; /* remaining bytes while splitting */
 +  void**    marray;         /* either "chunks" or malloced ptr array */
 +  mchunkptr array_chunk;    /* chunk for malloced ptr array */
 +  flag_t    was_enabled;    /* to disable mmap */
 +  size_t    size;
 +  size_t    i;
 +
 +  /* compute array length, if needed */
 +  if (chunks != 0) {
 +    if (n_elements == 0)
 +      return chunks; /* nothing to do */
 +    marray = chunks;
 +    array_size = 0;
 +  }
 +  else {
 +    /* if empty req, must still return chunk representing empty array */
 +    if (n_elements == 0)
 +      return (void**)internal_malloc(m, 0);
 +    marray = 0;
 +    array_size = request2size(n_elements * (sizeof(void*)));
 +  }
 +
 +  /* compute total element size */
 +  if (opts & 0x1) { /* all-same-size */
 +    element_size = request2size(*sizes);
 +    contents_size = n_elements * element_size;
 +  }
 +  else { /* add up all the sizes */
 +    element_size = 0;
 +    contents_size = 0;
 +    for (i = 0; i != n_elements; ++i)
 +      contents_size += request2size(sizes[i]);
 +  }
 +
 +  size = contents_size + array_size;
 +
 +  /*
 +     Allocate the aggregate chunk.  First disable direct-mmapping so
 +     malloc won't use it, since we would not be able to later
 +     free/realloc space internal to a segregated mmap region.
 +  */
 +  was_enabled = use_mmap(m);
 +  disable_mmap(m);
 +  mem = internal_malloc(m, size - CHUNK_OVERHEAD);
 +  if (was_enabled)
 +    enable_mmap(m);
 +  if (mem == 0)
 +    return 0;
 +
 +  if (PREACTION(m)) return 0;
 +  p = mem2chunk(mem);
 +  remainder_size = chunksize(p);
 +
 +  assert(!is_mmapped(p));
 +
 +  if (opts & 0x2) {       /* optionally clear the elements */
 +    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
 +  }
 +
 +  /* If not provided, allocate the pointer array as final part of chunk */
 +  if (marray == 0) {
 +    size_t  array_chunk_size;
 +    array_chunk = chunk_plus_offset(p, contents_size);
 +    array_chunk_size = remainder_size - contents_size;
 +    marray = (void**) (chunk2mem(array_chunk));
 +    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
 +    remainder_size = contents_size;
 +  }
 +
 +  /* split out elements */
 +  for (i = 0; ; ++i) {
 +    marray[i] = chunk2mem(p);
 +    if (i != n_elements-1) {
 +      if (element_size != 0)
 +        size = element_size;
 +      else
 +        size = request2size(sizes[i]);
 +      remainder_size -= size;
 +      set_size_and_pinuse_of_inuse_chunk(m, p, size);
 +      p = chunk_plus_offset(p, size);
 +    }
 +    else { /* the final element absorbs any overallocation slop */
 +      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
 +      break;
 +    }
 +  }
 +
 +#if DEBUG
 +  if (marray != chunks) {
 +    /* final element must have exactly exhausted chunk */
 +    if (element_size != 0) {
 +      assert(remainder_size == element_size);
 +    }
 +    else {
 +      assert(remainder_size == request2size(sizes[i]));
 +    }
 +    check_inuse_chunk(m, mem2chunk(marray));
 +  }
 +  for (i = 0; i != n_elements; ++i)
 +    check_inuse_chunk(m, mem2chunk(marray[i]));
 +
 +#endif /* DEBUG */
 +
 +  POSTACTION(m);
 +  return marray;
 +}
 +
 +
 +/* -------------------------- public routines ---------------------------- */
 +
 +#if !ONLY_MSPACES
 +
 +void* dlmalloc(size_t bytes) {
 +  /*
 +     Basic algorithm:
 +     If a small request (< 256 bytes minus per-chunk overhead):
 +       1. If one exists, use a remainderless chunk in associated smallbin.
 +          (Remainderless means that there are too few excess bytes to
 +          represent as a chunk.)
 +       2. If it is big enough, use the dv chunk, which is normally the
 +          chunk adjacent to the one used for the most recent small request.
 +       3. If one exists, split the smallest available chunk in a bin,
 +          saving remainder in dv.
 +       4. If it is big enough, use the top chunk.
 +       5. If available, get memory from system and use it
 +     Otherwise, for a large request:
 +       1. Find the smallest available binned chunk that fits, and use it
 +          if it is better fitting than dv chunk, splitting if necessary.
 +       2. If better fitting than any binned chunk, use the dv chunk.
 +       3. If it is big enough, use the top chunk.
 +       4. If request size >= mmap threshold, try to directly mmap this chunk.
 +       5. If available, get memory from system and use it
 +
 +     The ugly goto's here ensure that postaction occurs along all paths.
 +  */
 +
 +  if (!PREACTION(gm)) {
 +    void* mem;
 +    size_t nb;
 +    if (bytes <= MAX_SMALL_REQUEST) {
 +      bindex_t idx;
 +      binmap_t smallbits;
 +      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
 +      idx = small_index(nb);
 +      smallbits = gm->smallmap >> idx;
 +
 +      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
 +        mchunkptr b, p;
 +        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
 +        b = smallbin_at(gm, idx);
 +        p = b->fd;
 +        assert(chunksize(p) == small_index2size(idx));
 +        unlink_first_small_chunk(gm, b, p, idx);
 +        set_inuse_and_pinuse(gm, p, small_index2size(idx));
 +        mem = chunk2mem(p);
 +        check_malloced_chunk(gm, mem, nb);
 +        goto postaction;
 +      }
 +
 +      else if (nb > gm->dvsize) {
 +        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
 +          mchunkptr b, p, r;
 +          size_t rsize;
 +          bindex_t i;
 +          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
 +          binmap_t leastbit = least_bit(leftbits);
 +          compute_bit2idx(leastbit, i);
 +          b = smallbin_at(gm, i);
 +          p = b->fd;
 +          assert(chunksize(p) == small_index2size(i));
 +          unlink_first_small_chunk(gm, b, p, i);
 +          rsize = small_index2size(i) - nb;
 +          /* Fit here cannot be remainderless if 4byte sizes */
 +          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
 +            set_inuse_and_pinuse(gm, p, small_index2size(i));
 +          else {
 +            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
 +            r = chunk_plus_offset(p, nb);
 +            set_size_and_pinuse_of_free_chunk(r, rsize);
 +            replace_dv(gm, r, rsize);
 +          }
 +          mem = chunk2mem(p);
 +          check_malloced_chunk(gm, mem, nb);
 +          goto postaction;
 +        }
 +
 +        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
 +          check_malloced_chunk(gm, mem, nb);
 +          goto postaction;
 +        }
 +      }
 +    }
 +    else if (bytes >= MAX_REQUEST)
 +      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
 +    else {
 +      nb = pad_request(bytes);
 +      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
 +        check_malloced_chunk(gm, mem, nb);
 +        goto postaction;
 +      }
 +    }
 +
 +    if (nb <= gm->dvsize) {
 +      size_t rsize = gm->dvsize - nb;
 +      mchunkptr p = gm->dv;
 +      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
 +        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
 +        gm->dvsize = rsize;
 +        set_size_and_pinuse_of_free_chunk(r, rsize);
 +        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
 +      }
 +      else { /* exhaust dv */
 +        size_t dvs = gm->dvsize;
 +        gm->dvsize = 0;
 +        gm->dv = 0;
 +        set_inuse_and_pinuse(gm, p, dvs);
 +      }
 +      mem = chunk2mem(p);
 +      check_malloced_chunk(gm, mem, nb);
 +      goto postaction;
 +    }
 +
 +    else if (nb < gm->topsize) { /* Split top */
 +      size_t rsize = gm->topsize -= nb;
 +      mchunkptr p = gm->top;
 +      mchunkptr r = gm->top = chunk_plus_offset(p, nb);
 +      r->head = rsize | PINUSE_BIT;
 +      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
 +      mem = chunk2mem(p);
 +      check_top_chunk(gm, gm->top);
 +      check_malloced_chunk(gm, mem, nb);
 +      goto postaction;
 +    }
 +
 +    mem = sys_alloc(gm, nb);
 +
 +  postaction:
 +    POSTACTION(gm);
 +    return mem;
 +  }
 +
 +  return 0;
 +}
 +
 +void dlfree(void* mem) {
 +  /*
 +     Consolidate freed chunks with preceeding or succeeding bordering
 +     free chunks, if they exist, and then place in a bin.  Intermixed
 +     with special cases for top, dv, mmapped chunks, and usage errors.
 +  */
 +
 +  if (mem != 0) {
 +    mchunkptr p  = mem2chunk(mem);
 +#if FOOTERS
 +    mstate fm = get_mstate_for(p);
 +    if (!ok_magic(fm)) {
 +      USAGE_ERROR_ACTION(fm, p);
 +      return;
 +    }
 +#else /* FOOTERS */
 +#define fm gm
 +#endif /* FOOTERS */
 +    if (!PREACTION(fm)) {
 +      check_inuse_chunk(fm, p);
 +      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
 +        size_t psize = chunksize(p);
 +        mchunkptr next = chunk_plus_offset(p, psize);
 +        if (!pinuse(p)) {
 +          size_t prevsize = p->prev_foot;
 +          if ((prevsize & IS_MMAPPED_BIT) != 0) {
 +            prevsize &= ~IS_MMAPPED_BIT;
 +            psize += prevsize + MMAP_FOOT_PAD;
 +            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
 +              fm->footprint -= psize;
 +            goto postaction;
 +          }
 +          else {
 +            mchunkptr prev = chunk_minus_offset(p, prevsize);
 +            psize += prevsize;
 +            p = prev;
 +            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
 +              if (p != fm->dv) {
 +                unlink_chunk(fm, p, prevsize);
 +              }
 +              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
 +                fm->dvsize = psize;
 +                set_free_with_pinuse(p, psize, next);
 +                goto postaction;
 +              }
 +            }
 +            else
 +              goto erroraction;
 +          }
 +        }
 +
 +        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
 +          if (!cinuse(next)) {  /* consolidate forward */
 +            if (next == fm->top) {
 +              size_t tsize = fm->topsize += psize;
 +              fm->top = p;
 +              p->head = tsize | PINUSE_BIT;
 +              if (p == fm->dv) {
 +                fm->dv = 0;
 +                fm->dvsize = 0;
 +              }
 +              if (should_trim(fm, tsize))
 +                sys_trim(fm, 0);
 +              goto postaction;
 +            }
 +            else if (next == fm->dv) {
 +              size_t dsize = fm->dvsize += psize;
 +              fm->dv = p;
 +              set_size_and_pinuse_of_free_chunk(p, dsize);
 +              goto postaction;
 +            }
 +            else {
 +              size_t nsize = chunksize(next);
 +              psize += nsize;
 +              unlink_chunk(fm, next, nsize);
 +              set_size_and_pinuse_of_free_chunk(p, psize);
 +              if (p == fm->dv) {
 +                fm->dvsize = psize;
 +                goto postaction;
 +              }
 +            }
 +          }
 +          else
 +            set_free_with_pinuse(p, psize, next);
 +          insert_chunk(fm, p, psize);
 +          check_free_chunk(fm, p);
 +          goto postaction;
 +        }
 +      }
 +    erroraction:
 +      USAGE_ERROR_ACTION(fm, p);
 +    postaction:
 +      POSTACTION(fm);
 +    }
 +  }
 +#if !FOOTERS
 +#undef fm
 +#endif /* FOOTERS */
 +}
 +
 +void* dlcalloc(size_t n_elements, size_t elem_size) {
 +  void* mem;
 +  size_t req = 0;
 +  if (n_elements != 0) {
 +    req = n_elements * elem_size;
 +    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
 +        (req / n_elements != elem_size))
 +      req = MAX_SIZE_T; /* force downstream failure on overflow */
 +  }
 +  mem = dlmalloc(req);
 +  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
 +    memset(mem, 0, req);
 +  return mem;
 +}
 +
 +void* dlrealloc(void* oldmem, size_t bytes) {
 +  if (oldmem == 0)
 +    return dlmalloc(bytes);
 +#ifdef REALLOC_ZERO_BYTES_FREES
 +  if (bytes == 0) {
 +    dlfree(oldmem);
 +    return 0;
 +  }
 +#endif /* REALLOC_ZERO_BYTES_FREES */
 +  else {
 +#if ! FOOTERS
 +    mstate m = gm;
 +#else /* FOOTERS */
 +    mstate m = get_mstate_for(mem2chunk(oldmem));
 +    if (!ok_magic(m)) {
 +      USAGE_ERROR_ACTION(m, oldmem);
 +      return 0;
 +    }
 +#endif /* FOOTERS */
 +    return internal_realloc(m, oldmem, bytes);
 +  }
 +}
 +
 +void* dlmemalign(size_t alignment, size_t bytes) {
 +  return internal_memalign(gm, alignment, bytes);
 +}
 +
 +void** dlindependent_calloc(size_t n_elements, size_t elem_size,
 +                                 void* chunks[]) {
 +  size_t sz = elem_size; /* serves as 1-element array */
 +  return ialloc(gm, n_elements, &sz, 3, chunks);
 +}
 +
 +void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
 +                                   void* chunks[]) {
 +  return ialloc(gm, n_elements, sizes, 0, chunks);
 +}
 +
 +void* dlvalloc(size_t bytes) {
 +  size_t pagesz;
 +  init_mparams();
 +  pagesz = mparams.page_size;
 +  return dlmemalign(pagesz, bytes);
 +}
 +
 +void* dlpvalloc(size_t bytes) {
 +  size_t pagesz;
 +  init_mparams();
 +  pagesz = mparams.page_size;
 +  return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));
 +}
 +
 +int dlmalloc_trim(size_t pad) {
 +  int result = 0;
 +  if (!PREACTION(gm)) {
 +    result = sys_trim(gm, pad);
 +    POSTACTION(gm);
 +  }
 +  return result;
 +}
 +
 +size_t dlmalloc_footprint(void) {
 +  return gm->footprint;
 +}
 +
 +size_t dlmalloc_max_footprint(void) {
 +  return gm->max_footprint;
 +}
 +
 +#if !NO_MALLINFO
 +struct mallinfo dlmallinfo(void) {
 +  return internal_mallinfo(gm);
 +}
 +#endif /* NO_MALLINFO */
 +
 +void dlmalloc_stats() {
 +  internal_malloc_stats(gm);
 +}
 +
 +size_t dlmalloc_usable_size(void* mem) {
 +  if (mem != 0) {
 +    mchunkptr p = mem2chunk(mem);
 +    if (cinuse(p))
 +      return chunksize(p) - overhead_for(p);
 +  }
 +  return 0;
 +}
 +
 +int dlmallopt(int param_number, int value) {
 +  return change_mparam(param_number, value);
 +}
 +
 +#endif /* !ONLY_MSPACES */
 +
 +/* ----------------------------- user mspaces ---------------------------- */
 +
 +#if MSPACES
 +
 +static mstate init_user_mstate(char* tbase, size_t tsize) {
 +  size_t msize = pad_request(sizeof(struct malloc_state));
 +  mchunkptr mn;
 +  mchunkptr msp = align_as_chunk(tbase);
 +  mstate m = (mstate)(chunk2mem(msp));
 +  memset(m, 0, msize);
 +  INITIAL_LOCK(&m->mutex);
 +  msp->head = (msize|PINUSE_BIT|CINUSE_BIT);
 +  m->seg.base = m->least_addr = tbase;
 +  m->seg.size = m->footprint = m->max_footprint = tsize;
 +  m->magic = mparams.magic;
 +  m->mflags = mparams.default_mflags;
 +  disable_contiguous(m);
 +  init_bins(m);
 +  mn = next_chunk(mem2chunk(m));
 +  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
 +  check_top_chunk(m, m->top);
 +  return m;
 +}
 +
 +mspace create_mspace(size_t capacity, int locked) {
 +  mstate m = 0;
 +  size_t msize = pad_request(sizeof(struct malloc_state));
 +  init_mparams(); /* Ensure pagesize etc initialized */
 +
 +  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
 +    size_t rs = ((capacity == 0)? mparams.granularity :
 +                 (capacity + TOP_FOOT_SIZE + msize));
 +    size_t tsize = granularity_align(rs);
 +    char* tbase = (char*)(CALL_MMAP(tsize));
 +    if (tbase != CMFAIL) {
 +      m = init_user_mstate(tbase, tsize);
 +      set_segment_flags(&m->seg, IS_MMAPPED_BIT);
 +      set_lock(m, locked);
 +    }
 +  }
 +  return (mspace)m;
 +}
 +
 +mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
 +  mstate m = 0;
 +  size_t msize = pad_request(sizeof(struct malloc_state));
 +  init_mparams(); /* Ensure pagesize etc initialized */
 +
 +  if (capacity > msize + TOP_FOOT_SIZE &&
 +      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
 +    m = init_user_mstate((char*)base, capacity);
 +    set_segment_flags(&m->seg, EXTERN_BIT);
 +    set_lock(m, locked);
 +  }
 +  return (mspace)m;
 +}
 +
 +size_t destroy_mspace(mspace msp) {
 +  size_t freed = 0;
 +  mstate ms = (mstate)msp;
 +  if (ok_magic(ms)) {
 +    msegmentptr sp = &ms->seg;
 +    while (sp != 0) {
 +      char* base = sp->base;
 +      size_t size = sp->size;
 +      flag_t flag = get_segment_flags(sp);
 +      sp = sp->next;
 +      if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) &&
 +          CALL_MUNMAP(base, size) == 0)
 +        freed += size;
 +    }
 +  }
 +  else {
 +    USAGE_ERROR_ACTION(ms,ms);
 +  }
 +  return freed;
 +}
 +
 +/*
 +  mspace versions of routines are near-clones of the global
 +  versions. This is not so nice but better than the alternatives.
 +*/
 +
 +
 +void* mspace_malloc(mspace msp, size_t bytes) {
 +  mstate ms = (mstate)msp;
 +  if (!ok_magic(ms)) {
 +    USAGE_ERROR_ACTION(ms,ms);
 +    return 0;
 +  }
 +  if (!PREACTION(ms)) {
 +    void* mem;
 +    size_t nb;
 +    if (bytes <= MAX_SMALL_REQUEST) {
 +      bindex_t idx;
 +      binmap_t smallbits;
 +      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
 +      idx = small_index(nb);
 +      smallbits = ms->smallmap >> idx;
 +
 +      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
 +        mchunkptr b, p;
 +        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
 +        b = smallbin_at(ms, idx);
 +        p = b->fd;
 +        assert(chunksize(p) == small_index2size(idx));
 +        unlink_first_small_chunk(ms, b, p, idx);
 +        set_inuse_and_pinuse(ms, p, small_index2size(idx));
 +        mem = chunk2mem(p);
 +        check_malloced_chunk(ms, mem, nb);
 +        goto postaction;
 +      }
 +
 +      else if (nb > ms->dvsize) {
 +        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
 +          mchunkptr b, p, r;
 +          size_t rsize;
 +          bindex_t i;
 +          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
 +          binmap_t leastbit = least_bit(leftbits);
 +          compute_bit2idx(leastbit, i);
 +          b = smallbin_at(ms, i);
 +          p = b->fd;
 +          assert(chunksize(p) == small_index2size(i));
 +          unlink_first_small_chunk(ms, b, p, i);
 +          rsize = small_index2size(i) - nb;
 +          /* Fit here cannot be remainderless if 4byte sizes */
 +          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
 +            set_inuse_and_pinuse(ms, p, small_index2size(i));
 +          else {
 +            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
 +            r = chunk_plus_offset(p, nb);
 +            set_size_and_pinuse_of_free_chunk(r, rsize);
 +            replace_dv(ms, r, rsize);
 +          }
 +          mem = chunk2mem(p);
 +          check_malloced_chunk(ms, mem, nb);
 +          goto postaction;
 +        }
 +
 +        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
 +          check_malloced_chunk(ms, mem, nb);
 +          goto postaction;
 +        }
 +      }
 +    }
 +    else if (bytes >= MAX_REQUEST)
 +      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
 +    else {
 +      nb = pad_request(bytes);
 +      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
 +        check_malloced_chunk(ms, mem, nb);
 +        goto postaction;
 +      }
 +    }
 +
 +    if (nb <= ms->dvsize) {
 +      size_t rsize = ms->dvsize - nb;
 +      mchunkptr p = ms->dv;
 +      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
 +        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
 +        ms->dvsize = rsize;
 +        set_size_and_pinuse_of_free_chunk(r, rsize);
 +        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
 +      }
 +      else { /* exhaust dv */
 +        size_t dvs = ms->dvsize;
 +        ms->dvsize = 0;
 +        ms->dv = 0;
 +        set_inuse_and_pinuse(ms, p, dvs);
 +      }
 +      mem = chunk2mem(p);
 +      check_malloced_chunk(ms, mem, nb);
 +      goto postaction;
 +    }
 +
 +    else if (nb < ms->topsize) { /* Split top */
 +      size_t rsize = ms->topsize -= nb;
 +      mchunkptr p = ms->top;
 +      mchunkptr r = ms->top = chunk_plus_offset(p, nb);
 +      r->head = rsize | PINUSE_BIT;
 +      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
 +      mem = chunk2mem(p);
 +      check_top_chunk(ms, ms->top);
 +      check_malloced_chunk(ms, mem, nb);
 +      goto postaction;
 +    }
 +
 +    mem = sys_alloc(ms, nb);
 +
 +  postaction:
 +    POSTACTION(ms);
 +    return mem;
 +  }
 +
 +  return 0;
 +}
 +
 +void mspace_free(mspace msp, void* mem) {
 +  if (mem != 0) {
 +    mchunkptr p  = mem2chunk(mem);
 +#if FOOTERS
 +    mstate fm = get_mstate_for(p);
 +#else /* FOOTERS */
 +    mstate fm = (mstate)msp;
 +#endif /* FOOTERS */
 +    if (!ok_magic(fm)) {
 +      USAGE_ERROR_ACTION(fm, p);
 +      return;
 +    }
 +    if (!PREACTION(fm)) {
 +      check_inuse_chunk(fm, p);
 +      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
 +        size_t psize = chunksize(p);
 +        mchunkptr next = chunk_plus_offset(p, psize);
 +        if (!pinuse(p)) {
 +          size_t prevsize = p->prev_foot;
 +          if ((prevsize & IS_MMAPPED_BIT) != 0) {
 +            prevsize &= ~IS_MMAPPED_BIT;
 +            psize += prevsize + MMAP_FOOT_PAD;
 +            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
 +              fm->footprint -= psize;
 +            goto postaction;
 +          }
 +          else {
 +            mchunkptr prev = chunk_minus_offset(p, prevsize);
 +            psize += prevsize;
 +            p = prev;
 +            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
 +              if (p != fm->dv) {
 +                unlink_chunk(fm, p, prevsize);
 +              }
 +              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
 +                fm->dvsize = psize;
 +                set_free_with_pinuse(p, psize, next);
 +                goto postaction;
 +              }
 +            }
 +            else
 +              goto erroraction;
 +          }
 +        }
 +
 +        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
 +          if (!cinuse(next)) {  /* consolidate forward */
 +            if (next == fm->top) {
 +              size_t tsize = fm->topsize += psize;
 +              fm->top = p;
 +              p->head = tsize | PINUSE_BIT;
 +              if (p == fm->dv) {
 +                fm->dv = 0;
 +                fm->dvsize = 0;
 +              }
 +              if (should_trim(fm, tsize))
 +                sys_trim(fm, 0);
 +              goto postaction;
 +            }
 +            else if (next == fm->dv) {
 +              size_t dsize = fm->dvsize += psize;
 +              fm->dv = p;
 +              set_size_and_pinuse_of_free_chunk(p, dsize);
 +              goto postaction;
 +            }
 +            else {
 +              size_t nsize = chunksize(next);
 +              psize += nsize;
 +              unlink_chunk(fm, next, nsize);
 +              set_size_and_pinuse_of_free_chunk(p, psize);
 +              if (p == fm->dv) {
 +                fm->dvsize = psize;
 +                goto postaction;
 +              }
 +            }
 +          }
 +          else
 +            set_free_with_pinuse(p, psize, next);
 +          insert_chunk(fm, p, psize);
 +          check_free_chunk(fm, p);
 +          goto postaction;
 +        }
 +      }
 +    erroraction:
 +      USAGE_ERROR_ACTION(fm, p);
 +    postaction:
 +      POSTACTION(fm);
 +    }
 +  }
 +}
 +
 +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
 +  void* mem;
 +  size_t req = 0;
 +  mstate ms = (mstate)msp;
 +  if (!ok_magic(ms)) {
 +    USAGE_ERROR_ACTION(ms,ms);
 +    return 0;
 +  }
 +  if (n_elements != 0) {
 +    req = n_elements * elem_size;
 +    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
 +        (req / n_elements != elem_size))
 +      req = MAX_SIZE_T; /* force downstream failure on overflow */
 +  }
 +  mem = internal_malloc(ms, req);
 +  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
 +    memset(mem, 0, req);
 +  return mem;
 +}
 +
 +void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
 +  if (oldmem == 0)
 +    return mspace_malloc(msp, bytes);
 +#ifdef REALLOC_ZERO_BYTES_FREES
 +  if (bytes == 0) {
 +    mspace_free(msp, oldmem);
 +    return 0;
 +  }
 +#endif /* REALLOC_ZERO_BYTES_FREES */
 +  else {
 +#if FOOTERS
 +    mchunkptr p  = mem2chunk(oldmem);
 +    mstate ms = get_mstate_for(p);
 +#else /* FOOTERS */
 +    mstate ms = (mstate)msp;
 +#endif /* FOOTERS */
 +    if (!ok_magic(ms)) {
 +      USAGE_ERROR_ACTION(ms,ms);
 +      return 0;
 +    }
 +    return internal_realloc(ms, oldmem, bytes);
 +  }
 +}
 +
 +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
 +  mstate ms = (mstate)msp;
 +  if (!ok_magic(ms)) {
 +    USAGE_ERROR_ACTION(ms,ms);
 +    return 0;
 +  }
 +  return internal_memalign(ms, alignment, bytes);
 +}
 +
 +void** mspace_independent_calloc(mspace msp, size_t n_elements,
 +                                 size_t elem_size, void* chunks[]) {
 +  size_t sz = elem_size; /* serves as 1-element array */
 +  mstate ms = (mstate)msp;
 +  if (!ok_magic(ms)) {
 +    USAGE_ERROR_ACTION(ms,ms);
 +    return 0;
 +  }
 +  return ialloc(ms, n_elements, &sz, 3, chunks);
 +}
 +
 +void** mspace_independent_comalloc(mspace msp, size_t n_elements,
 +                                   size_t sizes[], void* chunks[]) {
 +  mstate ms = (mstate)msp;
 +  if (!ok_magic(ms)) {
 +    USAGE_ERROR_ACTION(ms,ms);
 +    return 0;
 +  }
 +  return ialloc(ms, n_elements, sizes, 0, chunks);
 +}
 +
 +int mspace_trim(mspace msp, size_t pad) {
 +  int result = 0;
 +  mstate ms = (mstate)msp;
 +  if (ok_magic(ms)) {
 +    if (!PREACTION(ms)) {
 +      result = sys_trim(ms, pad);
 +      POSTACTION(ms);
 +    }
 +  }
 +  else {
 +    USAGE_ERROR_ACTION(ms,ms);
 +  }
 +  return result;
 +}
 +
 +void mspace_malloc_stats(mspace msp) {
 +  mstate ms = (mstate)msp;
 +  if (ok_magic(ms)) {
 +    internal_malloc_stats(ms);
 +  }
 +  else {
 +    USAGE_ERROR_ACTION(ms,ms);
 +  }
 +}
 +
 +size_t mspace_footprint(mspace msp) {
 +  size_t result;
 +  mstate ms = (mstate)msp;
 +  if (ok_magic(ms)) {
 +    result = ms->footprint;
 +  }
 +  USAGE_ERROR_ACTION(ms,ms);
 +  return result;
 +}
 +
 +
 +size_t mspace_max_footprint(mspace msp) {
 +  size_t result;
 +  mstate ms = (mstate)msp;
 +  if (ok_magic(ms)) {
 +    result = ms->max_footprint;
 +  }
 +  USAGE_ERROR_ACTION(ms,ms);
 +  return result;
 +}
 +
 +
 +#if !NO_MALLINFO
 +struct mallinfo mspace_mallinfo(mspace msp) {
 +  mstate ms = (mstate)msp;
 +  if (!ok_magic(ms)) {
 +    USAGE_ERROR_ACTION(ms,ms);
 +  }
 +  return internal_mallinfo(ms);
 +}
 +#endif /* NO_MALLINFO */
 +
 +int mspace_mallopt(int param_number, int value) {
 +  return change_mparam(param_number, value);
 +}
 +
 +#endif /* MSPACES */
 +
 +/* -------------------- Alternative MORECORE functions ------------------- */
 +
 +/*
 +  Guidelines for creating a custom version of MORECORE:
 +
 +  * For best performance, MORECORE should allocate in multiples of pagesize.
 +  * MORECORE may allocate more memory than requested. (Or even less,
 +      but this will usually result in a malloc failure.)
 +  * MORECORE must not allocate memory when given argument zero, but
 +      instead return one past the end address of memory from previous
 +      nonzero call.
 +  * For best performance, consecutive calls to MORECORE with positive
 +      arguments should return increasing addresses, indicating that
 +      space has been contiguously extended.
 +  * Even though consecutive calls to MORECORE need not return contiguous
 +      addresses, it must be OK for malloc'ed chunks to span multiple
 +      regions in those cases where they do happen to be contiguous.
 +  * MORECORE need not handle negative arguments -- it may instead
 +      just return MFAIL when given negative arguments.
 +      Negative arguments are always multiples of pagesize. MORECORE
 +      must not misinterpret negative args as large positive unsigned
 +      args. You can suppress all such calls from even occurring by defining
 +      MORECORE_CANNOT_TRIM,
 +
 +  As an example alternative MORECORE, here is a custom allocator
 +  kindly contributed for pre-OSX macOS.  It uses virtually but not
 +  necessarily physically contiguous non-paged memory (locked in,
 +  present and won't get swapped out).  You can use it by uncommenting
 +  this section, adding some #includes, and setting up the appropriate
 +  defines above:
 +
 +      #define MORECORE osMoreCore
 +
 +  There is also a shutdown routine that should somehow be called for
 +  cleanup upon program exit.
 +
 +  #define MAX_POOL_ENTRIES 100
 +  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)
 +  static int next_os_pool;
 +  void *our_os_pools[MAX_POOL_ENTRIES];
 +
 +  void *osMoreCore(int size)
 +  {
 +    void *ptr = 0;
 +    static void *sbrk_top = 0;
 +
 +    if (size > 0)
 +    {
 +      if (size < MINIMUM_MORECORE_SIZE)
 +         size = MINIMUM_MORECORE_SIZE;
 +      if (CurrentExecutionLevel() == kTaskLevel)
 +         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
 +      if (ptr == 0)
 +      {
 +        return (void *) MFAIL;
 +      }
 +      // save ptrs so they can be freed during cleanup
 +      our_os_pools[next_os_pool] = ptr;
 +      next_os_pool++;
 +      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
 +      sbrk_top = (char *) ptr + size;
 +      return ptr;
 +    }
 +    else if (size < 0)
 +    {
 +      // we don't currently support shrink behavior
 +      return (void *) MFAIL;
 +    }
 +    else
 +    {
 +      return sbrk_top;
 +    }
 +  }
 +
 +  // cleanup any allocated memory pools
 +  // called as last thing before shutting down driver
 +
 +  void osCleanupMem(void)
 +  {
 +    void **ptr;
 +
 +    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
 +      if (*ptr)
 +      {
 +         PoolDeallocate(*ptr);
 +         *ptr = 0;
 +      }
 +  }
 +
 +*/
 +
 +
 +/* -----------------------------------------------------------------------
 +History:
 +    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)
 +      * Add max_footprint functions
 +      * Ensure all appropriate literals are size_t
 +      * Fix conditional compilation problem for some #define settings
 +      * Avoid concatenating segments with the one provided
 +        in create_mspace_with_base
 +      * Rename some variables to avoid compiler shadowing warnings
 +      * Use explicit lock initialization.
 +      * Better handling of sbrk interference.
 +      * Simplify and fix segment insertion, trimming and mspace_destroy
 +      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
 +      * Thanks especially to Dennis Flanagan for help on these.
 +
 +    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)
 +      * Fix memalign brace error.
 +
 +    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)
 +      * Fix improper #endif nesting in C++
 +      * Add explicit casts needed for C++
 +
 +    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)
 +      * Use trees for large bins
 +      * Support mspaces
 +      * Use segments to unify sbrk-based and mmap-based system allocation,
 +        removing need for emulation on most platforms without sbrk.
 +      * Default safety checks
 +      * Optional footer checks. Thanks to William Robertson for the idea.
 +      * Internal code refactoring
 +      * Incorporate suggestions and platform-specific changes.
 +        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
 +        Aaron Bachmann,  Emery Berger, and others.
 +      * Speed up non-fastbin processing enough to remove fastbins.
 +      * Remove useless cfree() to avoid conflicts with other apps.
 +      * Remove internal memcpy, memset. Compilers handle builtins better.
 +      * Remove some options that no one ever used and rename others.
 +
 +    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
 +      * Fix malloc_state bitmap array misdeclaration
 +
 +    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)
 +      * Allow tuning of FIRST_SORTED_BIN_SIZE
 +      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
 +      * Better detection and support for non-contiguousness of MORECORE.
 +        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
 +      * Bypass most of malloc if no frees. Thanks To Emery Berger.
 +      * Fix freeing of old top non-contiguous chunk im sysmalloc.
 +      * Raised default trim and map thresholds to 256K.
 +      * Fix mmap-related #defines. Thanks to Lubos Lunak.
 +      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
 +      * Branch-free bin calculation
 +      * Default trim and mmap thresholds now 256K.
 +
 +    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
 +      * Introduce independent_comalloc and independent_calloc.
 +        Thanks to Michael Pachos for motivation and help.
 +      * Make optional .h file available
 +      * Allow > 2GB requests on 32bit systems.
 +      * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.
 +        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
 +        and Anonymous.
 +      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
 +        helping test this.)
 +      * memalign: check alignment arg
 +      * realloc: don't try to shift chunks backwards, since this
 +        leads to  more fragmentation in some programs and doesn't
 +        seem to help in any others.
 +      * Collect all cases in malloc requiring system memory into sysmalloc
 +      * Use mmap as backup to sbrk
 +      * Place all internal state in malloc_state
 +      * Introduce fastbins (although similar to 2.5.1)
 +      * Many minor tunings and cosmetic improvements
 +      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
 +      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
 +        Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.
 +      * Include errno.h to support default failure action.
 +
 +    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
 +      * return null for negative arguments
 +      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
 +         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
 +          (e.g. WIN32 platforms)
 +         * Cleanup header file inclusion for WIN32 platforms
 +         * Cleanup code to avoid Microsoft Visual C++ compiler complaints
 +         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
 +           memory allocation routines
 +         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
 +         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
 +           usage of 'assert' in non-WIN32 code
 +         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
 +           avoid infinite loop
 +      * Always call 'fREe()' rather than 'free()'
 +
 +    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
 +      * Fixed ordering problem with boundary-stamping
 +
 +    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
 +      * Added pvalloc, as recommended by H.J. Liu
 +      * Added 64bit pointer support mainly from Wolfram Gloger
 +      * Added anonymously donated WIN32 sbrk emulation
 +      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
 +      * malloc_extend_top: fix mask error that caused wastage after
 +        foreign sbrks
 +      * Add linux mremap support code from HJ Liu
 +
 +    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
 +      * Integrated most documentation with the code.
 +      * Add support for mmap, with help from
 +        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
 +      * Use last_remainder in more cases.
 +      * Pack bins using idea from  colin@nyx10.cs.du.edu
 +      * Use ordered bins instead of best-fit threshhold
 +      * Eliminate block-local decls to simplify tracing and debugging.
 +      * Support another case of realloc via move into top
 +      * Fix error occuring when initial sbrk_base not word-aligned.
 +      * Rely on page size for units instead of SBRK_UNIT to
 +        avoid surprises about sbrk alignment conventions.
 +      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
 +        (raymond@es.ele.tue.nl) for the suggestion.
 +      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
 +      * More precautions for cases where other routines call sbrk,
 +        courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
 +      * Added macros etc., allowing use in linux libc from
 +        H.J. Lu (hjl@gnu.ai.mit.edu)
 +      * Inverted this history list
 +
 +    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
 +      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
 +      * Removed all preallocation code since under current scheme
 +        the work required to undo bad preallocations exceeds
 +        the work saved in good cases for most test programs.
 +      * No longer use return list or unconsolidated bins since
 +        no scheme using them consistently outperforms those that don't
 +        given above changes.
 +      * Use best fit for very large chunks to prevent some worst-cases.
 +      * Added some support for debugging
 +
 +    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
 +      * Removed footers when chunks are in use. Thanks to
 +        Paul Wilson (wilson@cs.texas.edu) for the suggestion.
 +
 +    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
 +      * Added malloc_trim, with help from Wolfram Gloger
 +        (wmglo@Dent.MED.Uni-Muenchen.DE).
 +
 +    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
 +
 +    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
 +      * realloc: try to expand in both directions
 +      * malloc: swap order of clean-bin strategy;
 +      * realloc: only conditionally expand backwards
 +      * Try not to scavenge used bins
 +      * Use bin counts as a guide to preallocation
 +      * Occasionally bin return list chunks in first scan
 +      * Add a few optimizations from colin@nyx10.cs.du.edu
 +
 +    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
 +      * faster bin computation & slightly different binning
 +      * merged all consolidations to one part of malloc proper
 +         (eliminating old malloc_find_space & malloc_clean_bin)
 +      * Scan 2 returns chunks (not just 1)
 +      * Propagate failure in realloc if malloc returns 0
 +      * Add stuff to allow compilation on non-ANSI compilers
 +          from kpv@research.att.com
 +
 +    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
 +      * removed potential for odd address access in prev_chunk
 +      * removed dependency on getpagesize.h
 +      * misc cosmetics and a bit more internal documentation
 +      * anticosmetics: mangled names in macros to evade debugger strangeness
 +      * tested on sparc, hp-700, dec-mips, rs6000
 +          with gcc & native cc (hp, dec only) allowing
 +          Detlefs & Zorn comparison study (in SIGPLAN Notices.)
 +
 +    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
 +      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
 +         structure of old version,  but most details differ.)
 + 
 +*/
index d84f1c393a8d5b2c6f489cf799ce74fa27b58330,66c6a3be76e1fe490c63648837a4e0e09045fbfb..5e7772068ad721e18ee3f35a5565c1ee54766275
@@@ -569,53 -478,53 +569,53 @@@ typedef struct aix_fd_struct 
     and aix_clsoure.S
  
     SP previous -> +---------------------------------------+ <--- child frame
 -                  | back chain to caller 4                |
 -                  +---------------------------------------+ 4
 -                  | saved CR 4                            |
 -                  +---------------------------------------+ 8
 -                  | saved LR 4                            |
 -                  +---------------------------------------+ 12
 -                  | reserved for compilers 4              |
 -                  +---------------------------------------+ 16
 -                  | reserved for binders 4                |
 -                  +---------------------------------------+ 20
 -                  | saved TOC pointer 4                   |
 -                  +---------------------------------------+ 24
 -                  | always reserved 8*4=32 (previous GPRs)|
 -                  | according to the linkage convention   |
 -                  | from AIX                              |
 -                  +---------------------------------------+ 56
 -                  | our FPR area 13*8=104                 |
 -                  | f1                                    |
 -                  | .                                     |
 -                  | f13                                   |
 -                  +---------------------------------------+ 160
 -                  | result area 8                         |
 -                  +---------------------------------------+ 168
 -                  | alignment to the next multiple of 16  |
 +                | back chain to caller 4                |
 +                +---------------------------------------+ 4
 +                | saved CR 4                            |
 +                +---------------------------------------+ 8
 +                | saved LR 4                            |
 +                +---------------------------------------+ 12
 +                | reserved for compilers 4              |
 +                +---------------------------------------+ 16
 +                | reserved for binders 4                |
 +                +---------------------------------------+ 20
 +                | saved TOC pointer 4                   |
 +                +---------------------------------------+ 24
 +                | always reserved 8*4=32 (previous GPRs)|
 +                | according to the linkage convention   |
 +                | from AIX                              |
 +                +---------------------------------------+ 56
 +                | our FPR area 13*8=104                 |
 +                | f1                                    |
 +                | .                                     |
 +                | f13                                   |
 +                +---------------------------------------+ 160
 +                | result area 8                         |
 +                +---------------------------------------+ 168
-                 | alignement to the next multiple of 16 |
++                | alignment to the next multiple of 16  |
  SP current -->    +---------------------------------------+ 176 <- parent frame
 -                  | back chain to caller 4                |
 -                  +---------------------------------------+ 180
 -                  | saved CR 4                            |
 -                  +---------------------------------------+ 184
 -                  | saved LR 4                            |
 -                  +---------------------------------------+ 188
 -                  | reserved for compilers 4              |
 -                  +---------------------------------------+ 192
 -                  | reserved for binders 4                |
 -                  +---------------------------------------+ 196
 -                  | saved TOC pointer 4                   |
 -                  +---------------------------------------+ 200
 -                  | always reserved 8*4=32  we store our  |
 -                  | GPRs here                             |
 -                  | r3                                    |
 -                  | .                                     |
 -                  | r10                                   |
 -                  +---------------------------------------+ 232
 -                  | overflow part                         |
 -                  +---------------------------------------+ xxx
 -                  | ????                                  |
 -                  +---------------------------------------+ xxx
 +                | back chain to caller 4                |
 +                +---------------------------------------+ 180
 +                | saved CR 4                            |
 +                +---------------------------------------+ 184
 +                | saved LR 4                            |
 +                +---------------------------------------+ 188
 +                | reserved for compilers 4              |
 +                +---------------------------------------+ 192
 +                | reserved for binders 4                |
 +                +---------------------------------------+ 196
 +                | saved TOC pointer 4                   |
 +                +---------------------------------------+ 200
 +                | always reserved 8*4=32  we store our  |
 +                | GPRs here                             |
 +                | r3                                    |
 +                | .                                     |
 +                | r10                                   |
 +                +---------------------------------------+ 232
 +                | overflow part                         |
 +                +---------------------------------------+ xxx
 +                | ????                                  |
 +                +---------------------------------------+ xxx
  
  */
  ffi_status
index 8953d5fda35818334123c592a031f4fad773a00d,e00f153d7ed9f32460dcddd518fb34271dc5c5bd..dba2184099a255452218f5bbe50134a443e93398
@@@ -627,53 -627,53 +627,53 @@@ ffi_call
     and aix_clsoure.S
  
     SP previous -> +---------------------------------------+ <--- child frame
 -                  | back chain to caller 4                |
 -                  +---------------------------------------+ 4
 -                  | saved CR 4                            |
 -                  +---------------------------------------+ 8
 -                  | saved LR 4                            |
 -                  +---------------------------------------+ 12
 -                  | reserved for compilers 4              |
 -                  +---------------------------------------+ 16
 -                  | reserved for binders 4                |
 -                  +---------------------------------------+ 20
 -                  | saved TOC pointer 4                   |
 -                  +---------------------------------------+ 24
 -                  | always reserved 8*4=32 (previous GPRs)|
 -                  | according to the linkage convention   |
 -                  | from AIX                              |
 -                  +---------------------------------------+ 56
 -                  | our FPR area 13*8=104                 |
 -                  | f1                                    |
 -                  | .                                     |
 -                  | f13                                   |
 -                  +---------------------------------------+ 160
 -                  | result area 8                         |
 -                  +---------------------------------------+ 168
 -                  | alignment to the next multiple of 16  |
 +                | back chain to caller 4                |
 +                +---------------------------------------+ 4
 +                | saved CR 4                            |
 +                +---------------------------------------+ 8
 +                | saved LR 4                            |
 +                +---------------------------------------+ 12
 +                | reserved for compilers 4              |
 +                +---------------------------------------+ 16
 +                | reserved for binders 4                |
 +                +---------------------------------------+ 20
 +                | saved TOC pointer 4                   |
 +                +---------------------------------------+ 24
 +                | always reserved 8*4=32 (previous GPRs)|
 +                | according to the linkage convention   |
 +                | from AIX                              |
 +                +---------------------------------------+ 56
 +                | our FPR area 13*8=104                 |
 +                | f1                                    |
 +                | .                                     |
 +                | f13                                   |
 +                +---------------------------------------+ 160
 +                | result area 8                         |
 +                +---------------------------------------+ 168
-                 | alignement to the next multiple of 16 |
++                | alignment to the next multiple of 16  |
  SP current -->    +---------------------------------------+ 176 <- parent frame
 -                  | back chain to caller 4                |
 -                  +---------------------------------------+ 180
 -                  | saved CR 4                            |
 -                  +---------------------------------------+ 184
 -                  | saved LR 4                            |
 -                  +---------------------------------------+ 188
 -                  | reserved for compilers 4              |
 -                  +---------------------------------------+ 192
 -                  | reserved for binders 4                |
 -                  +---------------------------------------+ 196
 -                  | saved TOC pointer 4                   |
 -                  +---------------------------------------+ 200
 -                  | always reserved 8*4=32  we store our  |
 -                  | GPRs here                             |
 -                  | r3                                    |
 -                  | .                                     |
 -                  | r10                                   |
 -                  +---------------------------------------+ 232
 -                  | overflow part                         |
 -                  +---------------------------------------+ xxx
 -                  | ????                                  |
 -                  +---------------------------------------+ xxx
 +                | back chain to caller 4                |
 +                +---------------------------------------+ 180
 +                | saved CR 4                            |
 +                +---------------------------------------+ 184
 +                | saved LR 4                            |
 +                +---------------------------------------+ 188
 +                | reserved for compilers 4              |
 +                +---------------------------------------+ 192
 +                | reserved for binders 4                |
 +                +---------------------------------------+ 196
 +                | saved TOC pointer 4                   |
 +                +---------------------------------------+ 200
 +                | always reserved 8*4=32  we store our  |
 +                | GPRs here                             |
 +                | r3                                    |
 +                | .                                     |
 +                | r10                                   |
 +                +---------------------------------------+ 232
 +                | overflow part                         |
 +                +---------------------------------------+ xxx
 +                | ????                                  |
 +                +---------------------------------------+ xxx
  */
  
  #if !defined(POWERPC_DARWIN)
Simple merge
Simple merge
Simple merge
index 39beaba691b93d8a6a945b4b5446b51f676a6e45,a836af6cd05d272f2125a220c1edd0d44978bac2..89d3f2f2d0b783d32eb2a9307692f9d6ce5bfe29
@@@ -1269,44 -1193,6 +1269,44 @@@ win32_xstat_w(const wchar_t *path, stru
      return code;
  }
  
-    The _w represent Unicode equivalents of the aformentioned ANSI functions. */
 +/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
 +   win32_stat_w
 +
 +   In Posix, stat automatically traverses symlinks and returns the stat
 +   structure for the target.  In Windows, the equivalent GetFileAttributes by
 +   default does not traverse symlinks and instead returns attributes for
 +   the symlink.
 +
 +   Therefore, win32_lstat will get the attributes traditionally, and
 +   win32_stat will first explicitly resolve the symlink target and then will
 +   call win32_lstat on that result.
 +
++   The _w represent Unicode equivalents of the aforementioned ANSI functions. */
 +
 +static int 
 +win32_lstat(const char* path, struct win32_stat *result)
 +{
 +    return win32_xstat(path, result, FALSE);
 +}
 +
 +static int
 +win32_lstat_w(const wchar_t* path, struct win32_stat *result)
 +{
 +    return win32_xstat_w(path, result, FALSE);
 +}
 +
 +static int
 +win32_stat(const char* path, struct win32_stat *result)
 +{
 +    return win32_xstat(path, result, TRUE);
 +}
 +
 +static int 
 +win32_stat_w(const wchar_t* path, struct win32_stat *result)
 +{
 +    return win32_xstat_w(path, result, TRUE);
 +}
 +
  static int
  win32_fstat(int file_number, struct win32_stat *result)
  {
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 51c39e48d4eb5d989366dd6e5706cdad7ca53c3a,543e0bb4cac63ccc1576b2eff4d3cbc5e78fd147..a797887b9c2dd68acddac5f542047190f21d1996
@@@ -728,43 -732,7 +728,43 @@@ warn_unicode(PyObject *category, PyObje
      return 0;
  }
  
- /* PyErr_Warn is only for backwards compatability and will be removed.
 +int
 +PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
 +                 const char *format, ...)
 +{
 +    int ret;
 +    PyObject *message;
 +    va_list vargs;
 +
 +#ifdef HAVE_STDARG_PROTOTYPES
 +    va_start(vargs, format);
 +#else
 +    va_start(vargs);
 +#endif
 +    message = PyUnicode_FromFormatV(format, vargs);
 +    if (message != NULL) {
 +        ret = warn_unicode(category, message, stack_level);
 +        Py_DECREF(message);
 +    }
 +    else
 +        ret = -1;
 +    va_end(vargs);
 +    return ret;
 +}
 +
 +int
 +PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
 +{
 +    int ret;
 +    PyObject *message = PyUnicode_FromString(text);
 +    if (message == NULL)
 +        return -1;
 +    ret = warn_unicode(category, message, stack_level);
 +    Py_DECREF(message);
 +    return ret;
 +}
 +
+ /* PyErr_Warn is only for backwards compatibility and will be removed.
     Use PyErr_WarnEx instead. */
  
  #undef PyErr_Warn
index ea095d26607a66922e0c6f580253721ff40f504c,f85cc55ad1d8074e0f1b2eda6e3904c1baef2f43..8d44135be1026aa2c4f32bd12b14e3478f87437e
@@@ -683,40 -544,13 +683,40 @@@ recursion from causing an overflow of t
  PyDoc_STRVAR(getwindowsversion_doc,
  "getwindowsversion()\n\
  \n\
 -Return information about the running version of Windows.\n\
 -The result is a tuple of (major, minor, build, platform, text)\n\
 -All elements are numbers, except text which is a string.\n\
 -Platform may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP\n\
 -"
 +Return information about the running version of Windows as a named tuple.\n\
 +The members are named: major, minor, build, platform, service_pack,\n\
 +service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\
- backward compatibiliy, only the first 5 items are available by indexing.\n\
++backward compatibility, only the first 5 items are available by indexing.\n\
 +All elements are numbers, except service_pack which is a string. Platform\n\
 +may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7,\n\
 +3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain\n\
 +controller, 3 for a server."
  );
  
 +static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
 +
 +static PyStructSequence_Field windows_version_fields[] = {
 +    {"major", "Major version number"},
 +    {"minor", "Minor version number"},
 +    {"build", "Build number"},
 +    {"platform", "Operating system platform"},
 +    {"service_pack", "Latest Service Pack installed on the system"},
 +    {"service_pack_major", "Service Pack major version number"},
 +    {"service_pack_minor", "Service Pack minor version number"},
 +    {"suite_mask", "Bit mask identifying available product suites"},
 +    {"product_type", "System product type"},
 +    {0}
 +};
 +
 +static PyStructSequence_Desc windows_version_desc = {
 +    "sys.getwindowsversion",  /* name */
 +    getwindowsversion_doc,    /* doc */
 +    windows_version_fields,   /* fields */
 +    5                         /* For backward compatibility,
 +                                 only the first 5 items are accessible
 +                                 via indexing, the rest are name only */
 +};
 +
  static PyObject *
  sys_getwindowsversion(PyObject *self)
  {
index 2d1e49058c80daefbaaf62f4574ad130a99b19a9,8b074895e4995bc866b61c98fe195de95efe9a50..4cea66717100010fc267748b3898d44054071782
mode 100755,100644..100755
@@@ -586,7 -582,7 +586,7 @@@ class SheetGUI
          cell = Tk.Label(self.cellgrid, relief='raised')
          cell.grid_configure(column=0, row=0, sticky='NSWE')
          cell.bind("<ButtonPress-1>", self.selectall)
--        # Create the top row of labels, and confiure the grid columns
++        # Create the top row of labels, and configure the grid columns
          for x in range(1, columns+1):
              self.cellgrid.grid_columnconfigure(x, minsize=64)
              cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised')
Simple merge
Simple merge
diff --cc setup.py
Simple merge