      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

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

 #include "sgx_error.h"
 #include "sgx_urts.h"
 #include "sgx_uswitchless.h"
@@ -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);
 }
