  #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);
  }

    - Affected files:
      + `trts_internal.h`
      + `trts_nsp.cpp`
* [PR308](https://github.com/intel/linux-sgx/pull/308): Include sl_util.h to
  define the MIN macro before its use.
    - Affected files:
      + `common/inc/internal/mini_snprintf.h`

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

     Node<se_thread_id_t, CTrustThread *>    *m_thread_list;
     Mutex                                   m_thread_mutex; //protect thread_cache list. The mutex is recursive.
                                                             //Thread can operate the list when it get the mutex
diff -Nur psw/urts/urts_com.h psw/urts/urts_com.h
--- psw/urts/urts_com.h
+++ psw/urts/urts_com.h
@@ -422,33 +422,27 @@
     return ret;
 }
 
-
-sgx_status_t _create_enclave_ex(const bool debug, se_file_handle_t pfile, se_file_t& file, le_prd_css_file_t *prd_css_file, 
-	                            sgx_launch_token_t *launch, int *launch_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 _create_enclave_ex_internal(
+        uint8_t *base_addr,
+        uint64_t file_size,
+        const bool debug,
+        se_file_t& file,
+        le_prd_css_file_t *prd_css_file,
+        sgx_launch_token_t *launch,
+        int *launch_updated,
+        sgx_enclave_id_t *enclave_id,
+        sgx_misc_attribute_t *misc_attr,
+        const uint32_t ex_features,
+        void* ex_features_p[32])
 {
     unsigned int ret = SGX_SUCCESS;
     sgx_status_t lt_result = SGX_SUCCESS;
-    uint32_t file_size = 0;
-    map_handle_t* mh = NULL;
     sgx_misc_attribute_t sgx_misc_attr;
     metadata_t *metadata = NULL;
     SGXLaunchToken *lc = NULL;
     memset(&sgx_misc_attr, 0, sizeof(sgx_misc_attribute_t));
 
-    if(NULL == launch || NULL == launch_updated || NULL == enclave_id)
-        return SGX_ERROR_INVALID_PARAMETER;
-#ifndef SE_SIM
-    ret = validate_platform();
-    if(ret != SGX_SUCCESS)
-        return (sgx_status_t)ret;
-#endif
-
-    mh = map_file(pfile, &file_size);
-    if (!mh)
-        return SGX_ERROR_OUT_OF_MEMORY;
-
-    PARSER parser(const_cast<uint8_t *>(mh->base_addr), (uint64_t)(file_size));
+    PARSER parser(base_addr, file_size);
     if(SGX_SUCCESS != (ret = parser.run_parser()))
     {
         goto clean_return;
@@ -517,7 +511,7 @@
 
     //Need to set the whole misc_attr instead of just secs_attr.
     do {
-        ret = __create_enclave(parser, mh->base_addr, metadata, file, debug, lc, prd_css_file, enclave_id, misc_attr, ex_features, ex_features_p);
+        ret = __create_enclave(parser, base_addr, metadata, file, debug, lc, prd_css_file, enclave_id, misc_attr, ex_features, ex_features_p);
         //SGX_ERROR_ENCLAVE_LOST caused by initializing enclave while power transition occurs
     } while(SGX_ERROR_ENCLAVE_LOST == ret);
 
@@ -542,13 +536,70 @@
 
 
 clean_return:
-    if(mh != NULL)
-        unmap_file(mh);
     if(lc != NULL)
         delete lc;
     return (sgx_status_t)ret;
 }
 
+sgx_status_t _create_enclave_ex(const bool debug, se_file_handle_t pfile, se_file_t& file, le_prd_css_file_t *prd_css_file, 
+	                            sgx_launch_token_t *launch, int *launch_updated, sgx_enclave_id_t *enclave_id, 
+                                sgx_misc_attribute_t *misc_attr, const uint32_t ex_features, void* ex_features_p[32])
+{
+    unsigned int ret = SGX_SUCCESS;
+    uint32_t file_size = 0;
+    map_handle_t* mh = NULL;
+
+    if(NULL == launch || NULL == launch_updated || NULL == enclave_id)
+        return SGX_ERROR_INVALID_PARAMETER;
+#ifndef SE_SIM
+    ret = validate_platform();
+    if(ret != SGX_SUCCESS)
+        return (sgx_status_t)ret;
+#endif
+
+    mh = map_file(pfile, &file_size);
+    if (!mh)
+        return SGX_ERROR_OUT_OF_MEMORY;
+
+    ret = _create_enclave_ex_internal(
+            mh->base_addr, (uint64_t)file_size, debug, file, prd_css_file, launch, launch_updated,
+            enclave_id, misc_attr, ex_features, ex_features_p);
+
+    if(mh != NULL)
+        unmap_file(mh);
+    return (sgx_status_t)ret;
+}
+
+sgx_status_t _create_enclave_from_buffer_ex(
+        uint8_t *buffer,
+        size_t buffer_size,
+        const bool debug,
+        se_file_t& file,
+        le_prd_css_file_t *prd_css_file,
+        sgx_launch_token_t *launch,
+        int *launch_updated,
+        sgx_enclave_id_t *enclave_id,
+        sgx_misc_attribute_t *misc_attr,
+        const uint32_t ex_features,
+        void* ex_features_p[32])
+{
+    unsigned int ret = SGX_SUCCESS;
+
+    if(NULL == buffer || NULL == launch || NULL == launch_updated || NULL == enclave_id)
+        return SGX_ERROR_INVALID_PARAMETER;
+#ifndef SE_SIM
+    ret = validate_platform();
+    if(ret != SGX_SUCCESS)
+        return (sgx_status_t)ret;
+#endif
+
+    ret = _create_enclave_ex_internal(
+            buffer, (uint64_t)buffer_size, debug, file, prd_css_file, launch,
+            launch_updated, enclave_id, misc_attr, ex_features, ex_features_p);
+
+    return (sgx_status_t)ret;
+}
+
 sgx_status_t _create_enclave(const bool debug, se_file_handle_t pfile, se_file_t& file, le_prd_css_file_t *prd_css_file, 
                              sgx_launch_token_t *launch, int *launch_updated, sgx_enclave_id_t *enclave_id, sgx_misc_attribute_t *misc_attr) 
 {
diff -Nur sdk/edger8r/linux/Ast.ml sdk/edger8r/linux/Ast.ml
--- sdk/edger8r/linux/Ast.ml
+++ sdk/edger8r/linux/Ast.ml
