Merge pull request #279 from apache/support-new-allocator

compiler: bump up to nightly-2020-10-25 for new AllocRef trait and AllocError
diff --git a/documents/README.md b/documents/README.md
index 9b67397..8a0152c 100644
--- a/documents/README.md
+++ b/documents/README.md
@@ -4,6 +4,9 @@
 
 # Teaclave SGX SDK Documentation
 
+* [`is_x86_feature_detected` in Teaclave SGX SDK](/sgx-sdk-docs/is_x86_feature_detected-in-sgx-sdk)
+* [Developing with Visual Studio Code](/sgx-sdk-docs/developing-with-vscode/)
+
 ## Security
 
 * [Everything about CVE-2020-5499](/sgx-sdk-docs/everything-about-cve-2020-5499/)
diff --git a/documents/developing-with-vscode.md b/documents/developing-with-vscode.md
new file mode 100644
index 0000000..0aa6760
--- /dev/null
+++ b/documents/developing-with-vscode.md
@@ -0,0 +1,101 @@
+---
+permalink: /sgx-sdk-docs/developing-with-vscode
+---
+
+# Developing with Visual Studio Code
+
+## Overview
+
+1. Use Visual Studio Code and the [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) plugin to establish a vscode-ssh session.
+2. Tweak a project with a new `Cargo.toml` workspace and all `Makefile`s. This enables `rls`.
+3. Tweak the build options for compiling in debug mode.
+4. Use [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) plugin for graphic debugging.
+
+## Prerequisites
+
+* Visual Studio Code installed on your machine. OS is flexible.
+* Remote Linux supports Intel SGX, with SSH service started.
+* `rustup`, Intel SGX driver/PSW/SDKs are correctly installed. `hello-rust` code sample works.
+* Remote Linux **could** be the same machine. Just ignore the `vscode-ssh` plugin mentioned in this wiki page and you'll be fine.
+
+## Known bugs
+
+* `sgx-gdb` throws Python exception on `gdb` > 7.12 on some platforms, such as
+  mine. But native sgx-gdb may not throw that error. Don't have a solution for
+  VSCode yet.
+
+## Steps
+
+### Setup the vscode-ssh session.
+
+1. Setup a convenient way for ssh login. I always append my `~/.ssh/id_rsa.pub` to the remote `~/.ssh/authorized_keys`.
+2. Install the [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) plugin.
+3. Establish a vscode-ssh session to the remote Linux.
+
+### Create an rls-friendly Teaclave SGX SDK project.
+
+[hello-rust-vscode-debug](https://github.com/baidu/rust-sgx-sdk/tree/master/samplecode/hello-rust-vscode-debug)
+is an example. Differences between this and `hello-rust` are:
+1. An extra `Cargo.toml` at the root, which contains two Rust crates: `app` and `enclave`. This change would result in changing the path of `target` folders.
+2. Tweak `Makefile` and `enclave/Makefile` and correct the path of `target` folders.
+3. Tweak `Makefile` and `enclave/Makefile` to enable debug compilation. Changes
+   include: (1) remove `--release` in `cargo build`, (2) add `-ggdb` to
+   `SGX_COMMON_FLAGS`.
+
+After these steps, the `hello-rust-vscode-debug` should be an rls-friendly
+project. And open the remote folder of it in the VSCode main screen "Start -
+open folder". Then autocompletion should work!
+
+### Setup Native Debug with sgx-gdb
+
+Now we have a vscode-ssh session to the remote Linux and an opened folder of
+`hello-rust-vscode-debug`. The next step is to configure a correct `launch.json`
+for Native Debug plugin. Now open the debug panel of VS code and click on the
+gear icon to open `launch.json` in the editor.
+
+```
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Debug",
+            "type": "gdb",
+            "request": "launch",
+            "target": "app",
+            "cwd": "${workspaceRoot}/bin",
+            "valuesFormatting": "parseText",
+            "gdbpath": "sgx-gdb",
+            "ssh": {
+                "forwardX11": false,
+                "host": "xxx", // your IP
+                "cwd": "${workspaceRoot}/bin",
+                 // SSH private key on remote machine. Add the pub key to ~/.ssh/authorized_keys
+                 // This ssh configuration is established from host to host, because the current
+                 // vscode session is "within a ssh session established by vscode-ssh".
+                 // I think this might be a bug but can hardly be resolved.
+                "keyfile": "/home/ding/.ssh/id_rsa", // private key
+                "user": "xxx",
+                "bootstrap": "source /opt/sgxsdk/environment",
+                "port": 22
+            }
+        }
+    ]
+}
+```
+
+`name`,`type`,`request`,`valuesFormatting` are default values.
+`cwd` is the working directory we launch the app, so it should be the `bin`
+folder. `target` is the debugee executable so it should be the `app`. `host` is
+the IP address of your Linux machine. Then comes the tricky part: ssh. It means
+that we use an extra ssh session for debugger, within the current vscode-ssh
+session. This means that we are here creating an additional ssh session from
+remote machine to itself. Only in this way could we setup the environment using
+the Intel's script before launching `sgx-gdb`. So we need to add the public key
+`~/.ssh/id_rsa` to `~/.ssh/authorized_keys` and demonstrate the corresponding
+private key as `~/.ssh/id_rsa`.
+
+Having this `launch.json` configured correctly, we could simply set up a
+breakpoint on the first line of `say_something` and start debugging. Enjoy!
diff --git a/documents/is_x86_feature_detected-in-sgx-sdk.md b/documents/is_x86_feature_detected-in-sgx-sdk.md
new file mode 100644
index 0000000..8c71865
--- /dev/null
+++ b/documents/is_x86_feature_detected-in-sgx-sdk.md
@@ -0,0 +1,99 @@
+---
+permalink: /sgx-sdk-docs/is_x86_feature_detected-in-sgx-sdk
+---
+
+# `is_x86_feature_detected` in Teaclave SGX SDK
+
+## Background
+
+Crates often use `is_x86_feature_detected` to select appropriate implementations
+(such as AVX/SSE/SSSE/FMA). It triggers `cpuid` instruction in default `libstd`
+implementation on x86_64. We want to avoid such kind of SGX in-compatible
+instructions and unnecessary AEX events.
+
+## Solution
+
+We found that Intel's SDK initializes its optimized libraries in a way of:
+
+1. initialize a global cpu feature indicator by enclave initialization parameter
+   in [urts](https://github.com/intel/linux-sgx/blob/042849cef8db1f0384e52e8cebcd8820c7754398/psw/urts/enclave_creator_hw_com.cpp#L61)
+
+```c
+//Since CPUID instruction is NOT supported within enclave, we enumerate the cpu features here and send to tRTS.
+get_cpu_features(&info.cpu_features);
+get_cpu_features_ext(&info.cpu_features_ext);
+init_cpuinfo((uint32_t *)info.cpuinfo_table);
+```
+
+2. Initialize optimized libraries according to the global cpu feature indicator
+   in [trts](https://github.com/intel/linux-sgx/blob/042849cef8db1f0384e52e8cebcd8820c7754398/sdk/trts/init_enclave.cpp#L169)
+
+```c
+// optimized libs
+if (SDK_VERSION_2_0 < g_sdk_version || sys_features.size != 0)
+{
+  if (0 != init_optimized_libs(cpu_features, (uint32_t*)sys_features.cpuinfo_table, xfrm))
+  {
+    return -1;
+  }
+}
+```
+
+We found that in `init_optimized_libs`, a global variable
+`g_cpu_feature_indicator` is initialized to store the `feature_bit_array` which
+contains everything we need!
+
+```c
+static int set_global_feature_indicator(uint64_t feature_bit_array, uint64_t xfrm) {
+    ......
+    g_cpu_feature_indicator = feature_bit_array;
+    return 0;
+}
+```
+
+Since Rust SGX SDK depends on trts, we can simply re-use the
+`g_cpu_feature_indicator` and simulate the `is_x86_feature_detected` macro
+easily! First we import the value from trts:
+
+```rust
+#[link(name = "sgx_trts")]
+extern {
+    static g_cpu_feature_indicator: uint64_t;
+    static EDMM_supported: c_int;
+}
+
+#[inline]
+pub fn rsgx_get_cpu_feature() -> u64 {
+    unsafe { g_cpu_feature_indicator }
+}
+```
+
+Then parse `g_cpu_feature_indicator` like std_detect:
+
+```rust
+#[macro_export]
+macro_rules! is_cpu_feature_supported {
+    ($feature:expr) => ( (($feature & $crate::enclave::rsgx_get_cpu_feature()) != 0) )
+}
+
+#[macro_export]
+macro_rules! is_x86_feature_detected {
+    ("ia32") => {
+        $crate::cpu_feature::check_for($crate::cpu_feature::Feature::ia32)
+    };
+    ...
+}
+```
+
+## Performance concerns
+
+We observed that some crates (such as matrixmultiply) are likely to use the
+highest level of instructions for speed up. But it may not be the best solution.
+For example, the "machine-learning" SGX sample depends on rusty-machine and
+matrixmultiply, which intend to use AVX instruction if supported. However, if we
+use the "fallback" mode, it'll be about 10x faster than the AVX version. The AVX
+optimiztion is pretty complicated and I have no time to read Intel's [Intel® 64
+and IA-32 Architectures Optimization Reference
+Manual](https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf).
+And I don't think either of crate's owner or llvm backend can optimize it
+ideally. I recommend to choose the appropirate instruction set per workload.