diff --git a/rustlib/proc_macro/src/lib.rs b/rustlib/proc_macro/src/lib.rs
index 0a70c488..138090da 100644
--- a/rustlib/proc_macro/src/lib.rs
+++ b/rustlib/proc_macro/src/lib.rs
@@ -27,7 +27,6 @@
#![feature(maybe_uninit_write_slice)]
#![feature(negative_impls)]
#![feature(new_uninit)]
-#![feature(restricted_std)]
#![feature(rustc_attrs)]
#![feature(min_specialization)]
#![feature(strict_provenance)]
diff --git a/rustlib/x86_64-unknown-linux-sgx.json b/rustlib/x86_64-unknown-linux-sgx.json
index ece4b8ee..8cbaa964 100644
--- a/rustlib/x86_64-unknown-linux-sgx.json
+++ b/rustlib/x86_64-unknown-linux-sgx.json
@@ -37,7 +37,7 @@
"memory",
"thread"
],
- "target-c-int-width": "32",
+ "target-c-int-width": 32,
"target-endian": "little",
"target-family": "unix",
"target-pointer-width": "64",
diff --git a/samplecode/multi-enclave-template/Makefile b/samplecode/multi-enclave-template/Makefile
new file mode 100644
index 00000000..c030cae1
--- /dev/null
+++ b/samplecode/multi-enclave-template/Makefile
@@ -0,0 +1,211 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/intel/sgxsdk
+SGX_MODE ?= HW
+SGX_ARCH ?= x64
+
+TOP_DIR := ../..
+include $(TOP_DIR)/buildenv.mk
+
+ifeq ($(shell getconf LONG_BIT), 32)
+ SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+ SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+ SGX_COMMON_CFLAGS := -m32
+ SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+ SGX_BIN_PATH := $(SGX_SDK)/bin/x86
+else
+ SGX_COMMON_CFLAGS := -m64
+ SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+ SGX_BIN_PATH := $(SGX_SDK)/bin/x64
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ SGX_COMMON_CFLAGS += -O0 -g
+ Rust_Build_Flags :=
+ Rust_Build_Out := debug
+else
+ SGX_COMMON_CFLAGS += -O2
+ Rust_Build_Flags := --release
+ Rust_Build_Out := release
+endif
+
+SGX_EDGER8R := $(SGX_BIN_PATH)/sgx_edger8r
+ifneq ($(SGX_MODE), HYPER)
+ SGX_ENCLAVE_SIGNER := $(SGX_BIN_PATH)/sgx_sign
+else
+ SGX_ENCLAVE_SIGNER := $(SGX_BIN_PATH)/sgx_sign_hyper
+ SGX_EDGER8R_MODE := --sgx-mode $(SGX_MODE)
+endif
+
+######## CUSTOM Settings ########
+
+CUSTOM_LIBRARY_PATH := ./lib
+CUSTOM_BIN_PATH := ./bin
+CUSTOM_SYSROOT_PATH := ./sysroot
+CUSTOM_EDL_PATH := $(ROOT_DIR)/sgx_edl/edl
+CUSTOM_COMMON_PATH := $(ROOT_DIR)/common
+
+######## EDL Settings ########
+
+ENCLAVES := enclave0 enclave1
+Enclave_EDL_Files := $(foreach enclave,$(ENCLAVES),$(enclave)/$(enclave)_t.c $(enclave)/$(enclave)_t.h app/$(enclave)_u.c app/$(enclave)_u.h)
+
+######## APP Settings ########
+
+App_Rust_Flags := $(Rust_Build_Flags)
+App_Include_Paths := -I ./app -I$(SGX_SDK)/include -I$(CUSTOM_COMMON_PATH)/inc -I$(CUSTOM_EDL_PATH)
+App_C_Flags := $(CFLAGS) $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+
+App_Rust_Path := ./app/target/$(Rust_Build_Out)
+App_Enclave_u_Object := $(CUSTOM_LIBRARY_PATH)/libenclave_u.a
+App_Name := $(CUSTOM_BIN_PATH)/app
+
+######## Enclave Settings ########
+
+# BUILD_STD=no use no_std
+# BUILD_STD=cargo use cargo-std-aware
+# BUILD_STD=xargo use xargo
+BUILD_STD ?= no
+
+Rust_Build_Target := x86_64-unknown-linux-sgx
+Rust_Target_Path := $(ROOT_DIR)/rustlib
+
+ifeq ($(BUILD_STD), cargo)
+ Rust_Build_Std := $(Rust_Build_Flags) -Zbuild-std=core,alloc
+ Rust_Std_Features :=
+ Rust_Target_Flags := --target $(Rust_Target_Path)/$(Rust_Build_Target).json
+ Rust_Sysroot_Path := $(CURDIR)/sysroot
+ Rust_Sysroot_Flags := RUSTFLAGS="--sysroot $(Rust_Sysroot_Path)"
+endif
+
+RustEnclave_Build_Flags := $(Rust_Build_Flags)
+RustEnclave_Include_Paths := -I$(CUSTOM_COMMON_PATH)/inc -I$(CUSTOM_COMMON_PATH)/inc/tlibc -I$(CUSTOM_EDL_PATH)
+
+RustEnclave_Link_Libs := -L$(CUSTOM_LIBRARY_PATH) -lenclave
+RustEnclave_C_Flags := $(CFLAGS) $(ENCLAVE_CFLAGS) $(SGX_COMMON_CFLAGS) $(RustEnclave_Include_Paths)
+RustEnclave_Link_Flags := -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles \
+ -Wl,--start-group $(RustEnclave_Link_Libs) -Wl,--end-group \
+ $(ENCLAVE_LDFLAGS)
+
+ifeq ($(BUILD_STD), cargo)
+ RustEnclave_Out_Path := ./enclave/target/$(Rust_Build_Target)/$(Rust_Build_Out)
+else ifeq ($(BUILD_STD), xargo)
+ RustEnclave_Out_Path := ./enclave/target/$(Rust_Build_Target)/$(Rust_Build_Out)
+else
+ RustEnclave_Out_Path := ./enclave/target/$(Rust_Build_Out)
+endif
+
+RustEnclave_Name := $(foreach enclave,$(ENCLAVES),$(CUSTOM_BIN_PATH)/$(enclave).so)
+RustEnclave_Signed_Name := $(foreach enclave,$(ENCLAVES),$(CUSTOM_BIN_PATH)/$(enclave).signed.so)
+
+.PHONY: all
+all: $(Enclave_EDL_Files) $(App_Name) $(RustEnclave_Signed_Name)
+
+######## EDL Objects ########
+
+$(Enclave_EDL_Files): $(SGX_EDGER8R) $(foreach enclave,$(ENCLAVES),$(enclave)/$(enclave).edl)
+ $(foreach enclave,$(ENCLAVES),\
+ $(SGX_EDGER8R) $(SGX_EDGER8R_MODE) --trusted $(enclave)/$(enclave).edl --search-path $(CUSTOM_COMMON_PATH)/inc --search-path $(CUSTOM_EDL_PATH) --trusted-dir $(enclave);\
+ $(SGX_EDGER8R) $(SGX_EDGER8R_MODE) --untrusted $(enclave)/$(enclave).edl --search-path $(CUSTOM_COMMON_PATH)/inc --search-path $(CUSTOM_EDL_PATH) --untrusted-dir app;\
+ )
+ @echo "GEN => $(Enclave_EDL_Files)"
+
+######## App Objects ########
+
+app/%_u.o: app/%_u.c $(Enclave_EDL_Files)
+ @$(CC) $(App_C_Flags) -c $< -o $@
+
+$(App_Enclave_u_Object): $(foreach enclave,$(ENCLAVES),app/$(enclave)_u.o)
+ @mkdir -p $(CUSTOM_LIBRARY_PATH)
+ @$(AR) rcsD $@ $^
+
+$(App_Name): $(App_Enclave_u_Object) app
+ @mkdir -p $(CUSTOM_BIN_PATH)
+ @cp $(App_Rust_Path)/app $(CUSTOM_BIN_PATH)
+ @echo "LINK => $@"
+
+######## Enclave Objects ########
+
+%_t.o: %_t.c $(Enclave_EDL_Files)
+ @$(CC) $(RustEnclave_C_Flags) -c $< -o $@
+
+$(RustEnclave_Name): $(foreach enclave,$(ENCLAVES),$(enclave)/$(enclave)_t.o) enclave
+ @mkdir -p $(CUSTOM_LIBRARY_PATH)
+ @mkdir -p $(CUSTOM_BIN_PATH)
+ @$(foreach enclave,$(ENCLAVES),\
+ cp $(RustEnclave_Out_Path)/lib$(enclave).a $(CUSTOM_LIBRARY_PATH)/lib$(enclave).a;\
+ $(CXX) $(enclave)/$(enclave)_t.o -o $@ $(RustEnclave_Link_Flags) -Wl,--version-script=$(enclave)/$(enclave).lds;\
+ )
+ @echo "LINK => $@"
+
+$(RustEnclave_Signed_Name): $(RustEnclave_Name) $(foreach enclave,$(ENCLAVES),$(enclave)/config.xml)
+ @$(foreach enclave,$(ENCLAVES),\
+ $(SGX_ENCLAVE_SIGNER) sign -key $(enclave)/private.pem -enclave $(CUSTOM_BIN_PATH)/$(enclave).so -out $@ -config $(enclave)/config.xml;\
+ )
+ @echo "SIGN => $@"
+
+######## Build App ########
+
+.PHONY: app
+app:
+ @cd app && SGX_SDK=$(SGX_SDK) cargo build $(App_Rust_Flags)
+
+######## Build Enclave ########
+
+.PHONY: enclave
+enclave:
+ifeq ($(BUILD_STD), cargo)
+ @cd $(Rust_Target_Path)/std && cargo build $(Rust_Build_Std) $(Rust_Target_Flags) $(Rust_Std_Features)
+
+ @rm -rf $(Rust_Sysroot_Path)
+ @mkdir -p $(Rust_Sysroot_Path)/lib/rustlib/$(Rust_Build_Target)/lib
+ @cp -r $(Rust_Target_Path)/std/target/$(Rust_Build_Target)/$(Rust_Build_Out)/deps/* $(Rust_Sysroot_Path)/lib/rustlib/$(Rust_Build_Target)/lib
+
+ @$(foreach enclave,$(ENCLAVES),\
+ cd $(enclave) && $(Rust_Sysroot_Flags) cargo build $(Rust_Target_Flags) $(RustEnclave_Build_Flags) && cd ..;\
+ )
+else ifeq ($(BUILD_STD), xargo)
+ @$(foreach enclave,$(ENCLAVES),\
+ cd $(enclave) && RUST_TARGET_PATH=$(Rust_Target_Path) xargo build --target $(Rust_Build_Target) $(RustEnclave_Build_Flags) && cd ..;\
+ )
+else
+ @$(foreach enclave,$(ENCLAVES),\
+ cd $(enclave) && cargo build $(RustEnclave_Build_Flags) && cd ..;\
+ )
+endif
+
+######## Run Enclave ########
+
+.PHONY: run
+run: $(App_Name) $(RustEnclave_Signed_Name)
+ @echo -e '\n===== Run Enclave =====\n'
+ @cd bin && ./app
+
+.PHONY: clean
+clean:
+ @rm -f $(App_Name) $(RustEnclave_Name) $(RustEnclave_Signed_Name) enclave/*_t.* app/*_u.*
+ @cd enclave && cargo clean
+ @cd app && cargo clean
+ @cd $(Rust_Target_Path)/std && cargo clean
+ @rm -rf $(CUSTOM_BIN_PATH) $(CUSTOM_LIBRARY_PATH) $(CUSTOM_SYSROOT_PATH)
diff --git a/samplecode/multi-enclave-template/app/Cargo.toml b/samplecode/multi-enclave-template/app/Cargo.toml
new file mode 100644
index 00000000..b289769a
--- /dev/null
+++ b/samplecode/multi-enclave-template/app/Cargo.toml
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+[package]
+name = "app"
+version = "1.0.0"
+authors = ["The Teaclave Authors"]
+edition = "2021"
+
+[dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_urts = { path = "../../../sgx_urts" }
diff --git a/samplecode/multi-enclave-template/app/build.rs b/samplecode/multi-enclave-template/app/build.rs
new file mode 100644
index 00000000..935390b0
--- /dev/null
+++ b/samplecode/multi-enclave-template/app/build.rs
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+use std::env;
+
+fn main() {
+ println!("cargo:rerun-if-env-changed=SGX_MODE");
+ println!("cargo:rerun-if-changed=build.rs");
+
+ let sdk_dir = env::var("SGX_SDK").unwrap_or_else(|_| "/opt/intel/sgxsdk".to_string());
+ let mode = env::var("SGX_MODE").unwrap_or_else(|_| "HW".to_string());
+
+ println!("cargo:rustc-link-search=native=../lib");
+ println!("cargo:rustc-link-lib=static=enclave_u");
+
+ println!("cargo:rustc-link-search=native={}/lib64", sdk_dir);
+ match mode.as_ref() {
+ "SIM" | "SW" => println!("cargo:rustc-link-lib=dylib=sgx_urts_sim"),
+ "HYPER" => println!("cargo:rustc-link-lib=dylib=sgx_urts_hyper"),
+ "HW" => println!("cargo:rustc-link-lib=dylib=sgx_urts"),
+ _ => println!("cargo:rustc-link-lib=dylib=sgx_urts"),
+ }
+}
diff --git a/samplecode/multi-enclave-template/app/src/main.rs b/samplecode/multi-enclave-template/app/src/main.rs
new file mode 100644
index 00000000..3b3e502e
--- /dev/null
+++ b/samplecode/multi-enclave-template/app/src/main.rs
@@ -0,0 +1,87 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+extern crate sgx_types;
+extern crate sgx_urts;
+
+use sgx_types::error::SgxStatus;
+use sgx_types::types::*;
+use sgx_urts::enclave::SgxEnclave;
+
+static ENCLAVE0_FILE: &str = "enclave0.signed.so";
+static ENCLAVE1_FILE: &str = "enclave1.signed.so";
+
+extern "C" {
+ fn say_something(
+ eid: EnclaveId,
+ retval: *mut SgxStatus,
+ some_string: *const u8,
+ len: usize,
+ ) -> SgxStatus;
+}
+
+fn main() {
+ let enclave0 = match SgxEnclave::create(ENCLAVE0_FILE, true) {
+ Ok(enclave) => {
+ println!("[+] Init Enclave Successful {}!", enclave.eid());
+ enclave
+ }
+ Err(err) => {
+ println!("[-] Init Enclave Failed {}!", err.as_str());
+ return;
+ }
+ };
+ let enclave1 = match SgxEnclave::create(ENCLAVE1_FILE, true) {
+ Ok(enclave) => {
+ println!("[+] Init Enclave Successful {}!", enclave.eid());
+ enclave
+ }
+ Err(err) => {
+ println!("[-] Init Enclave Failed {}!", err.as_str());
+ return;
+ }
+ };
+
+ let input_string = String::from("This is a normal world string passed into Enclave!\n");
+ let mut retval = SgxStatus::Success;
+
+ let result = unsafe {
+ say_something(
+ enclave0.eid(),
+ &mut retval,
+ input_string.as_ptr() as *const u8,
+ input_string.len(),
+ )
+ };
+ match result {
+ SgxStatus::Success => println!("[+] ECall Success..."),
+ _ => println!("[-] ECall Enclave Failed {}!", result.as_str()),
+ }
+
+ let result = unsafe {
+ say_something(
+ enclave1.eid(),
+ &mut retval,
+ input_string.as_ptr() as *const u8,
+ input_string.len(),
+ )
+ };
+ match result {
+ SgxStatus::Success => println!("[+] ECall Success..."),
+ _ => println!("[-] ECall Enclave Failed {}!", result.as_str()),
+ }
+}
diff --git a/samplecode/multi-enclave-template/enclave0/Cargo.toml b/samplecode/multi-enclave-template/enclave0/Cargo.toml
new file mode 100644
index 00000000..1511e3d1
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave0/Cargo.toml
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+[package]
+name = "enclave0"
+version = "1.0.0"
+authors = ["The Teaclave Authors"]
+edition = "2021"
+
+[lib]
+name = "enclave0"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+
+[target.'cfg(not(target_vendor = "teaclave"))'.dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tstd = { path = "../../../sgx_tstd" }
diff --git a/samplecode/multi-enclave-template/enclave0/Xargo.toml b/samplecode/multi-enclave-template/enclave0/Xargo.toml
new file mode 100644
index 00000000..d1d0e6d1
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave0/Xargo.toml
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+[dependencies]
+alloc = {}
+
+[dependencies.std]
+path = "../../../rustlib/std"
+stage = 1
diff --git a/samplecode/multi-enclave-template/enclave0/config.xml b/samplecode/multi-enclave-template/enclave0/config.xml
new file mode 100644
index 00000000..0cf1f46d
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave0/config.xml
@@ -0,0 +1,31 @@
+
+
+
+ 0
+ 0
+ 0x40000
+ 0x100000
+ 1
+ 0
+ 0
+ 0
+ 0xFFFFFFFF
+
diff --git a/samplecode/multi-enclave-template/enclave0/enclave0.edl b/samplecode/multi-enclave-template/enclave0/enclave0.edl
new file mode 100644
index 00000000..b7ff8f42
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave0/enclave0.edl
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+enclave {
+ from "sgx_stdio.edl" import *;
+ from "sgx_tstd.edl" import *;
+
+ trusted {
+ public sgx_status_t say_something([in, size=len] const uint8_t* some_string, size_t len);
+ };
+};
diff --git a/samplecode/multi-enclave-template/enclave0/enclave0.lds b/samplecode/multi-enclave-template/enclave0/enclave0.lds
new file mode 100644
index 00000000..bdb7a4b5
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave0/enclave0.lds
@@ -0,0 +1,12 @@
+enclave.so
+{
+ global:
+ g_global_data_hyper;
+ g_global_data_sim;
+ g_global_data;
+ enclave_entry;
+ g_peak_heap_used;
+ g_peak_rsrv_mem_committed;
+ local:
+ *;
+};
diff --git a/samplecode/multi-enclave-template/enclave0/private.pem b/samplecode/multi-enclave-template/enclave0/private.pem
new file mode 100644
index 00000000..529d07be
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave0/private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/multi-enclave-template/enclave0/src/lib.rs b/samplecode/multi-enclave-template/enclave0/src/lib.rs
new file mode 100644
index 00000000..2ab1bdf2
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave0/src/lib.rs
@@ -0,0 +1,60 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+#![cfg_attr(not(target_vendor = "teaclave"), no_std)]
+#![cfg_attr(target_vendor = "teaclave", feature(rustc_private))]
+
+#[cfg(not(target_vendor = "teaclave"))]
+#[macro_use]
+extern crate sgx_tstd as std;
+extern crate sgx_types;
+
+use sgx_types::error::SgxStatus;
+use std::io::{self, Write};
+use std::slice;
+use std::string::String;
+use std::vec::Vec;
+
+/// # Safety
+#[no_mangle]
+pub unsafe extern "C" fn say_something(some_string: *const u8, some_len: usize) -> SgxStatus {
+ let str_slice = slice::from_raw_parts(some_string, some_len);
+ let _ = io::stdout().write(str_slice);
+
+ // A sample &'static string
+ let rust_raw_string = "This is a in-Enclave ";
+ // An array
+ let word: [u8; 4] = [82, 117, 115, 116];
+ // An vector
+ let word_vec: Vec = vec![32, 115, 116, 114, 105, 110, 103, 33];
+
+ // Construct a string from &'static string
+ let mut hello_string = String::from(rust_raw_string);
+
+ // Iterate on word array
+ for c in word.iter() {
+ hello_string.push(*c as char);
+ }
+
+ // Rust style convertion
+ hello_string += String::from_utf8(word_vec).expect("Invalid UTF-8").as_str();
+
+ // Ocall to normal world for output
+ println!("{}", &hello_string);
+
+ SgxStatus::Success
+}
diff --git a/samplecode/multi-enclave-template/enclave1/Cargo.toml b/samplecode/multi-enclave-template/enclave1/Cargo.toml
new file mode 100644
index 00000000..cf30f4b6
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave1/Cargo.toml
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+[package]
+name = "enclave1"
+version = "1.0.0"
+authors = ["The Teaclave Authors"]
+edition = "2021"
+
+[lib]
+name = "enclave1"
+crate-type = ["staticlib"]
+
+[features]
+default = []
+
+[target.'cfg(not(target_vendor = "teaclave"))'.dependencies]
+sgx_types = { path = "../../../sgx_types" }
+sgx_tstd = { path = "../../../sgx_tstd" }
diff --git a/samplecode/multi-enclave-template/enclave1/Xargo.toml b/samplecode/multi-enclave-template/enclave1/Xargo.toml
new file mode 100644
index 00000000..d1d0e6d1
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave1/Xargo.toml
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+[dependencies]
+alloc = {}
+
+[dependencies.std]
+path = "../../../rustlib/std"
+stage = 1
diff --git a/samplecode/multi-enclave-template/enclave1/config.xml b/samplecode/multi-enclave-template/enclave1/config.xml
new file mode 100644
index 00000000..0cf1f46d
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave1/config.xml
@@ -0,0 +1,31 @@
+
+
+
+ 0
+ 0
+ 0x40000
+ 0x100000
+ 1
+ 0
+ 0
+ 0
+ 0xFFFFFFFF
+
diff --git a/samplecode/multi-enclave-template/enclave1/enclave1.edl b/samplecode/multi-enclave-template/enclave1/enclave1.edl
new file mode 100644
index 00000000..b7ff8f42
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave1/enclave1.edl
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+enclave {
+ from "sgx_stdio.edl" import *;
+ from "sgx_tstd.edl" import *;
+
+ trusted {
+ public sgx_status_t say_something([in, size=len] const uint8_t* some_string, size_t len);
+ };
+};
diff --git a/samplecode/multi-enclave-template/enclave1/enclave1.lds b/samplecode/multi-enclave-template/enclave1/enclave1.lds
new file mode 100644
index 00000000..bdb7a4b5
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave1/enclave1.lds
@@ -0,0 +1,12 @@
+enclave.so
+{
+ global:
+ g_global_data_hyper;
+ g_global_data_sim;
+ g_global_data;
+ enclave_entry;
+ g_peak_heap_used;
+ g_peak_rsrv_mem_committed;
+ local:
+ *;
+};
diff --git a/samplecode/multi-enclave-template/enclave1/private.pem b/samplecode/multi-enclave-template/enclave1/private.pem
new file mode 100644
index 00000000..529d07be
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave1/private.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/samplecode/multi-enclave-template/enclave1/src/lib.rs b/samplecode/multi-enclave-template/enclave1/src/lib.rs
new file mode 100644
index 00000000..2ab1bdf2
--- /dev/null
+++ b/samplecode/multi-enclave-template/enclave1/src/lib.rs
@@ -0,0 +1,60 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+
+#![cfg_attr(not(target_vendor = "teaclave"), no_std)]
+#![cfg_attr(target_vendor = "teaclave", feature(rustc_private))]
+
+#[cfg(not(target_vendor = "teaclave"))]
+#[macro_use]
+extern crate sgx_tstd as std;
+extern crate sgx_types;
+
+use sgx_types::error::SgxStatus;
+use std::io::{self, Write};
+use std::slice;
+use std::string::String;
+use std::vec::Vec;
+
+/// # Safety
+#[no_mangle]
+pub unsafe extern "C" fn say_something(some_string: *const u8, some_len: usize) -> SgxStatus {
+ let str_slice = slice::from_raw_parts(some_string, some_len);
+ let _ = io::stdout().write(str_slice);
+
+ // A sample &'static string
+ let rust_raw_string = "This is a in-Enclave ";
+ // An array
+ let word: [u8; 4] = [82, 117, 115, 116];
+ // An vector
+ let word_vec: Vec = vec![32, 115, 116, 114, 105, 110, 103, 33];
+
+ // Construct a string from &'static string
+ let mut hello_string = String::from(rust_raw_string);
+
+ // Iterate on word array
+ for c in word.iter() {
+ hello_string.push(*c as char);
+ }
+
+ // Rust style convertion
+ hello_string += String::from_utf8(word_vec).expect("Invalid UTF-8").as_str();
+
+ // Ocall to normal world for output
+ println!("{}", &hello_string);
+
+ SgxStatus::Success
+}