Merge remote-tracking branch 'origin/pr/2563' into mbedtls-2.7

* origin/pr/2563:
  Fix CMake build error on Cygwin and minGW platforms
diff --git a/.travis.yml b/.travis.yml
index 4d23652..b4f21a3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,7 +24,8 @@
 - tests/scripts/travis-log-failure.sh
 env:
   global:
-    secure: "barHldniAfXyoWOD/vcO+E6/Xm4fmcaUoC9BeKW+LwsHqlDMLvugaJnmLXkSpkbYhVL61Hzf3bo0KPJn88AFc5Rkf8oYHPjH4adMnVXkf3B9ghHCgznqHsAH3choo6tnPxaFgOwOYmLGb382nQxfE5lUdvnM/W/psQjWt66A1+k="
+    - SEED=1
+    - secure: "barHldniAfXyoWOD/vcO+E6/Xm4fmcaUoC9BeKW+LwsHqlDMLvugaJnmLXkSpkbYhVL61Hzf3bo0KPJn88AFc5Rkf8oYHPjH4adMnVXkf3B9ghHCgznqHsAH3choo6tnPxaFgOwOYmLGb382nQxfE5lUdvnM/W/psQjWt66A1+k="
 
 addons:
   apt:
diff --git a/ChangeLog b/ChangeLog
index 54971ae..d57b890 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,12 +24,19 @@
    * Fix potential memory leak in X.509 self test. Found and fixed by
      Junhwan Park, #2106.
    * Fix 1-byte buffer overflow in mbedtls_mpi_write_string() when
-     used with negative inputs. Found by Guido Vranken in #2404.
+     used with negative inputs. Found by Guido Vranken in #2404. Credit to
+     OSS-Fuzz.
    * Fix bugs in the AEAD test suite which would be exposed by ciphers which
      either used both encrypt and decrypt key schedules, or which perform padding.
      GCM and CCM were not affected. Fixed by Jack Lloyd.
    * Fix incorrect default port number in ssl_mail_client example's usage.
      Found and fixed by irwir. #2337
+   * Add missing parentheses around parameters in the definition of the
+     public macro MBEDTLS_X509_ID_FLAG. This could lead to invalid evaluation
+     in case operators binding less strongly than subtraction were used
+     for the parameter.
+   * Add a check for MBEDTLS_X509_CRL_PARSE_C in ssl_server2, guarding the crl
+     sni entry parameter. Reported by inestlerode in #560.
 
 Changes
    * Return from various debugging routines immediately if the
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 2c3c758..e72231e 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -98,7 +98,7 @@
  * Build flag from an algorithm/curve identifier (pk, md, ecp)
  * Since 0 is always XXX_NONE, ignore it.
  */
-#define MBEDTLS_X509_ID_FLAG( id )   ( 1 << ( id - 1 ) )
+#define MBEDTLS_X509_ID_FLAG( id )   ( 1 << ( ( id ) - 1 ) )
 
 /**
  * Security profile for certificate verification.
diff --git a/programs/Makefile b/programs/Makefile
index 25f184f..b4a553a 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -65,7 +65,7 @@
 	ssl/ssl_mail_client$(EXEXT)	random/gen_entropy$(EXEXT)	\
 	random/gen_random_havege$(EXEXT)				\
 	random/gen_random_ctr_drbg$(EXEXT)				\
-	test/ssl_cert_test$(EXEXT)	test/benchmark$(EXEXT)		\
+	test/benchmark$(EXEXT)                          		\
 	test/selftest$(EXEXT)		test/udp_proxy$(EXEXT)		\
 	util/pem2der$(EXEXT)		util/strerror$(EXEXT)		\
 	x509/cert_app$(EXEXT)		x509/crl_app$(EXEXT)		\
@@ -233,10 +233,6 @@
 	echo "  CC    ssl/mini_client.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) ssl/mini_client.c   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
-test/ssl_cert_test$(EXEXT): test/ssl_cert_test.c $(DEP)
-	echo "  CC    test/ssl_cert_test.c"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/ssl_cert_test.c   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-
 test/benchmark$(EXEXT): test/benchmark.c $(DEP)
 	echo "  CC    test/benchmark.c"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/benchmark.c   $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index ec23c8a..e8e5cd1 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -229,8 +229,14 @@
 #endif /* MBEDTLS_SSL_CACHE_C */
 
 #if defined(SNI_OPTION)
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+#define SNI_CRL              ",crl"
+#else
+#define SNI_CRL              ""
+#endif
+
 #define USAGE_SNI                                                           \
-    "    sni=%%s              name1,cert1,key1,ca1,crl1,auth1[,...]\n"  \
+    "    sni=%%s              name1,cert1,key1,ca1"SNI_CRL",auth1[,...]\n"  \
     "                        default: disabled\n"
 #else
 #define USAGE_SNI ""
@@ -565,10 +571,10 @@
 
         mbedtls_x509_crt_free( cur->ca );
         mbedtls_free( cur->ca );
-
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
         mbedtls_x509_crl_free( cur->crl );
         mbedtls_free( cur->crl );
-
+#endif
         next = cur->next;
         mbedtls_free( cur );
         cur = next;
@@ -587,7 +593,10 @@
     sni_entry *cur = NULL, *new = NULL;
     char *p = sni_string;
     char *end = p;
-    char *crt_file, *key_file, *ca_file, *crl_file, *auth_str;
+    char *crt_file, *key_file, *ca_file, *auth_str;
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+    char *crl_file;
+#endif
 
     while( *end != '\0' )
         ++end;
@@ -605,7 +614,9 @@
         GET_ITEM( crt_file );
         GET_ITEM( key_file );
         GET_ITEM( ca_file );
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
         GET_ITEM( crl_file );
+#endif
         GET_ITEM( auth_str );
 
         if( ( new->cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ) ) == NULL ||
@@ -630,6 +641,7 @@
                 goto error;
         }
 
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
         if( strcmp( crl_file, "-" ) != 0 )
         {
             if( ( new->crl = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) ) ) == NULL )
@@ -640,6 +652,7 @@
             if( mbedtls_x509_crl_parse_file( new->crl, crl_file ) != 0 )
                 goto error;
         }
+#endif
 
         if( strcmp( auth_str, "-" ) != 0 )
         {
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 0ed7145..64b9637 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -16,12 +16,10 @@
 add_executable(benchmark benchmark.c)
 target_link_libraries(benchmark ${libs})
 
-add_executable(ssl_cert_test ssl_cert_test.c)
-target_link_libraries(ssl_cert_test ${libs})
 
 add_executable(udp_proxy udp_proxy.c)
 target_link_libraries(udp_proxy ${libs})
 
-install(TARGETS selftest benchmark ssl_cert_test udp_proxy
+install(TARGETS selftest benchmark udp_proxy
         DESTINATION "bin"
         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/programs/test/ssl_cert_test.c b/programs/test/ssl_cert_test.c
deleted file mode 100644
index fd3526f..0000000
--- a/programs/test/ssl_cert_test.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- *  SSL certificate functionality tests
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *  This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#define mbedtls_snprintf        snprintf
-#define mbedtls_printf          printf
-#define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
-#define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
-#endif /* MBEDTLS_PLATFORM_C */
-
-#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
-    defined(MBEDTLS_FS_IO) && defined(MBEDTLS_X509_CRL_PARSE_C)
-#include "mbedtls/certs.h"
-#include "mbedtls/x509_crt.h"
-
-#include <stdio.h>
-#include <string.h>
-#endif
-
-#define MAX_CLIENT_CERTS    8
-
-#if !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
-    !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_X509_CRL_PARSE_C)
-int main( void )
-{
-    mbedtls_printf("MBEDTLS_RSA_C and/or MBEDTLS_X509_CRT_PARSE_C "
-           "MBEDTLS_FS_IO and/or MBEDTLS_X509_CRL_PARSE_C "
-           "not defined.\n");
-    return( 0 );
-}
-#else
-const char *client_certificates[MAX_CLIENT_CERTS] =
-{
-    "client1.crt",
-    "client2.crt",
-    "server1.crt",
-    "server2.crt",
-    "cert_sha224.crt",
-    "cert_sha256.crt",
-    "cert_sha384.crt",
-    "cert_sha512.crt"
-};
-
-const char *client_private_keys[MAX_CLIENT_CERTS] =
-{
-    "client1.key",
-    "client2.key",
-    "server1.key",
-    "server2.key",
-    "cert_digest.key",
-    "cert_digest.key",
-    "cert_digest.key",
-    "cert_digest.key"
-};
-
-int main( void )
-{
-    int ret = 1, i;
-    int exit_code = MBEDTLS_EXIT_FAILURE;
-    mbedtls_x509_crt cacert;
-    mbedtls_x509_crl crl;
-    char buf[10240];
-
-    mbedtls_x509_crt_init( &cacert );
-    mbedtls_x509_crl_init( &crl );
-
-    /*
-     * 1.1. Load the trusted CA
-     */
-    mbedtls_printf( "\n  . Loading the CA root certificate ..." );
-    fflush( stdout );
-
-    /*
-     * Alternatively, you may load the CA certificates from a .pem or
-     * .crt file by calling mbedtls_x509_crt_parse_file( &cacert, "myca.crt" ).
-     */
-    ret = mbedtls_x509_crt_parse_file( &cacert, "ssl/test-ca/test-ca.crt" );
-    if( ret != 0 )
-    {
-        mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
-        goto exit;
-    }
-
-    mbedtls_printf( " ok\n" );
-
-    mbedtls_x509_crt_info( buf, 1024, "CRT: ", &cacert );
-    mbedtls_printf("%s\n", buf );
-
-    /*
-     * 1.2. Load the CRL
-     */
-    mbedtls_printf( "  . Loading the CRL ..." );
-    fflush( stdout );
-
-    ret = mbedtls_x509_crl_parse_file( &crl, "ssl/test-ca/crl.pem" );
-    if( ret != 0 )
-    {
-        mbedtls_printf( " failed\n  !  mbedtls_x509_crl_parse_file returned %d\n\n", ret );
-        goto exit;
-    }
-
-    mbedtls_printf( " ok\n" );
-
-    mbedtls_x509_crl_info( buf, 1024, "CRL: ", &crl );
-    mbedtls_printf("%s\n", buf );
-
-    for( i = 0; i < MAX_CLIENT_CERTS; i++ )
-    {
-        /*
-         * 1.3. Load own certificate
-         */
-        char    name[512];
-        uint32_t flags;
-        mbedtls_x509_crt clicert;
-        mbedtls_pk_context pk;
-
-        mbedtls_x509_crt_init( &clicert );
-        mbedtls_pk_init( &pk );
-
-        mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_certificates[i]);
-
-        mbedtls_printf( "  . Loading the client certificate %s...", name );
-        fflush( stdout );
-
-        ret = mbedtls_x509_crt_parse_file( &clicert, name );
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
-            goto exit;
-        }
-
-        mbedtls_printf( " ok\n" );
-
-        /*
-         * 1.4. Verify certificate validity with CA certificate
-         */
-        mbedtls_printf( "  . Verify the client certificate with CA certificate..." );
-        fflush( stdout );
-
-        ret = mbedtls_x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL,
-                               NULL );
-        if( ret != 0 )
-        {
-            if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
-            {
-                 char vrfy_buf[512];
-
-                 mbedtls_printf( " failed\n" );
-                 mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
-                 mbedtls_printf( "%s\n", vrfy_buf );
-             }
-             else
-             {
-                mbedtls_printf( " failed\n  !  mbedtls_x509_crt_verify returned %d\n\n", ret );
-                goto exit;
-            }
-        }
-
-        mbedtls_printf( " ok\n" );
-
-        /*
-         * 1.5. Load own private key
-         */
-        mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_private_keys[i]);
-
-        mbedtls_printf( "  . Loading the client private key %s...", name );
-        fflush( stdout );
-
-        ret = mbedtls_pk_parse_keyfile( &pk, name, NULL );
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned %d\n\n", ret );
-            goto exit;
-        }
-
-        mbedtls_printf( " ok\n" );
-
-        /*
-         * 1.6. Verify certificate validity with private key
-         */
-        mbedtls_printf( "  . Verify the client certificate with private key..." );
-        fflush( stdout );
-
-
-        /* EC NOT IMPLEMENTED YET */
-        if( ! mbedtls_pk_can_do( &clicert.pk, MBEDTLS_PK_RSA ) )
-        {
-            mbedtls_printf( " failed\n  !  certificate's key is not RSA\n\n" );
-            goto exit;
-        }
-
-        ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->N, &mbedtls_pk_rsa( clicert.pk )->N);
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for N returned %d\n\n", ret );
-            goto exit;
-        }
-
-        ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->E, &mbedtls_pk_rsa( clicert.pk )->E);
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for E returned %d\n\n", ret );
-            goto exit;
-        }
-
-        ret = mbedtls_rsa_check_privkey( mbedtls_pk_rsa( pk ) );
-        if( ret != 0 )
-        {
-            mbedtls_printf( " failed\n  !  mbedtls_rsa_check_privkey returned %d\n\n", ret );
-            goto exit;
-        }
-
-        mbedtls_printf( " ok\n" );
-
-        mbedtls_x509_crt_free( &clicert );
-        mbedtls_pk_free( &pk );
-    }
-
-    exit_code = MBEDTLS_EXIT_SUCCESS;
-
-exit:
-    mbedtls_x509_crt_free( &cacert );
-    mbedtls_x509_crl_free( &crl );
-
-#if defined(_WIN32)
-    mbedtls_printf( "  + Press Enter to exit this program.\n" );
-    fflush( stdout ); getchar();
-#endif
-
-    return( exit_code );
-}
-#endif /* MBEDTLS_RSA_C && MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO &&
-          MBEDTLS_X509_CRL_PARSE_C */
diff --git a/scripts/abi_check.py b/scripts/abi_check.py
new file mode 100755
index 0000000..f837f7a
--- /dev/null
+++ b/scripts/abi_check.py
@@ -0,0 +1,404 @@
+#!/usr/bin/env python3
+"""
+This file is part of Mbed TLS (https://tls.mbed.org)
+
+Copyright (c) 2018, Arm Limited, All Rights Reserved
+
+Purpose
+
+This script is a small wrapper around the abi-compliance-checker and
+abi-dumper tools, applying them to compare the ABI and API of the library
+files from two different Git revisions within an Mbed TLS repository.
+The results of the comparison are either formatted as HTML and stored at
+a configurable location, or are given as a brief list of problems.
+Returns 0 on success, 1 on ABI/API non-compliance, and 2 if there is an error
+while running the script. Note: must be run from Mbed TLS root.
+"""
+
+import os
+import sys
+import traceback
+import shutil
+import subprocess
+import argparse
+import logging
+import tempfile
+import fnmatch
+from types import SimpleNamespace
+
+import xml.etree.ElementTree as ET
+
+
+class AbiChecker(object):
+    """API and ABI checker."""
+
+    def __init__(self, old_version, new_version, configuration):
+        """Instantiate the API/ABI checker.
+
+        old_version: RepoVersion containing details to compare against
+        new_version: RepoVersion containing details to check
+        configuration.report_dir: directory for output files
+        configuration.keep_all_reports: if false, delete old reports
+        configuration.brief: if true, output shorter report to stdout
+        configuration.skip_file: path to file containing symbols and types to skip
+        """
+        self.repo_path = "."
+        self.log = None
+        self.verbose = configuration.verbose
+        self._setup_logger()
+        self.report_dir = os.path.abspath(configuration.report_dir)
+        self.keep_all_reports = configuration.keep_all_reports
+        self.can_remove_report_dir = not (os.path.exists(self.report_dir) or
+                                          self.keep_all_reports)
+        self.old_version = old_version
+        self.new_version = new_version
+        self.skip_file = configuration.skip_file
+        self.brief = configuration.brief
+        self.git_command = "git"
+        self.make_command = "make"
+
+    @staticmethod
+    def check_repo_path():
+        current_dir = os.path.realpath('.')
+        root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+        if current_dir != root_dir:
+            raise Exception("Must be run from Mbed TLS root")
+
+    def _setup_logger(self):
+        self.log = logging.getLogger()
+        if self.verbose:
+            self.log.setLevel(logging.DEBUG)
+        else:
+            self.log.setLevel(logging.INFO)
+        self.log.addHandler(logging.StreamHandler())
+
+    @staticmethod
+    def check_abi_tools_are_installed():
+        for command in ["abi-dumper", "abi-compliance-checker"]:
+            if not shutil.which(command):
+                raise Exception("{} not installed, aborting".format(command))
+
+    def _get_clean_worktree_for_git_revision(self, version):
+        """Make a separate worktree with version.revision checked out.
+        Do not modify the current worktree."""
+        git_worktree_path = tempfile.mkdtemp()
+        if version.repository:
+            self.log.debug(
+                "Checking out git worktree for revision {} from {}".format(
+                    version.revision, version.repository
+                )
+            )
+            fetch_output = subprocess.check_output(
+                [self.git_command, "fetch",
+                 version.repository, version.revision],
+                cwd=self.repo_path,
+                stderr=subprocess.STDOUT
+            )
+            self.log.debug(fetch_output.decode("utf-8"))
+            worktree_rev = "FETCH_HEAD"
+        else:
+            self.log.debug("Checking out git worktree for revision {}".format(
+                version.revision
+            ))
+            worktree_rev = version.revision
+        worktree_output = subprocess.check_output(
+            [self.git_command, "worktree", "add", "--detach",
+             git_worktree_path, worktree_rev],
+            cwd=self.repo_path,
+            stderr=subprocess.STDOUT
+        )
+        self.log.debug(worktree_output.decode("utf-8"))
+        return git_worktree_path
+
+    def _update_git_submodules(self, git_worktree_path, version):
+        """If the crypto submodule is present, initialize it.
+        if version.crypto_revision exists, update it to that revision,
+        otherwise update it to the default revision"""
+        update_output = subprocess.check_output(
+            [self.git_command, "submodule", "update", "--init", '--recursive'],
+            cwd=git_worktree_path,
+            stderr=subprocess.STDOUT
+        )
+        self.log.debug(update_output.decode("utf-8"))
+        if not (os.path.exists(os.path.join(git_worktree_path, "crypto"))
+                and version.crypto_revision):
+            return
+
+        if version.crypto_repository:
+            fetch_output = subprocess.check_output(
+                [self.git_command, "fetch", version.crypto_repository,
+                 version.crypto_revision],
+                cwd=os.path.join(git_worktree_path, "crypto"),
+                stderr=subprocess.STDOUT
+            )
+            self.log.debug(fetch_output.decode("utf-8"))
+            crypto_rev = "FETCH_HEAD"
+        else:
+            crypto_rev = version.crypto_revision
+
+        checkout_output = subprocess.check_output(
+            [self.git_command, "checkout", crypto_rev],
+            cwd=os.path.join(git_worktree_path, "crypto"),
+            stderr=subprocess.STDOUT
+        )
+        self.log.debug(checkout_output.decode("utf-8"))
+
+    def _build_shared_libraries(self, git_worktree_path, version):
+        """Build the shared libraries in the specified worktree."""
+        my_environment = os.environ.copy()
+        my_environment["CFLAGS"] = "-g -Og"
+        my_environment["SHARED"] = "1"
+        my_environment["USE_CRYPTO_SUBMODULE"] = "1"
+        make_output = subprocess.check_output(
+            [self.make_command, "lib"],
+            env=my_environment,
+            cwd=git_worktree_path,
+            stderr=subprocess.STDOUT
+        )
+        self.log.debug(make_output.decode("utf-8"))
+        for root, _dirs, files in os.walk(git_worktree_path):
+            for file in fnmatch.filter(files, "*.so"):
+                version.modules[os.path.splitext(file)[0]] = (
+                    os.path.join(root, file)
+                )
+
+    def _get_abi_dumps_from_shared_libraries(self, version):
+        """Generate the ABI dumps for the specified git revision.
+        The shared libraries must have been built and the module paths
+        present in version.modules."""
+        for mbed_module, module_path in version.modules.items():
+            output_path = os.path.join(
+                self.report_dir, "{}-{}-{}.dump".format(
+                    mbed_module, version.revision, version.version
+                )
+            )
+            abi_dump_command = [
+                "abi-dumper",
+                module_path,
+                "-o", output_path,
+                "-lver", version.revision
+            ]
+            abi_dump_output = subprocess.check_output(
+                abi_dump_command,
+                stderr=subprocess.STDOUT
+            )
+            self.log.debug(abi_dump_output.decode("utf-8"))
+            version.abi_dumps[mbed_module] = output_path
+
+    def _cleanup_worktree(self, git_worktree_path):
+        """Remove the specified git worktree."""
+        shutil.rmtree(git_worktree_path)
+        worktree_output = subprocess.check_output(
+            [self.git_command, "worktree", "prune"],
+            cwd=self.repo_path,
+            stderr=subprocess.STDOUT
+        )
+        self.log.debug(worktree_output.decode("utf-8"))
+
+    def _get_abi_dump_for_ref(self, version):
+        """Generate the ABI dumps for the specified git revision."""
+        git_worktree_path = self._get_clean_worktree_for_git_revision(version)
+        self._update_git_submodules(git_worktree_path, version)
+        self._build_shared_libraries(git_worktree_path, version)
+        self._get_abi_dumps_from_shared_libraries(version)
+        self._cleanup_worktree(git_worktree_path)
+
+    def _remove_children_with_tag(self, parent, tag):
+        children = parent.getchildren()
+        for child in children:
+            if child.tag == tag:
+                parent.remove(child)
+            else:
+                self._remove_children_with_tag(child, tag)
+
+    def _remove_extra_detail_from_report(self, report_root):
+        for tag in ['test_info', 'test_results', 'problem_summary',
+                    'added_symbols', 'removed_symbols', 'affected']:
+            self._remove_children_with_tag(report_root, tag)
+
+        for report in report_root:
+            for problems in report.getchildren()[:]:
+                if not problems.getchildren():
+                    report.remove(problems)
+
+    def get_abi_compatibility_report(self):
+        """Generate a report of the differences between the reference ABI
+        and the new ABI. ABI dumps from self.old_version and self.new_version
+        must be available."""
+        compatibility_report = ""
+        compliance_return_code = 0
+        shared_modules = list(set(self.old_version.modules.keys()) &
+                              set(self.new_version.modules.keys()))
+        for mbed_module in shared_modules:
+            output_path = os.path.join(
+                self.report_dir, "{}-{}-{}.html".format(
+                    mbed_module, self.old_version.revision,
+                    self.new_version.revision
+                )
+            )
+            abi_compliance_command = [
+                "abi-compliance-checker",
+                "-l", mbed_module,
+                "-old", self.old_version.abi_dumps[mbed_module],
+                "-new", self.new_version.abi_dumps[mbed_module],
+                "-strict",
+                "-report-path", output_path,
+            ]
+            if self.skip_file:
+                abi_compliance_command += ["-skip-symbols", self.skip_file,
+                                           "-skip-types", self.skip_file]
+            if self.brief:
+                abi_compliance_command += ["-report-format", "xml",
+                                           "-stdout"]
+            try:
+                subprocess.check_output(
+                    abi_compliance_command,
+                    stderr=subprocess.STDOUT
+                )
+            except subprocess.CalledProcessError as err:
+                if err.returncode == 1:
+                    compliance_return_code = 1
+                    if self.brief:
+                        self.log.info(
+                            "Compatibility issues found for {}".format(mbed_module)
+                        )
+                        report_root = ET.fromstring(err.output.decode("utf-8"))
+                        self._remove_extra_detail_from_report(report_root)
+                        self.log.info(ET.tostring(report_root).decode("utf-8"))
+                    else:
+                        self.can_remove_report_dir = False
+                        compatibility_report += (
+                            "Compatibility issues found for {}, "
+                            "for details see {}\n".format(mbed_module, output_path)
+                        )
+                else:
+                    raise err
+            else:
+                compatibility_report += (
+                    "No compatibility issues for {}\n".format(mbed_module)
+                )
+                if not (self.keep_all_reports or self.brief):
+                    os.remove(output_path)
+            os.remove(self.old_version.abi_dumps[mbed_module])
+            os.remove(self.new_version.abi_dumps[mbed_module])
+        if self.can_remove_report_dir:
+            os.rmdir(self.report_dir)
+        self.log.info(compatibility_report)
+        return compliance_return_code
+
+    def check_for_abi_changes(self):
+        """Generate a report of ABI differences
+        between self.old_rev and self.new_rev."""
+        self.check_repo_path()
+        self.check_abi_tools_are_installed()
+        self._get_abi_dump_for_ref(self.old_version)
+        self._get_abi_dump_for_ref(self.new_version)
+        return self.get_abi_compatibility_report()
+
+
+def run_main():
+    try:
+        parser = argparse.ArgumentParser(
+            description=(
+                """This script is a small wrapper around the
+                abi-compliance-checker and abi-dumper tools, applying them
+                to compare the ABI and API of the library files from two
+                different Git revisions within an Mbed TLS repository.
+                The results of the comparison are either formatted as HTML and
+                stored at a configurable location, or are given as a brief list
+                of problems. Returns 0 on success, 1 on ABI/API non-compliance,
+                and 2 if there is an error while running the script.
+                Note: must be run from Mbed TLS root."""
+            )
+        )
+        parser.add_argument(
+            "-v", "--verbose", action="store_true",
+            help="set verbosity level",
+        )
+        parser.add_argument(
+            "-r", "--report-dir", type=str, default="reports",
+            help="directory where reports are stored, default is reports",
+        )
+        parser.add_argument(
+            "-k", "--keep-all-reports", action="store_true",
+            help="keep all reports, even if there are no compatibility issues",
+        )
+        parser.add_argument(
+            "-o", "--old-rev", type=str, help="revision for old version.",
+            required=True,
+        )
+        parser.add_argument(
+            "-or", "--old-repo", type=str, help="repository for old version."
+        )
+        parser.add_argument(
+            "-oc", "--old-crypto-rev", type=str,
+            help="revision for old crypto submodule."
+        )
+        parser.add_argument(
+            "-ocr", "--old-crypto-repo", type=str,
+            help="repository for old crypto submodule."
+        )
+        parser.add_argument(
+            "-n", "--new-rev", type=str, help="revision for new version",
+            required=True,
+        )
+        parser.add_argument(
+            "-nr", "--new-repo", type=str, help="repository for new version."
+        )
+        parser.add_argument(
+            "-nc", "--new-crypto-rev", type=str,
+            help="revision for new crypto version"
+        )
+        parser.add_argument(
+            "-ncr", "--new-crypto-repo", type=str,
+            help="repository for new crypto submodule."
+        )
+        parser.add_argument(
+            "-s", "--skip-file", type=str,
+            help="path to file containing symbols and types to skip"
+        )
+        parser.add_argument(
+            "-b", "--brief", action="store_true",
+            help="output only the list of issues to stdout, instead of a full report",
+        )
+        abi_args = parser.parse_args()
+        if os.path.isfile(abi_args.report_dir):
+            print("Error: {} is not a directory".format(abi_args.report_dir))
+            parser.exit()
+        old_version = SimpleNamespace(
+            version="old",
+            repository=abi_args.old_repo,
+            revision=abi_args.old_rev,
+            crypto_repository=abi_args.old_crypto_repo,
+            crypto_revision=abi_args.old_crypto_rev,
+            abi_dumps={},
+            modules={}
+        )
+        new_version = SimpleNamespace(
+            version="new",
+            repository=abi_args.new_repo,
+            revision=abi_args.new_rev,
+            crypto_repository=abi_args.new_crypto_repo,
+            crypto_revision=abi_args.new_crypto_rev,
+            abi_dumps={},
+            modules={}
+        )
+        configuration = SimpleNamespace(
+            verbose=abi_args.verbose,
+            report_dir=abi_args.report_dir,
+            keep_all_reports=abi_args.keep_all_reports,
+            brief=abi_args.brief,
+            skip_file=abi_args.skip_file
+        )
+        abi_check = AbiChecker(old_version, new_version, configuration)
+        return_code = abi_check.check_for_abi_changes()
+        sys.exit(return_code)
+    except Exception: # pylint: disable=broad-except
+        # Print the backtrace and exit explicitly so as to exit with
+        # status 2, not 1.
+        traceback.print_exc()
+        sys.exit(2)
+
+
+if __name__ == "__main__":
+    run_main()
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 2ac9901..8e24064 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -591,6 +591,17 @@
 #### Build and test many configurations and targets
 ################################################################
 
+component_test_default_out_of_box () {
+    msg "build: make, default config (out-of-box)" # ~1min
+    make
+
+    msg "test: main suites make, default config (out-of-box)" # ~10s
+    make test
+
+    msg "selftest: make, default config (out-of-box)" # ~10s
+    programs/test/selftest
+}
+
 component_build_yotta () {
     # Note - use of yotta is deprecated, and yotta also requires armcc to be on the
     # path, and uses whatever version of armcc it finds there.
@@ -846,10 +857,16 @@
     # Build again with -O1, to compile in the i386 specific inline assembly
     msg "build: i386, make, gcc -O1 (ASan build)" # ~ 30s
     scripts/config.pl full
+    scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE
+    scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
+    scripts/config.pl unset MBEDTLS_MEMORY_DEBUG
     make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address'
 
     msg "test: i386, make, gcc -O1 (ASan build)"
     make test
+
+    msg "test ssl-opt.sh, i386, make, gcc-O1"
+    if_build_succeeded tests/ssl-opt.sh
 }
 support_test_m32_o1 () {
     support_test_m32_o0 "$@"
@@ -1028,10 +1045,8 @@
     msg "test: main suites valgrind (Release)"
     make memcheck
 
-    # Optional part(s)
-    # Currently broken, programs don't seem to receive signals
-    # under valgrind on OS X
-
+    # Optional parts (slow; currently broken on OS X because programs don't
+    # seem to receive signals under valgrind on OS X).
     if [ "$MEMORY" -gt 0 ]; then
         msg "test: ssl-opt.sh --memcheck (Release)"
         if_build_succeeded tests/ssl-opt.sh --memcheck
diff --git a/tests/scripts/list-identifiers.sh b/tests/scripts/list-identifiers.sh
index 130d9d6..cc9c54f 100755
--- a/tests/scripts/list-identifiers.sh
+++ b/tests/scripts/list-identifiers.sh
@@ -1,4 +1,10 @@
-#!/bin/sh
+#!/bin/bash
+#
+# Create a file named identifiers containing identifiers from internal header
+# files or all header files, based on --internal flag.
+# Outputs the line count of the file to stdout.
+#
+# Usage: list-identifiers.sh [ -i | --internal ]
 
 set -eu
 
@@ -7,7 +13,29 @@
     exit 1
 fi
 
-HEADERS=$( ls include/mbedtls/*.h | egrep -v 'compat-1\.3\.h|bn_mul' )
+INTERNAL=""
+
+until [ -z "${1-}" ]
+do
+  case "$1" in
+    -i|--internal)
+      INTERNAL="1"
+      ;;
+    *)
+      # print error
+      echo "Unknown argument: '$1'"
+      exit 1
+      ;;
+  esac
+  shift
+done
+
+if [ $INTERNAL ]
+then
+    HEADERS=$( ls include/mbedtls/*_internal.h | egrep -v 'compat-1\.3\.h|bn_mul' )
+else
+    HEADERS=$( ls include/mbedtls/*.h | egrep -v 'compat-1\.3\.h|bn_mul' )
+fi
 
 rm -f identifiers
 
diff --git a/visualc/VS2010/mbedTLS.sln b/visualc/VS2010/mbedTLS.sln
index 686091c..89178cc 100644
--- a/visualc/VS2010/mbedTLS.sln
+++ b/visualc/VS2010/mbedTLS.sln
@@ -183,11 +183,6 @@
 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

 	EndProjectSection

 EndProject

-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssl_cert_test", "ssl_cert_test.vcxproj", "{3FE0C0E1-D9BA-6A26-380C-F293E543B914}"

-	ProjectSection(ProjectDependencies) = postProject

-		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

-	EndProjectSection

-EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benchmark", "benchmark.vcxproj", "{90EFD9A4-C6B0-3EE8-1F06-0A0E0D55AEDA}"

 	ProjectSection(ProjectDependencies) = postProject

 		{46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}

@@ -542,14 +537,6 @@
 		{5FCC71F6-FF33-EBCF-FBA2-8FC783D5318E}.Release|Win32.Build.0 = Release|Win32

 		{5FCC71F6-FF33-EBCF-FBA2-8FC783D5318E}.Release|x64.ActiveCfg = Release|x64

 		{5FCC71F6-FF33-EBCF-FBA2-8FC783D5318E}.Release|x64.Build.0 = Release|x64

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Debug|Win32.ActiveCfg = Debug|Win32

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Debug|Win32.Build.0 = Debug|Win32

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Debug|x64.ActiveCfg = Debug|x64

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Debug|x64.Build.0 = Debug|x64

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Release|Win32.ActiveCfg = Release|Win32

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Release|Win32.Build.0 = Release|Win32

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Release|x64.ActiveCfg = Release|x64

-		{3FE0C0E1-D9BA-6A26-380C-F293E543B914}.Release|x64.Build.0 = Release|x64

 		{90EFD9A4-C6B0-3EE8-1F06-0A0E0D55AEDA}.Debug|Win32.ActiveCfg = Debug|Win32

 		{90EFD9A4-C6B0-3EE8-1F06-0A0E0D55AEDA}.Debug|Win32.Build.0 = Debug|Win32

 		{90EFD9A4-C6B0-3EE8-1F06-0A0E0D55AEDA}.Debug|x64.ActiveCfg = Debug|x64

diff --git a/visualc/VS2010/ssl_cert_test.vcxproj b/visualc/VS2010/ssl_cert_test.vcxproj
deleted file mode 100644
index b8f014e..0000000
--- a/visualc/VS2010/ssl_cert_test.vcxproj
+++ /dev/null
@@ -1,174 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <ItemGroup Label="ProjectConfigurations">

-    <ProjectConfiguration Include="Debug|Win32">

-      <Configuration>Debug</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Debug|x64">

-      <Configuration>Debug</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|Win32">

-      <Configuration>Release</Configuration>

-      <Platform>Win32</Platform>

-    </ProjectConfiguration>

-    <ProjectConfiguration Include="Release|x64">

-      <Configuration>Release</Configuration>

-      <Platform>x64</Platform>

-    </ProjectConfiguration>

-  </ItemGroup>

-  <ItemGroup>

-    <ClCompile Include="..\..\programs\test\ssl_cert_test.c" />

-  </ItemGroup>

-  <ItemGroup>

-    <ProjectReference Include="mbedTLS.vcxproj">
-      <Project>{46cf2d25-6a36-4189-b59c-e4815388e554}</Project>

-      <LinkLibraryDependencies>true</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemGroup>

-  <PropertyGroup Label="Globals">

-    <ProjectGuid>{3FE0C0E1-D9BA-6A26-380C-F293E543B914}</ProjectGuid>

-    <Keyword>Win32Proj</Keyword>

-    <RootNamespace>ssl_cert_test</RootNamespace>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>true</UseDebugLibraries>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">

-    <ConfigurationType>Application</ConfigurationType>

-    <UseDebugLibraries>false</UseDebugLibraries>

-    <WholeProgramOptimization>true</WholeProgramOptimization>

-    <CharacterSet>Unicode</CharacterSet>

-    <PlatformToolset>Windows7.1SDK</PlatformToolset>

-  </PropertyGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

-  <ImportGroup Label="ExtensionSettings">

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">

-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

-  </ImportGroup>

-  <PropertyGroup Label="UserMacros" />

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <IntDir>$(Configuration)\$(TargetName)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <ClCompile>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <WarningLevel>Level3</WarningLevel>

-      <Optimization>Disabled</Optimization>

-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <ShowProgress>NotSet</ShowProgress>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>Debug</AdditionalLibraryDirectories>

-    </Link>

-    <ProjectReference>

-      <LinkLibraryDependencies>false</LinkLibraryDependencies>

-    </ProjectReference>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>

-  </ItemDefinitionGroup>

-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <ClCompile>

-      <WarningLevel>Level3</WarningLevel>

-      <PrecompiledHeader>

-      </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

-      <FunctionLevelLinking>true</FunctionLevelLinking>

-      <IntrinsicFunctions>true</IntrinsicFunctions>

-      <PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

-      <AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>

-    </ClCompile>

-    <Link>

-      <SubSystem>Console</SubSystem>

-      <GenerateDebugInformation>true</GenerateDebugInformation>

-      <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <OptimizeReferences>true</OptimizeReferences>

-      <AdditionalLibraryDirectories>Release</AdditionalLibraryDirectories>

-      <AdditionalDependencies>%(AdditionalDependencies);</AdditionalDependencies>

-    </Link>

-  </ItemDefinitionGroup>

-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

-  <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>

-</Project>