  #include "sgx_error.h"
  #include "sgx_urts.h"
  #include "sgx_uswitchless.h"
-@@ -145,3 +146,20 @@
+@@ -102,6 +103,47 @@
+     return ret;
+ }
+ 
++extern "C" sgx_status_t __sgx_create_enclave_from_buffer_ex(
++        uint8_t *buffer,
++        size_t buffer_size,
++        const int debug,
++        sgx_launch_token_t *launch_token,
++        int *launch_token_updated,
++        sgx_enclave_id_t *enclave_id,
++        sgx_misc_attribute_t *misc_attr,
++        const uint32_t ex_features,
++        void* ex_features_p[32])
++{
++    sgx_status_t ret = SGX_SUCCESS;
++
++    // Only true or false is valid
++    if (TRUE != debug &&  FALSE != debug)
++    {
++        return SGX_ERROR_INVALID_PARAMETER;
++    }
++
++    if (!_check_ex_params_(ex_features, ex_features_p))
++    {
++        return SGX_ERROR_INVALID_PARAMETER;
++    }
++
++    se_file_t file = {NULL, 0, false};
++    ret = _create_enclave_from_buffer_ex(
++        buffer, buffer_size, !!debug, file, NULL, launch_token,
++        launch_token_updated, enclave_id, misc_attr, ex_features,
++        ex_features_p);
++    if (SGX_SUCCESS != ret && misc_attr)
++    {
++        sgx_misc_attribute_t plat_cap;
++        memset(&plat_cap, 0, sizeof(plat_cap));
++        get_enclave_creator()->get_plat_cap(&plat_cap);
++        memcpy_s(misc_attr, sizeof(sgx_misc_attribute_t), &plat_cap,
++                 sizeof(sgx_misc_attribute_t));
++    }
++
++    return ret;
++}
++
+ extern "C" sgx_status_t sgx_create_enclave(const char *file_name, 
+                                            const int debug, 
+                                            sgx_launch_token_t *launch_token, 
+@@ -113,6 +155,21 @@
+ }
+ 
+ 
++extern "C" sgx_status_t sgx_create_enclave_from_buffer(
++        uint8_t *buffer,
++        size_t buffer_size,
++        const int debug,
++        sgx_launch_token_t *launch_token,
++        int *launch_token_updated,
++        sgx_enclave_id_t *enclave_id,
++        sgx_misc_attribute_t *misc_attr)
++{
++    return __sgx_create_enclave_from_buffer_ex(
++        buffer, buffer_size, debug, launch_token, launch_token_updated,
++        enclave_id, misc_attr, 0, NULL);
++}
++
++
+ extern "C"  sgx_status_t sgx_create_enclave_ex(const char *file_name,
+                                                const int debug,
+                                                sgx_launch_token_t *launch_token,
+@@ -145,3 +202,20 @@
      return __sgx_create_enclave_ex(file_name, debug, launch_token,
          launch_token_updated, enclave_id, misc_attr, ex_features, ex_features_p);
  }

diff -Nur common/inc/sgx_urts.h common/inc/sgx_urts.h
--- common/inc/sgx_urts.h
+++ common/inc/sgx_urts.h
@@ -96,6 +96,8 @@
 
 sgx_status_t SGXAPI sgx_destroy_enclave(const sgx_enclave_id_t enclave_id);
 

    - Affected files:
      + `trts_internal.h`
      + `trts_nsp.cpp`
* [PR308](https://github.com/intel/linux-sgx/pull/308): Change use of undefined
  MIN macro to the intended meaning.
    - Affected files:
      + `common/inc/internal/mini_snprintf.h`
* [PR316](https://github.com/intel/linux-sgx/pull/316): Allow enclaves to be
  created from buffers.
    - Affected files:
      + `common/inc/sgx_urts.h`
      + `psw/urts/enclave.cpp`
      + `psw/urts/urts_com.h`
      + `psw/urts/linux/urts.cpp`
    - The version in this patch differs slightly from the PR.

### Non-upstreamed changes
* `sdk/trts/init_enclave.cpp`: Remove a memset_s of the enclave heap since
